C# 从数据表创建 XML 文件

C# create XML file from Datatable

提问人:DevP 提问时间:12/16/2022 最后编辑:dbcDevP 更新时间:12/17/2022 访问量:178

问:

我是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>12/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>

我尝试了以下方法,但它没有给我预期的结果:

如何遍历数据表行以创建XML文档?

C# 数据表 LINQ-to-XML

评论

0赞 Tu deschizi eu inchid 12/16/2022
以下内容可能会有所帮助:stackoverflow.com/questions/73638292/...

答:

1赞 dbc 12/16/2022 #1

您的基本问题是您只创建了一个元素。您需要的 XML 具有多个重复元素,因此您需要在 lambda 中移动这些元素的创建。<Trust><Trust>dt.AsEnumerable()

您还有一个元素错误:您正在创建一个名为 not 的元素。XML 区分大小写,因此必须始终使用正确的大小写创建元素。<Id><ID><Id>

最后,一个建议:您正在对 department 进行硬编码,但是您可以轻松地按列的值对 DataTable 行进行分组,然后编写组键而不是硬编码值。Number"123A"Number

总而言之,您的代码应如下所示:

// Group the rows by Department (all 123A in your question).
var departments = dt.AsEnumerable().GroupBy(r => r.Field<string>("Number")); 

// Generate the root element
var root = new XElement("Root",
    new XElement("Type", "MyType"),
    new XElement("FileDate", "12/15/2022"),
    new XElement("Version", "2.0"),
    departments.Select(
        d =>
        new XElement("Department",
            new XElement("Number", d.Key),
            new XElement("Id", "0000"),  // Fixed, was ID
            d.Select(
                r => 
                new XElement("Trust",
                    new XElement("DeptNo", r.Field<string>("DeptNo")),  
                    new XElement("DeptName", r.Field<string>("DeptName")),   
                    new XElement("DeptCode", r.Field<string>("DeptCode")),
                    new XElement("DepartmentData", 
                        new XElement("State", r.Field<string>("State")),
                        new XElement("Date", r.Field<string>("Date")),
                        new XElement("Year", r.Field<string>("Year")),
                        new XElement("ELP", r.Field<string>("ELP"))
                    )
                )
            )
        )
    )
);

应该不需要创建节点,当您将节点序列化为最终输出流时,它应该自动为您编写。XDeclarationXElement

演示小提琴在这里


但是我如何按“DeptNo”分组?我已经更新了 DataTable 和预期的 XML。对不起,我没有在问题中提到这个早点。

您可以添加一个额外的 GroupBy() 来按 DeptNo 对 Department 行进行分组,如下所示:

// Group the rows by Department (all 123A in your question).
var departments = dt.AsEnumerable().GroupBy(r => r.Field<string>("Number")); 

// Generate the root element
var root = new XElement("Root",
    new XElement("Type", "MyType"),
    new XElement("FileDate", "12/15/2022"),
    new XElement("Version", "2.0"),
    departments.Select(
        d =>
        new XElement("Department",
            new XElement("Number", d.Key),
            new XElement("Id", "0000"),  // Fixed, was ID
            // Group Departments by DeptNo. Also collect DeptName and DeptCode in the Key to use later (we assume they are consistent for each DeptNo).
            d.GroupBy(r => (DeptNo : r.Field<string>("DeptNo"), DeptName : r.Field<string>("DeptName"), DeptCode : r.Field<string>("DeptCode"))).Select(
                deptNo => 
                new XElement("Trust",
                    new XElement("DeptNo", deptNo.Key.DeptNo),  
                    new XElement("DeptName", deptNo.Key.DeptName),   
                    new XElement("DeptCode", deptNo.Key.DeptCode),
                    deptNo.Select(data =>
                        new XElement("DepartmentData", 
                            new XElement("State", data.Field<string>("State")),
                            new XElement("Date", data.Field<string>("Date")),
                            new XElement("Year", data.Field<string>("Year")),
                            new XElement("ELP", data.Field<string>("ELP"))
                        )
                    )
                )
            )
        )
    )
);

演示小提琴 #2 在这里

评论

0赞 DevP 12/17/2022
这行得通。DataTable 将仅包含 Number 为“123A”的行。但是我如何按“DeptNo”分组?我已经更新了 DataTable 和预期的 XML。对不起,我没有在问题中提到这个早点。
0赞 DevP 12/17/2022
我一直在尝试添加这个额外的组,但得到了重复的结果。你救了我的一天!!