艰难的表格转换为 XML

发布于 2024-08-09 20:52:50 字数 731 浏览 3 评论 0原文

我有一个从数据库中选择的数据表(嗯,这些数据跨多个表,查询并放入数据表后,如下所示)

ColumnA ColumnB
          11
         33
         44
          22
         55

但我想将其转换为这样的XML

<root>
   <header name ='a'>
       <item name='11' />
       <item name='22' />
   </header>
   <header name ='b'>
       <item name='33' />
       <item name='44' />
       <item name='55' />
   </header>

</root>

有没有一种简单的方法可以通过C#实现它?

I have a DataTable which I select from database (Well, these data cross several tables, after the query and putting into a DataTable, it shows at below)

ColumnA ColumnB
a             11
b             33
b             44
a             22
b             55

but I want to transform it into an XML like this

<root>
   <header name ='a'>
       <item name='11' />
       <item name='22' />
   </header>
   <header name ='b'>
       <item name='33' />
       <item name='44' />
       <item name='55' />
   </header>

</root>

Is there an easy way to implement it by C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

审判长 2024-08-16 20:52:50

为什么要麻烦 C# ?您可以直接在 T-SQL 中执行此操作(SQL Server 2005 及更高版本):

SELECT 
    ColumnA AS '@name',
    (SELECT ColumnB AS '@name' 
     FROM YourTable t 
     WHERE t.ColumnA = YourTable.ColumnA 
     FOR XML PATH('item'), TYPE)
FROM 
    YourTable
GROUP BY
    ColumnA
FOR XML PATH('header'), ROOT('root')

为您提供:

<root>
  <header name="a">
    <item name="11" />
    <item name="22" />
  </header>
  <header name="b">
    <item name="33" />
    <item name="44" />
    <item name="55" />
  </header>
</root>

您可以使用标准 ADO.NET SqlCommand 执行此 SQL 查询,并返回已格式化的 XML。

马克

Why bother with C# ?? You can do it in T-SQL directly (SQL Server 2005 and up):

SELECT 
    ColumnA AS '@name',
    (SELECT ColumnB AS '@name' 
     FROM YourTable t 
     WHERE t.ColumnA = YourTable.ColumnA 
     FOR XML PATH('item'), TYPE)
FROM 
    YourTable
GROUP BY
    ColumnA
FOR XML PATH('header'), ROOT('root')

Gives you:

<root>
  <header name="a">
    <item name="11" />
    <item name="22" />
  </header>
  <header name="b">
    <item name="33" />
    <item name="44" />
    <item name="55" />
  </header>
</root>

You can execute this SQL query using standard ADO.NET SqlCommand and get back the XML nicely formatted already.

Marc

独自唱情﹋歌 2024-08-16 20:52:50

好的,在了解到数据在 DataTable 中可用之后,我们开始采用第二种方法。

代码有点复杂,因为基于 DataTable,您在分组等方面实际上无法做太多事情。我正在构建 XmlDocument (因为您使用的是 .NET 2.0)同时扫描数据行。我需要跟踪字典中的

元素,以便将具有相同“ColumnA”值的第二个、第三个条目添加到现有的 XmlElement 在文档中 - 这有点复杂,但如果您仔细研究它,我希望您会发现这实际上没有欺骗或任何东西 - 只是在构建 XmlDocument 的过程中进行了一些簿记:

// create the XmlDocument and add <root> node
XmlDocument doc = new XmlDocument();
doc.AppendChild(doc.CreateElement("root"));

// dictionary to keep track of <header> nodes
Dictionary<string, XmlNode> nodesPerColumnA = new Dictionary<string, XmlNode>();

// Loop through data rows
foreach (DataRow row in tbl.Rows)
{
   // extract values for ColumnA and ColumnB as strings
   string columnAValue = row["ColumnA"].ToString();
   string columnBValue = row["ColumnB"].ToString();

   // create a new <item> XmlNode and fill its attribute @Name 
   XmlElement newNode = doc.CreateElement("item");

   XmlAttribute newNodeAttribute = doc.CreateAttribute("name");
   newNodeAttribute.InnerText = columnBValue;

   newNode.Attributes.Append(newNodeAttribute);

   // check if we already have a <header> node for that "ColumnA" value
   if(nodesPerColumnA.ContainsKey(columnAValue))
   {
       // if so - just add <item> below that <header>
       XmlNode parent = nodesPerColumnA[columnAValue];

       parent.AppendChild(newNode);
   }
   else
   {
       // if not - create appropriate <header> node and its @name attribute
       XmlElement header = doc.CreateElement("header");

       XmlAttribute headerAttr = doc.CreateAttribute("name");
       headerAttr.InnerText = columnAValue;

       header.Attributes.Append(headerAttr);

       header.AppendChild(newNode);

       doc.DocumentElement.AppendChild(header);

       // store that <header> xmlnode into the dictionary for future use
       nodesPerColumnA.Add(columnAValue, header);
    }
 }

 // check the contents of the XmlDocument at the end
 string xmlContents = doc.InnerXml;

OK, second approach after learning that the data is available in a DataTable to begin with.

The code is a bit more involved, since based on a DataTable, you can't really do much in terms of grouping etc. I am building up the XmlDocument (since you're on .NET 2.0) while scanning through the rows of data. I need to keep track of the <header> elements in a dictionary, in order to add a second, third entry with the same "ColumnA" value to that already existing XmlElement in the document - it's a bit involved, but if you study it carefully, I hope you see it's really no trickery or anything - just a bit of bookkeeping along the way of building the XmlDocument:

// create the XmlDocument and add <root> node
XmlDocument doc = new XmlDocument();
doc.AppendChild(doc.CreateElement("root"));

// dictionary to keep track of <header> nodes
Dictionary<string, XmlNode> nodesPerColumnA = new Dictionary<string, XmlNode>();

// Loop through data rows
foreach (DataRow row in tbl.Rows)
{
   // extract values for ColumnA and ColumnB as strings
   string columnAValue = row["ColumnA"].ToString();
   string columnBValue = row["ColumnB"].ToString();

   // create a new <item> XmlNode and fill its attribute @Name 
   XmlElement newNode = doc.CreateElement("item");

   XmlAttribute newNodeAttribute = doc.CreateAttribute("name");
   newNodeAttribute.InnerText = columnBValue;

   newNode.Attributes.Append(newNodeAttribute);

   // check if we already have a <header> node for that "ColumnA" value
   if(nodesPerColumnA.ContainsKey(columnAValue))
   {
       // if so - just add <item> below that <header>
       XmlNode parent = nodesPerColumnA[columnAValue];

       parent.AppendChild(newNode);
   }
   else
   {
       // if not - create appropriate <header> node and its @name attribute
       XmlElement header = doc.CreateElement("header");

       XmlAttribute headerAttr = doc.CreateAttribute("name");
       headerAttr.InnerText = columnAValue;

       header.Attributes.Append(headerAttr);

       header.AppendChild(newNode);

       doc.DocumentElement.AppendChild(header);

       // store that <header> xmlnode into the dictionary for future use
       nodesPerColumnA.Add(columnAValue, header);
    }
 }

 // check the contents of the XmlDocument at the end
 string xmlContents = doc.InnerXml;
以歌曲疗慰 2024-08-16 20:52:50

使用 LINQ:-

var qry = from row in Table
          group row by row.ColumnA into header
          select header;

var elem = new XElement("root");

foreach (var header in qry)
{
  var elemHead = new XElement("header", new XAttribute("name", header.Key));
  elem.Add(elemHead);
  foreach (var item in header)
    elemHead.Add(new XElement("item", new XAttribute("name", item.ColumnB)));
}
// the variable elem contains the result.

With LINQ:-

var qry = from row in Table
          group row by row.ColumnA into header
          select header;

var elem = new XElement("root");

foreach (var header in qry)
{
  var elemHead = new XElement("header", new XAttribute("name", header.Key));
  elem.Add(elemHead);
  foreach (var item in header)
    elemHead.Add(new XElement("item", new XAttribute("name", item.ColumnB)));
}
// the variable elem contains the result.
飞烟轻若梦 2024-08-16 20:52:50

这将使用 .NET 3.5 和 XDocument 来完成

XDocument yourDocument = new XDocument(new XElement("root",
    new XElement("header",
        new XAttribute("name", "a"),
        new XElement("item",
            new XAttribute("name", "11")),
        new XElement("item",
            new XAttribute("name", "22"))),
    new XElement("header",
        new XAttribute("name", "b"),
        new XElement("item",
            new XAttribute("name", "33")),
        new XElement("item",
            new XAttribute("name", "44")),
        new XElement("item",
            new XAttribute("name", "55")))));

This will do it using .NET 3.5 and the XDocument

XDocument yourDocument = new XDocument(new XElement("root",
    new XElement("header",
        new XAttribute("name", "a"),
        new XElement("item",
            new XAttribute("name", "11")),
        new XElement("item",
            new XAttribute("name", "22"))),
    new XElement("header",
        new XAttribute("name", "b"),
        new XElement("item",
            new XAttribute("name", "33")),
        new XElement("item",
            new XAttribute("name", "44")),
        new XElement("item",
            new XAttribute("name", "55")))));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文