Показать данные в формате 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;
}