如何在 C# 中从数据表生成 XML

Posted

技术标签:

【中文标题】如何在 C# 中从数据表生成 XML【英文标题】:How to generate XML from datatable in c# 【发布时间】:2020-01-16 09:37:51 【问题描述】:

我有一个来自数据库的数据表,其中包含如下数据

ID  NAME    SERVICE                 SITENAME                NODENAME
27883481    EAGLE HILLS PROPERTIES  MANAGED WAN CAPITAL GATE-ADNEC LEANING TOWER    capitalgatetwrill-ra
27883481    EAGLE HILLS PROPERTIES  MANAGED WAN 2020 BLDG   dxbcontactcentreill-rb
27883481    EAGLE HILLS PROPERTIES  MANAGED WAN 2020 BLDG   dxbcontactcentreill-ra
27883481    EAGLE HILLS PROPERTIES  MANAGED WAN CAPITAL GATE-ADNEC LEANING TOWER    capitalgatetwrill-rb
27883481    EAGLE HILLS PROPERTIES  MANAGED LAN CAPITAL GATE-ADNEC LEANING TOWER    capitalgatetwrill-ra
27883481    EAGLE HILLS PROPERTIES  MANAGED LAN 2020 BLDG               dxbcontactcentreill-rb
27883481    EAGLE HILLS PROPERTIES  MANAGED LAN 2020 BLDG               dxbcontactcentreill-ra
27883481    EAGLE HILLS PROPERTIES  MANAGED LAN CAPITAL GATE-ADNEC LEANING TOWER    capitalgatetwrill-rb
27883   EAGLE DRILLS PROPERTIES MANAGED WAN     CAPITAL GATE-ADNEC LEANING TOWER    capitalgatetwrill-ra
27883   EAGLE DRILLS PROPERTIES MANAGED WAN     2020 BLDG               dxbcontactcentreill-rb
27883   EAGLE DRILLS PROPERTIES MANAGED WAN     2020 BLDG               dxbcontactcentreill-ra
27883   EAGLE DRILLS PROPERTIES MANAGED WAN     CAPITAL GATE-ADNEC LEANING TOWER    capitalgatetwrill-rb

我想从上面的数据创建 XMl,如下所示,它是 XML 的原型

<?xml version="1.0" encoding="utf-8" ?>
<AllSites>
  <SITE_NODES>
    <ID>27883481</ID>
    <NAME>EAGLE HILLS PROPERTIES""</NAME>
    <PARTY_SERVICES>
      <SERVICE_NAME>MANAGED WAN</SERVICE_NAME>
      <SERVICE_SITES>
        <SITE_NAME>CAPITAL GATE-ADNEC LEANING TOWER</SITE_NAME>
        <SITE_NODES>
          <NODE_NAME>capitalgatetwrill-ra</NODE_NAME>
          <NODE_NAME>capitalgatetwrill-rb</NODE_NAME>
        </SITE_NODES>
      </SERVICE_SITES>
      <SERVICE_SITES>
        <SITE_NAME>2020 BLDG</SITE_NAME>
        <SITE_NODES>
          <NODE_NAME>dxbcontactcentreill-rb</NODE_NAME>
          <NODE_NAME>dxbcontactcentreill-ra</NODE_NAME>
        </SITE_NODES>
      </SERVICE_SITES>
    </PARTY_SERVICES>
    <PARTY_SERVICES>
      <SERVICE_NAME>MANAGED LAN</SERVICE_NAME>
      <SERVICE_SITES>
        <SITE_NAME>CAPITAL GATE-ADNEC LEANING TOWER</SITE_NAME>
        <SITE_NODES>
          <NODE_NAME>abcd-ra</NODE_NAME>
          <NODE_NAME>abcd-rb</NODE_NAME>
        </SITE_NODES>
      </SERVICE_SITES>
      <SERVICE_SITES>
        <SITE_NAME>2021 BLDG</SITE_NAME>
        <SITE_NODES>
          <NODE_NAME>pqms-rb</NODE_NAME>
          <NODE_NAME>pqms-ra</NODE_NAME>
        </SITE_NODES>
      </SERVICE_SITES>
    </PARTY_SERVICES>
  </SITE_NODES>
</AllSites>

如何生成它?我是否需要创建一个带有占位符的 XML 模板,应该替换运行时?或创建 c# 类并生成它 如下

 public class DetailsBO
    
        public string ID  get; set; 
        public string NAME  get; set; 
        public string SERVICE  get; set; 
        public List<SitesBO> sites  get; set; 
    
    public class SitesBO
    
        public string SITENAME  get; set; 
        public List<NodesBO> noodes  get; set; 
    
    public class NodesBO
    
        public string NODENAME  get; set; 
    

谁能给我c#代码

编辑

假设如果站点名称为空或为空,则所有服务类型都将变为与 WAN 或 LAN 相同的服务类型

 DataTable dt = new DataTable();
            dt.Columns.Add("ID", typeof(string));
            dt.Columns.Add("NAME", typeof(string));
            dt.Columns.Add("SERVICE", typeof(string));
            dt.Columns.Add("SITENAME", typeof(string));
            dt.Columns.Add("NODENAME", typeof(string));

            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED WAN", "", "capitalgatetwrill-ra" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED WAN", "2020 BLDG", "dxbcontactcentreill-rb" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED WAN", "2020 BLDG", "dxbcontactcentreill-ra" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED WAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-rb" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED LAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-ra" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED LAN", "2020 BLDG", "dxbcontactcentreill-rb" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED LAN", "2020 BLDG", "dxbcontactcentreill-ra" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED LAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-rb" );
            dt.Rows.Add(new object[]  "27883", "EAGLE DRILLS PROPERTIES", "MANAGED WAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-ra" );
            dt.Rows.Add(new object[]  "27883", "EAGLE DRILLS PROPERTIES", "MANAGED WAN", "2020 BLDG", "dxbcontactcentreill-rb" );
            dt.Rows.Add(new object[]  "27883", "EAGLE DRILLS PROPERTIES", "MANAGED WAN", "2020 BLDG", "dxbcontactcentreill-ra" );
            dt.Rows.Add(new object[]  "27883", "EAGLE DRILLS PROPERTIES", "MANAGED WAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-rb" );

【问题讨论】:

这是 NOT 类似“gimme-ze-codes”的网站 - 以您的声誉,您应该知道这一点。到目前为止, 尝试过什么?你被困在哪里了?我们会帮助 - 但我们不会只是给你整个代码..... 【参考方案1】:

最少的代码是把当前的数据表直接输出到xml。您可以修改代码以使用将创建类和序列化类的实体。但是因为你已经有了数据表,所以我只是拿了表并直接制作了 xml。看起来您删除了重复项,所以我也这样做了。我还订购了结果。

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

namespace ConsoleApplication1

    class Program
    
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        
            DataTable dt = new DataTable();
            dt.Columns.Add("ID", typeof(string));
            dt.Columns.Add("NAME", typeof(string));
            dt.Columns.Add("SERVICE", typeof(string));
            dt.Columns.Add("SITENAME", typeof(string));
            dt.Columns.Add("NODENAME", typeof(string));

            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED WAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-ra" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED WAN", "2020 BLDG", "dxbcontactcentreill-rb" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED WAN", "2020 BLDG", "dxbcontactcentreill-ra" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED WAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-rb" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED LAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-ra" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED LAN", "2020 BLDG", "dxbcontactcentreill-rb" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED LAN", "2020 BLDG", "dxbcontactcentreill-ra" );
            dt.Rows.Add(new object[]  "27883481", "EAGLE HILLS PROPERTIES", "MANAGED LAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-rb" );
            dt.Rows.Add(new object[]  "27883", "EAGLE DRILLS PROPERTIES", "MANAGED WAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-ra" );
            dt.Rows.Add(new object[]  "27883", "EAGLE DRILLS PROPERTIES", "MANAGED WAN", "2020 BLDG", "dxbcontactcentreill-rb" );
            dt.Rows.Add(new object[]  "27883", "EAGLE DRILLS PROPERTIES", "MANAGED WAN", "2020 BLDG", "dxbcontactcentreill-ra" );
            dt.Rows.Add(new object[]  "27883", "EAGLE DRILLS PROPERTIES", "MANAGED WAN", "CAPITAL GATE-ADNEC LEANING TOWER", "capitalgatetwrill-rb" );

            dt = dt.AsEnumerable()
                .OrderBy(x => x.Field<string>("ID"))
                .ThenBy(x => x.Field<string>("NAME"))
                .ThenBy(x => x.Field<string>("SERVICE"))
                .ThenBy(x => x.Field<string>("SITENAME"))
                .ThenBy(x => x.Field<string>("NODENAME"))
                .CopyToDataTable();


            string xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><AllSites></AllSites>";
            XDocument doc = XDocument.Parse(xml);
            XElement allSites = doc.Root;

            foreach (var idGroup in dt.AsEnumerable().GroupBy(x => x.Field<string>("ID")))
            
                XElement siteNode = new XElement("SITE_NODE");
                allSites.Add(siteNode);


                siteNode.Add(new XElement("ID", idGroup.Key));
                siteNode.Add(new XElement("NAME", idGroup.First().Field<string>("NAME")));

                XElement partyServices = new XElement("PARTY_SERVICES");
                siteNode.Add(partyServices);

                partyServices.Add(new XElement("SERVICE_NAME", idGroup.First().Field<string>("SERVICE")));


                foreach (var serviceSite in idGroup.GroupBy(x => x.Field<string>("SITENAME")))
                
                    XElement serviceSites = new XElement("SERVICE_SITES");
                    partyServices.Add(serviceSites);
                    serviceSites.Add(new XElement("SITE_NAME", serviceSite.Key));

                    XElement siteNodes = new XElement("SITE_NODES");
                    serviceSites.Add(siteNodes);

                    string[] nodeNames = serviceSite.Select(x => x.Field<string>("NODENAME")).Distinct().ToArray();
                    foreach (string nodeName in nodeNames)
                    
                        siteNodes.Add(new XElement("NODE_NAME", nodeName));
                    
                
            

            doc.Save(FILENAME);

        
    

【讨论】:

不同之处在于您删除了重复项。所以我添加了代码来排序和删除重复项。 我需要查看代码和确切的错误。不知道你在做什么。 如果 SITE_NAME 为空那么它混合了 WAN 和 LAN 的情况,因为 serviceSite.Key 是空白的。如何避免它?我们需要写 where 子句 如果您从数据库中获取数据,则错误在数据库中。您将数据插入数据库的方法是错误的。您需要更正数据库。

以上是关于如何在 C# 中从数据表生成 XML的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中从包含 XML 的字符串中读取数据?

如何在 C# 中从 XML 中删除选定的节点?

如何在 C# WPF 中从 ListView/XML 中完全删除一个项目?

如何在 Visual Studio 2013 中从 C# 解决方案生成序列图?

如何在自适应对话框 HttpRequest 中从 xml 转换为 json?

如何在 Android 中从 styles.xml 设置 EditText 样式?