在 C# 中将 DataTable 转换为 XML 层次结构
Convert DataTable into XML hierarchy in 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。
但是那个用关系,我的数据就一个table。
我也试过这个 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
如何将我的 table 转换成我需要的 XML 格式?
您需要使用GroupBy
对行进行分组,然后select您想要的部分进入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();
Fiddle: https://dotnetfiddle.net/qEWNvj
我的风格和其他回答有点不同。代码已经过测试并符合您的预期结果。
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"))
))}
))}
)));
}
}
}
我有以下数据表:
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。 但是那个用关系,我的数据就一个table。 我也试过这个 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
如何将我的 table 转换成我需要的 XML 格式?
您需要使用GroupBy
对行进行分组,然后select您想要的部分进入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();
Fiddle: https://dotnetfiddle.net/qEWNvj
我的风格和其他回答有点不同。代码已经过测试并符合您的预期结果。
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"))
))}
))}
)));
}
}
}