使用 Linq 从 Datatable 创建 C# XML 文件

C# create XML file from Datatable with Linq

提问人:johndemanfran 提问时间:3/8/2023 最后编辑:johndemanfran 更新时间:3/8/2023 访问量:134

问:

我是XML的新手,想从datatable创建XML文档

我有一个包含以下数据的 DataTable:

数据库示例

我需要从上面的DataTable数据创建一个XML文件,如下所示:

<Root>
    <DB>
        <ORACLE>
            <name1>
                   <CONNECTION_STRING>connection1</CONNECTION_STRING>
                   <COMMAND>SELECT * FROM table</COMMAND>
            </name1>
            <name2>
                   <CONNECTION_STRING>connection2</CONNECTION_STRING>
                   <COMMAND>SELECT * FROM table</COMMAND>
            </name2>        
            <name3>
                    <CONNECTION_STRING>connection3</CONNECTION_STRING>
                    <COMMAND>SELECT * FROM table</COMMAND>
            </name3>        
        </ORACLE>
        <SQL>
            <name4>
                    <CONNECTION_STRING>connection4</CONNECTION_STRING>
                    <COMMAND>SELECT 1</COMMAND>
            </name4>
            <name5> 
                    <CONNECTION_STRING>connection5</CONNECTION_STRING>
                    <COMMAND>SELECT 1</COMMAND>
            </name5>
            <name6>
                    <CONNECTION_STRING>connection6</CONNECTION_STRING>
                    <COMMAND>SELECT 1</COMMAND>
            </name6>

        </SQL>
        <MYSQL>
            <name7>
                    <CONNECTION_STRING>connection7</CONNECTION_STRING>
                    <COMMAND>SELECT 1</COMMAND>
            </name7>
            <name8>
                    <CONNECTION_STRING>connection8</CONNECTION_STRING>
                    <COMMAND>SELECT 1</COMMAND>
            </name8>
            <name9>
                    <CONNECTION_STRING>connection9</CONNECTION_STRING>
                    <COMMAND>SELECT 1</COMMAND>
            </name9>
        </MYSQL>
    </DB>
    <SERVER>
        <SERVER>
            <Server1>
                    <CONNECTION_STRING>192.168.0.1</CONNECTION_STRING>
                    <COMMAND></COMMAND>
            </Server1>
            <Server2>
                    <CONNECTION_STRING>192.168.0.2</CONNECTION_STRING>
                    <COMMAND></COMMAND>
            </Server2>
        </SERVER>
    </SERVER>
</Root>

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

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

C# 数据表 LINQ-to-XML

评论

0赞 Crowcoder 3/8/2023
您确定这是您要创建的 xml 吗?您只是通过对每个项目使用不同的元素名称(name1、name2 等)来使其难以使用。
0赞 johndemanfran 3/8/2023
是的,我需要这种格式的 XML。这是一个工作请求......
0赞 Svyatoslav Danyliv 3/8/2023
检查这个答案

答:

0赞 jdweng 3/8/2023 #1

请尝试以下操作:

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


namespace ConsoleApplication52
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("CONNECTION_STRING", typeof(string));
            dt.Columns.Add("CONNECTION_TYPE", typeof(string));
            dt.Columns.Add("COMMAND", typeof(string));

            dt.Rows.Add(new object[] { "connection1", "ORACLE", "SELECT * FROM table"});
            dt.Rows.Add(new object[] { "connection2", "ORACLE", "SELECT * FROM table" });
            dt.Rows.Add(new object[] { "connection3", "ORACLE", "SELECT * FROM table" });
            dt.Rows.Add(new object[] { "connection4", "SQL", "SELECT 1" });
            dt.Rows.Add(new object[] { "connection5", "SQL", "SELECT 1" });
            dt.Rows.Add(new object[] { "connection6", "SQL", "SELECT 1" });
            dt.Rows.Add(new object[] { "connection7", "MYSQL", "SELECT 1" });
            dt.Rows.Add(new object[] { "connection8", "MYSQL", "SELECT 1" });
            dt.Rows.Add(new object[] { "connection9", "MYSQL", "SELECT 1" });
            dt.Rows.Add(new object[] { "192.168.0.1", "SERVER", "" });
            dt.Rows.Add(new object[] { "192.168.0.1", "SERVER", "" });

            string xml = "<Root><DB></DB></Root>";
            XDocument doc = XDocument.Parse(xml);
            XElement db = doc.Descendants("DB").First();

            var groups = dt.AsEnumerable().GroupBy(x => x.Field<string>("CONNECTION_TYPE"));

            foreach (var type in groups)
            {
                XElement newDb =  new XElement(type.Key);
                db.Add(newDb);

                int count = 0;
                foreach (var conn in type)
                {
                    count++;
                    XElement newConn = new XElement("name" + count);
                    newDb.Add(newConn);
                    newConn.Add(new XElement("CONNECTION_STRING", conn.Field<string>("CONNECTION_STRING")));
                    newConn.Add(new XElement("COMMAND", conn.Field<string>("COMMAND")));

                }
            }


        }
    }
 
   
}
0赞 johndemanfran 3/8/2023 #2

我以这种方式解决了。

           var connection = dt.AsEnumerable().GroupBy(r => r.Field<string>("CONN_TYPE"));

            // Generate the root element
            var root = new XElement("Controlli", new XAttribute("xmln:sxsi", "http://www.w3.org/2001/XMLSchema-instance"),

                connection.Select(
                    d => d.GroupBy(r => (ChildType: r.Field<string>("CHILD_TYPE"), ConnType: r.Field<string>("CONN_TYPE"))).Select(
                        deptNo =>
                                       new XElement(deptNo.Key.ChildType,
                                       new XElement(deptNo.Key.ConnType,
           d.Select(
               r =>
                    new XElement(r.Field<string>("CONN_NAME"),
                        new XElement("CONNECTION_STRING", r.Field<string>("CONNECTION_STRING")),
                        new XElement("COMMAND", r.Field<string>("COMMAND")
                        ))))))));

评论

0赞 Community 3/14/2023
正如目前所写的那样,你的答案尚不清楚。请编辑以添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。您可以在帮助中心找到有关如何写出好答案的更多信息。