我有一个DataTable,我从数据库中选择(好吧,这些数据跨越几个表,查询后放入DataTable,它显示在下面)
ColumnA ColumnB
a 11
b 33
b 44
a 22
b 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#是否有一种简单的方法来实现它?
答案 0 :(得分:5)
为什么要打扰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。
马克
答案 1 :(得分:2)
使用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.
答案 2 :(得分:2)
好的,第二种方法是在DataTable
开始学习数据后可用。
代码更复杂,因为基于DataTable,你在分组等方面做得不够。我正在构建XmlDocument
(因为你在.NET 2.0上)同时扫描数据行。我需要跟踪字典中的<header>
元素,以便为文档中已存在的XmlElement
添加具有相同“ColumnA”值的第二个,第三个条目 - 它有点涉及,但是如果你仔细研究它,我希望你看到它真的没有任何诡计或任何东西 - 只需要在构建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;
答案 3 :(得分:-1)
这将使用.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")))));