我有这个XML文件
有人可以使用LINQ给我一个C#代码,这是打印此结果的最简单方法:(
如果它是一个level2节点,请注意额外的空间)
A A1 A2 B B1 B2 C
目前我得到了这段代码
XDocument xdoc = XDocument.Load("data.xml")); var lv1s = from lv1 in xdoc.Descendants("level1") select lv1.Attribute("name").Value; foreach (var lv1 in lv1s) { result.AppendLine(lv1); var lv2s = from lv2 in xdoc...??? }
bendewey.. 219
试试这个.
using System.Xml.Linq; void Main() { StringBuilder result = new StringBuilder(); //Load xml XDocument xdoc = XDocument.Load("data.xml"); //Run query var lv1s = from lv1 in xdoc.Descendants("level1") select new { Header = lv1.Attribute("name").Value, Children = lv1.Descendants("level2") }; //Loop through results foreach (var lv1 in lv1s){ result.AppendLine(lv1.Header); foreach(var lv2 in lv1.Children) result.AppendLine(" " + lv2.Attribute("name").Value); } Console.WriteLine(result); }
这看起来像一种"硬编码"的方法. (26认同)
@bendewey我问一个类似的问题,请你检查一下,这里:http://stackoverflow.com/questions/13247449/customize-xml-serialize-with-new-tags-and-attributes-and-root (3认同)
就像乘坐航空母舰去钓鱼一样. (2认同)
dommer.. 53
或者,如果您想要更通用的方法 - 即嵌套到"levelN":
void Main() { XElement rootElement = XElement.Load(@"c:\events\test.xml"); Console.WriteLine(GetOutline(0, rootElement)); } private string GetOutline(int indentLevel, XElement element) { StringBuilder result = new StringBuilder(); if (element.Attribute("name") != null) { result = result.AppendLine(new string(' ', indentLevel * 2) + element.Attribute("name").Value); } foreach (XElement childElement in element.Elements()) { result.Append(GetOutline(indentLevel + 1, childElement)); } return result.ToString(); }
dommer.. 21
一些简单的旧foreach
循环提供了一个干净的解决方案:
foreach (XElement level1Element in XElement.Load("data.xml").Elements("level1")) { result.AppendLine(level1Element.Attribute("name").Value); foreach (XElement level2Element in level1Element.Elements("level2")) { result.AppendLine(" " + level2Element.Attribute("name").Value); } }
delliottg.. 19
以下是一些基于@bendewey和@dommer示例的完整工作示例.我需要稍微调整一下才能使它工作,但是如果另一个LINQ noob正在寻找工作示例,那么你去:
//bendewey's example using data.xml from OP using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; class loadXMLToLINQ1 { static void Main( ) { //Load xml XDocument xdoc = XDocument.Load(@"c:\\data.xml"); //you'll have to edit your path //Run query var lv1s = from lv1 in xdoc.Descendants("level1") select new { Header = lv1.Attribute("name").Value, Children = lv1.Descendants("level2") }; StringBuilder result = new StringBuilder(); //had to add this to make the result work //Loop through results foreach (var lv1 in lv1s) { result.AppendLine(" " + lv1.Header); foreach(var lv2 in lv1.Children) result.AppendLine(" " + lv2.Attribute("name").Value); } Console.WriteLine(result.ToString()); //added this so you could see the output on the console } }
接下来:
//Dommer's example, using data.xml from OP using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; class loadXMLToLINQ { static void Main( ) { XElement rootElement = XElement.Load(@"c:\\data.xml"); //you'll have to edit your path Console.WriteLine(GetOutline(0, rootElement)); } static private string GetOutline(int indentLevel, XElement element) { StringBuilder result = new StringBuilder(); if (element.Attribute("name") != null) { result = result.AppendLine(new string(' ', indentLevel * 2) + element.Attribute("name").Value); } foreach (XElement childElement in element.Elements()) { result.Append(GetOutline(indentLevel + 1, childElement)); } return result.ToString(); } }
这些都使用csc.exe版本4.0.30319.1在VS2010中编译和工作,并提供完全相同的输出.希望这些可以帮助那些正在寻找代码工作示例的人.
编辑:添加了@eglasius的例子,因为它对我有用:
//@eglasius example, still using data.xml from OP using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; class loadXMLToLINQ2 { static void Main( ) { StringBuilder result = new StringBuilder(); //needed for result below XDocument xdoc = XDocument.Load(@"c:\\deg\\data.xml"); //you'll have to edit your path var lv1s = xdoc.Root.Descendants("level1"); var lvs = lv1s.SelectMany(l=> new string[]{ l.Attribute("name").Value } .Union( l.Descendants("level2") .Select(l2=>" " + l2.Attribute("name").Value) ) ); foreach (var lv in lvs) { result.AppendLine(lv); } Console.WriteLine(result);//added this so you could see the result } }
eglasius.. 8
XDocument xdoc = XDocument.Load("data.xml"); var lv1s = xdoc.Root.Descendants("level1"); var lvs = lv1s.SelectMany(l=> new string[]{ l.Attribute("name").Value } .Union( l.Descendants("level2") .Select(l2=>" " + l2.Attribute("name").Value) ) ); foreach (var lv in lvs) { result.AppendLine(lv); }
PS.你必须在任何这些版本上使用.Root.
试试这个.
using System.Xml.Linq; void Main() { StringBuilder result = new StringBuilder(); //Load xml XDocument xdoc = XDocument.Load("data.xml"); //Run query var lv1s = from lv1 in xdoc.Descendants("level1") select new { Header = lv1.Attribute("name").Value, Children = lv1.Descendants("level2") }; //Loop through results foreach (var lv1 in lv1s){ result.AppendLine(lv1.Header); foreach(var lv2 in lv1.Children) result.AppendLine(" " + lv2.Attribute("name").Value); } Console.WriteLine(result); }
或者,如果您想要更通用的方法 - 即嵌套到"levelN":
void Main() { XElement rootElement = XElement.Load(@"c:\events\test.xml"); Console.WriteLine(GetOutline(0, rootElement)); } private string GetOutline(int indentLevel, XElement element) { StringBuilder result = new StringBuilder(); if (element.Attribute("name") != null) { result = result.AppendLine(new string(' ', indentLevel * 2) + element.Attribute("name").Value); } foreach (XElement childElement in element.Elements()) { result.Append(GetOutline(indentLevel + 1, childElement)); } return result.ToString(); }
一些简单的旧foreach
循环提供了一个干净的解决方案:
foreach (XElement level1Element in XElement.Load("data.xml").Elements("level1")) { result.AppendLine(level1Element.Attribute("name").Value); foreach (XElement level2Element in level1Element.Elements("level2")) { result.AppendLine(" " + level2Element.Attribute("name").Value); } }
以下是一些基于@bendewey和@dommer示例的完整工作示例.我需要稍微调整一下才能使它工作,但是如果另一个LINQ noob正在寻找工作示例,那么你去:
//bendewey's example using data.xml from OP using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; class loadXMLToLINQ1 { static void Main( ) { //Load xml XDocument xdoc = XDocument.Load(@"c:\\data.xml"); //you'll have to edit your path //Run query var lv1s = from lv1 in xdoc.Descendants("level1") select new { Header = lv1.Attribute("name").Value, Children = lv1.Descendants("level2") }; StringBuilder result = new StringBuilder(); //had to add this to make the result work //Loop through results foreach (var lv1 in lv1s) { result.AppendLine(" " + lv1.Header); foreach(var lv2 in lv1.Children) result.AppendLine(" " + lv2.Attribute("name").Value); } Console.WriteLine(result.ToString()); //added this so you could see the output on the console } }
接下来:
//Dommer's example, using data.xml from OP using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; class loadXMLToLINQ { static void Main( ) { XElement rootElement = XElement.Load(@"c:\\data.xml"); //you'll have to edit your path Console.WriteLine(GetOutline(0, rootElement)); } static private string GetOutline(int indentLevel, XElement element) { StringBuilder result = new StringBuilder(); if (element.Attribute("name") != null) { result = result.AppendLine(new string(' ', indentLevel * 2) + element.Attribute("name").Value); } foreach (XElement childElement in element.Elements()) { result.Append(GetOutline(indentLevel + 1, childElement)); } return result.ToString(); } }
这些都使用csc.exe版本4.0.30319.1在VS2010中编译和工作,并提供完全相同的输出.希望这些可以帮助那些正在寻找代码工作示例的人.
编辑:添加了@eglasius的例子,因为它对我有用:
//@eglasius example, still using data.xml from OP using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; class loadXMLToLINQ2 { static void Main( ) { StringBuilder result = new StringBuilder(); //needed for result below XDocument xdoc = XDocument.Load(@"c:\\deg\\data.xml"); //you'll have to edit your path var lv1s = xdoc.Root.Descendants("level1"); var lvs = lv1s.SelectMany(l=> new string[]{ l.Attribute("name").Value } .Union( l.Descendants("level2") .Select(l2=>" " + l2.Attribute("name").Value) ) ); foreach (var lv in lvs) { result.AppendLine(lv); } Console.WriteLine(result);//added this so you could see the result } }
XDocument xdoc = XDocument.Load("data.xml"); var lv1s = xdoc.Root.Descendants("level1"); var lvs = lv1s.SelectMany(l=> new string[]{ l.Attribute("name").Value } .Union( l.Descendants("level2") .Select(l2=>" " + l2.Attribute("name").Value) ) ); foreach (var lv in lvs) { result.AppendLine(lv); }
PS.你必须在任何这些版本上使用.Root.