2016-10-05 47 views
0

我有以下數據表:轉換數據表到XML的層次結構中的C#

A B C 
---------- 
A1 B1 C1 
A1 B1 C2 
A1 B1 C3 
A1 B2 C1 
A1 B2 C2 
---------- 

我試着用C#是XML格式,像這樣將它轉換:

<Data> 
    <A> 
     <lable>A1</lable> 
     <B> 
      <lable>B1</lable> 
      <C> 
       <lable>C1</lable> 
       <lable>C2</lable> 
       <lable>C3</lable> 
      </C> 
      <lable>B2</lable> 
      <C> 
       <lable>C1</lable> 
       <lable>C2</lable> 
      </C> 
     </B> 
    </A> 
</Data> 

我做了深刻的搜索我在網上找到了一些有用的東西,比如this。 但那個人使用關係,我的數據只是一個表。 我還試圖此C#代碼:

using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Drawing; 
    using System.Linq; 
    using System.Text; 
    using System.Threading.Tasks; 
    using System.Windows.Forms; 
    using System.Xml.Linq; 
    using System.Data.SqlClient; 

    SqlConnection con = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Files;Data Source=localhost"); 
    con.Open(); 
    SqlCommand cmd = new SqlCommand("select * from MyTable",con); 
    SqlDataAdapter da = new SqlDataAdapter(cmd); 
    DataTable DT = new DataTable("Data"); 
    da.Fill(DT); 
    dataGridView1.DataSource = DT; 
    con.Close(); 
    string XML = ToXmlFormat(DT, 0); 
    Console.WriteLine(XML); 


public string ToXmlFormat(this DataTable table, int metaIndex = 0) 
{ 
    XDocument xdoc = new XDocument(
     new XElement(table.TableName, 
      from column in table.Columns.Cast<DataColumn>() 
      where column != table.Columns[metaIndex] 
      select new XElement(column.ColumnName, 
       from row in table.AsEnumerable() 
       select new XElement(row.Field<string>(metaIndex), row[column]) 
       ) 
      ) 
     ); 

    return xdoc.ToString(); 
} 

結果是另一種格式,其並不像我解釋嵌套的XML。 see image

如何將我的表格轉換爲我需要的XML格式?

+0

的數據表,將中WriteXML寫出來的,它需要讀回 – Plutonix

+0

沒有我也試過了,它返回只有一個節點,你可以嘗試的格式,但它是錯誤的 –

回答

1

您需要使用GroupBy對行進行分組,然後將所需的零件選擇到XElements
下面的代碼應該做你想要什麼:

var xml = new XElement(table.TableName, table.Rows.Cast<DataRow>() 
     .GroupBy(row => (string)row[0]) 
     .Select(g => 
      new XElement(table.Columns[0].ColumnName, 
       new XElement("label", g.Key), 
       g.GroupBy(row => (string)row[1]) 
       .Select(g1 => 
        new XElement(table.Columns[1].ColumnName, 
         new XElement("label", g1.Key), 
         new XElement(table.Columns[2].ColumnName, 
          g1.Select(row => 
           new XElement("label", (string)row[2]) 
          ) 
         ) 
        ) 
       ) 
      ) 
     ) 
    ).ToString(); 

小提琴:https://dotnetfiddle.net/qEWNvj

+0

完美!謝謝 –

+0

沒問題;很高興我能幫上忙。 –

0

我的風格是從其他答案稍有不同。代碼已經過測試,符合您的預期結果。

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 
    { 
     static void Main(string[] args) 
     { 
      DataTable dt = new DataTable(); 
      dt.Columns.Add("A", typeof(string)); 
      dt.Columns.Add("B", typeof(string)); 
      dt.Columns.Add("C", typeof(string)); 

      dt.Rows.Add(new object[] {"A1", "B1","C1"}); 
      dt.Rows.Add(new object[] {"A1", "B1","C2"}); 
      dt.Rows.Add(new object[] {"A1", "B1","C3"}); 
      dt.Rows.Add(new object[] {"A1", "B2","C1"}); 
      dt.Rows.Add(new object[] {"A1", "B2","C2"}); 

      dt = dt.AsEnumerable() 
       .OrderBy(x => x.Field<string>("A")) 
       .ThenBy(x => x.Field<string>("B")) 
       .ThenBy(x => x.Field<string>("C")) 
       .CopyToDataTable(); 

      XElement data = new XElement("Data", new XElement("A", dt.AsEnumerable() 
       .GroupBy(g1 => g1.Field<string>("A")).Select(g1a => new object[] { 
        new XElement("lable",(string)g1a.Key), 
        new XElement("B", 
         g1a.GroupBy(g2 => g2.Field<string>("B")).Select(g2b => new object[] { 
          new XElement("lable", (string)g2b.Key), 
          new XElement("C", 
           g2b.Select(g3c => new XElement("lable", g3c.Field<string>("C")) 
          ))} 
        ))} 
      ))); 

     } 
    } 
}