如何在C#中从DataTable生成指定结构的XML文档?
从DataTable生成指定结构的XML文档
我是XML新手,希望从DataTable创建XML文档。现有包含如下数据的DataTable:
Number DeptNo DeptName State Date Year DeptCode ELP 123A 1001 DESC JR PA 12/12/2021 2021 74-123 Y 123A 1002 PHIL JR NY 09/12/2021 2021 74-124 Y 123A 1003 GILB JR CA 08/12/2021 2021 74-125 N 123A 1004 THEO JR AZ 07/12/2021 2021 74-126 N 123A 1005 HARR JR NV 06/12/2021 2021 74-127 Y 123A 1001 DESC JR FED 06/12/2021 2021 74-123 N 123A 1002 PHIL JR FED 09/12/2021 2021 74-124 N
需要基于上述DataTable数据生成如下结构的XML文件:
<Root> <Type>MyType</Type> <FileDate>12/15/2022</FileDate> <Version>2.0</Version> <Department> <Number>123A</Number> <Id>0000</Id> <Trust> <DeptNo>1001</DeptNo> <DeptName>DESC JR</DeptName> <DeptCode>74-123</DeptCode> <DepartmentData> <State>PA</State> <Date>12/12/2021</Date> <Year>2021</Year> <ELP>Y</ELP> </DepartmentData> <DepartmentData> <State>FED</State> <Date>06/12/2021</Date> <Year>2021</Year> <ELP>N</ELP> </DepartmentData> </Trust> <Trust> <DeptNo>1002</DeptNo> <DeptName>PHIL JR</DeptName> <DeptCode>74-124</DeptCode> <DepartmentData> <State>NY</State> <Date>09/12/2021</Date> <Year>2021</Year> <ELP>Y</ELP> </DepartmentData> <DepartmentData> <State>FED</State> <Date>09/12/2021</Date> <Year>2021</Year> <ELP>N</ELP> </DepartmentData> </Trust> <Trust> <DeptNo>1003</DeptNo> <DeptName>GILB JR</DeptName> <DeptCode>74-125</DeptCode> <DepartmentData> <State>CA</State> <Date>08/12/2021</Date> <Year>2021</Year> <ELP>N</ELP> </DepartmentData> </Trust> <!-- Other Trust nodes skipped --> </Department> </Root>
我曾尝试过一些方法,但未得到预期结果,请问如何遍历DataTable行来创建该XML文档?
解决方案
可以使用.NET的LINQ to XML实现,先对DataTable行按DeptNo分组,再逐层构建XML节点,高效生成符合要求的结构:
代码示例(C#)
using System.Data; using System.Linq; using System.Xml.Linq; // 假设你的DataTable名为dt,替换为实际获取DataTable的逻辑 DataTable dt = GetYourDataTable(); // 按DeptNo分组,聚合每个部门的所有数据行 var groupedDepartments = dt.AsEnumerable() .GroupBy(row => row.Field<string>("DeptNo")); // 构建目标XML文档 var xmlDocument = new XDocument( new XElement("Root", new XElement("Type", "MyType"), new XElement("FileDate", "12/15/2022"), new XElement("Version", "2.0"), new XElement("Department", // 取第一行的Number值(假设所有行Number相同) new XElement("Number", dt.AsEnumerable().First().Field<string>("Number")), new XElement("Id", "0000"), // 遍历每个部门分组,生成Trust节点 from deptGroup in groupedDepartments select new XElement("Trust", new XElement("DeptNo", deptGroup.Key), // 同DeptNo的DeptName、DeptCode一致,取分组第一行的值 new XElement("DeptName", deptGroup.First().Field<string>("DeptName")), new XElement("DeptCode", deptGroup.First().Field<string>("DeptCode")), // 遍历分组内的行,生成DepartmentData节点 from row in deptGroup select new XElement("DepartmentData", new XElement("State", row.Field<string>("State")), new XElement("Date", row.Field<string>("Date")), new XElement("Year", row.Field<int>("Year")), new XElement("ELP", row.Field<string>("ELP")) ) ) ) ) ); // 保存XML到文件 xmlDocument.Save("output.xml"); // 或转换为字符串输出:string xmlContent = xmlDocument.ToString();
关键说明
- 分组逻辑:通过
GroupBy按DeptNo聚合数据,确保每个Trust节点对应唯一部门,包含该部门的所有DepartmentData。 - 层级构建:用LINQ to XML的链式调用,逐层生成
Root→Department→Trust→DepartmentData的结构,代码简洁易维护。 - 数据提取:使用
Field<T>方法从DataRow中获取强类型数据,避免类型转换错误。 - 特殊值处理:
Type、FileDate等固定值直接写入;若Number可能存在多值,需在外层额外按Number分组生成多个Department节点。
内容的提问来源于stack exchange,提问作者DevP
相关产品推荐
相关产品推荐

