Показать данные в формате xml C#

Я пытаюсь создать XML-файл с данными в моем dataTable. В конечном итоге это то, что я хочу создать

<?xml version="1.0" encoding="utf-8"?>
<regisApts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <JobList>
    <Job id="1245">
      <Date>2010-07-25</Date>
      <Reason>No Access 1</Reason>
      <Comment>Tenant is on holiday</Comment>
      <ExternalJobNumber>123456</ExternalJobNumber>
    </Job>
    <Job id="">
      <Date>2010-07-26</Date>
      <Reason>No Access 2</Reason>
      <Comment>Tenant out at work</Comment>
      <ExternalJobNumber>123456</ExternalJobNumber>
    </Job>
    <Job id="1453">
      <Date>2010-07-25</Date>
      <Reason>No Access 1</Reason>
      <Comment>Tenant in hospital</Comment>
    </Job>
  </JobList>
</regisApts>

Мне удалось сгенерировать xml с помощью foreach, но он перевешивает xml при вставке следующей строки. Любая помощь очень ценится. Спасибо

foreach (DataRow row in dt.Rows)
{
    xmlCostCode = row["CostCode"].ToString();
    xmlReason = row["Reason"].ToString();
    xmlComment = row["PropertyCode"].ToString();
    xmlFilePath = xmlFolderPath + "test" + ".xml";

    xmlContent = "<JobList><Job Id=\"" + xmlCostCode + "\"><Date>2017-07-18</Date><Reason>" + xmlReason + "</Reason><Comment>" + xmlComment + "</Comment></Job></JobList>";

    XmlDocument xdoc = new XmlDocument();
    xdoc.LoadXml(xmlContent);
    xdoc.Save(xmlFilePath);
}

Результаты я получаю

<JobList>
    <Job id="1245">
      <Date>2010-07-25</Date>
      <Reason>No Access 1</Reason>
      <Comment>Tenant is on holiday</Comment>
      <ExternalJobNumber>123456</ExternalJobNumber>
    </Job>
<JobList>

4 ответа

Решение

Каждый раз, когда вы делаете

 XmlDocument xdoc = new XmlDocument();
 xdoc.LoadXml(xmlContent);
 xdoc.Save(xmlFilePath);

Он записывает поверх вашего предыдущего документа самую последнюю строку, поэтому попробуйте

xmlContent = "<regisApts xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><JobList>";
foreach (DataRow row in dt.Rows)
{
   xmlCostCode = row["CostCode"].ToString();
   xmlReason = row["Reason"].ToString();
   xmlComment = row["PropertyCode"].ToString();
   xmlFilePath = xmlFolderPath + "test" + ".xml";

   xmlContent = xmlContent +"<Job Id=\"" + xmlCostCode + "\"><Date>2017-07-18</Date><Reason>" + xmlReason + "</Reason><Comment>" + xmlComment + "</Comment></Job>";

}
xmlContent = xmlContent +"</JobList></regisApts>";
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(xmlContent);
xdoc.Save(xmlFilePath);

Таким образом, вы строите строку с каждой строкой, и после этого вы создаете документ XML.

Использование xml linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;

namespace ConsoleApplication65
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("CostCode", typeof(int));
            dt.Columns.Add("Date", typeof(DateTime));
            dt.Columns.Add("Reason", typeof(string));
            dt.Columns.Add("Comment", typeof(string));
            dt.Columns.Add("PropertyCode", typeof(int));

            dt.Rows.Add(new object[] { 1245, DateTime.Parse("2010-07-25"), "No Access 1", "Tenant is on holiday", 123456 });
            dt.Rows.Add(new object[] { null, DateTime.Parse("2010-07-26"), "No Access 2", "Tenant out at work", 123456 });
            dt.Rows.Add(new object[] { 1453, DateTime.Parse("2010-07-25"), "No Access 1", "Tenant in hospital", null });

            string header = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<regisApts xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
                "<JobList></JobList></regisApts>";

            XDocument doc = XDocument.Parse(header);
            XElement jobList = doc.Descendants("JobList").FirstOrDefault();

            foreach(DataRow row in dt.AsEnumerable())
            {
                XElement job = new XElement("Job", new object[] {
                    new XAttribute("id", row.Field<object>("CostCode") == null ? "" : row.Field<int>("CostCode").ToString()),
                    new XElement("Date", row.Field<DateTime>("Date").ToString("yyyy-MM-dd")),
                    new XElement("Reason", row.Field<string>("Reason")),
                    new XElement("Comment", row.Field<string>("Comment")),
                    new XElement("ExternalJobNumber", row.Field<object>("PropertyCode") == null ? "" : row.Field<int>("PropertyCode").ToString())
                });
                jobList.Add(job);
            }
        }
    }

}

Когда вы говорите, что используете for...eachЯ предполагаю, что вы создаете XML в текстовом виде. Я рекомендую вам не делать этого, а вместо этого заглянуть в сериализацию XML. Microsoft предоставляет пример здесь:

https://support.microsoft.com/en-us/help/815813/how-to-serialize-an-object-to-xml-by-using-visual-c

По сути, вы создаете объектное представление для вашего XML (ваша таблица данных, вероятно, уже существует), создаете сериализатор для вашего типа, а затем запускаете его, выводя в поток (поток файлов и т. Д.)

Если вам не нужно использовать DataTable по какой-либо причине (я не вижу здесь хорошего), вам следует использовать Generics для возврата ваших данных в виде строго типизированного объекта. Что-то вроде

List<JobList> jobList = new List<JobList>();

Затем используйте функцию для сериализации вашего класса JobList в XML. Просто передайте свой класс функции как объект. Я предпочитаю не использовать класс XMLSerializer, поскольку он раздут и должен создавать временный файл при сериализации вашего объекта. Я бы использовал что-то вроде этого, что значительно быстрее.

public XElement GetAsXml(object obj)
    {
        XElement xelement = new XElement(obj.GetType().Name); 

        PropertyInfo[] props = obj.GetType().GetProperties();

        foreach (PropertyInfo prop in props)
        {
            object propertyValue = prop.GetValue(obj);

            if(propertyValue != null)
            {
                XElement xProperty = new XElement(prop.Name, propertyValue);
                xelement.Add(xProperty);
            }
        }

        return xelement;
    }
Другие вопросы по тегам