LINQ to read XML
Try this.
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);}
Or, if you want a more general approach - i.e. for nesting up to "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();}
A couple of plain old foreach
loops provides a clean solution:
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); }}