2016-10-05 3 views
0

Ich habe die Datentabelle folgende:Convert Datatable in XML-Hierarchie in C#

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

Ich habe versucht, es zu konvertieren C# im XML-Format so sein:

<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> 

ich eine tiefe Suche tat und ich fand etwas hilfreiches online wie this. Aber das verwendet Beziehungen, und meine Daten sind nur eine Tabelle. ich auch diesen C# -Code versucht:

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(); 
} 

Das Ergebnis war ein anderes Format, das nicht verschachteltes XML ist wie ich erklärte. see image

Wie kann ich meine Tabelle in das XML-Format konvertieren, das ich brauche?

+0

Datentabelle, WriteXml wird es in einem Format schreiben es für sie zurück – Plutonix

+0

Lesen braucht kein Ich habe auch versucht, dass es nur einen Knoten zurückgibt, Sie versuchen es, aber es ist falsch –

Antwort

1

Sie müssen GroupBy verwenden, um die Zeilen zu gruppieren, und dann die gewünschten Teile in XElements auswählen.
Der folgende Code sollte tun, was Sie wollen:

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(); 

Fiddle: https://dotnetfiddle.net/qEWNvj

+0

perfekt! Danke –

+0

Kein Problem; froh, dass ich helfen konnte. –

0

Mein Stil ist ein wenig anders als die anderen Antworten. Der Code wird getestet und entspricht Ihren erwarteten Ergebnissen.

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")) 
          ))} 
        ))} 
      ))); 

     } 
    } 
}