LINQ to read XML LINQ to read XML xml xml

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