Search code examples
c#xmlobservablecollectionxelement

How can I maintain the treestructure of my xml-file in the code and access the "subtags"?


Hey have a little problem, I'm having a xml-file structured like this:

<cars>
  <car name="audi" id="123">
    <specs fuel="gas"/>
    <specs horsepower="150"/>
  </car>
  <car name="tesla" id="456">
    <specs fuel="electric"/>
    <specs horsepower="600"/>
  </car>
</cars

I am trying to read all the data and maintain the treestructure from the xml in the code so that I can display the car that I want lateron. Therefore I used an ObservableCollection. I tried it like this:

        XElement data = XElement.Load(path);

        IEnumerable<XElement> elements = data.Elements().Elements();

        XmlData = new ObservableCollection<XElement>();

        foreach(var item in elements)
        {
            XmlData.Add(item);
        }

With this method it doesn't add them in the collection. How can I get the different nodes from the loaded XElements and store them in an ObservableCollection? Or is there a much easier way to do this? Thanks already :)


Solution

  • I like putting results into a datatable which you can always bind to an observable view. I used xml linq to parse the xml

    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
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                DataTable dt = new DataTable();
                dt.Columns.Add("Name", typeof(string));
                dt.Columns.Add("ID", typeof(int));
                dt.Columns.Add("Fuel", typeof(string));
                dt.Columns.Add("Horsepower", typeof(int));
    
                XDocument doc = XDocument.Load(FILENAME);
    
                foreach (XElement car in doc.Descendants("car"))
                {
                    DataRow newRow = dt.Rows.Add();
                    newRow["Name"] = (string)car.Attribute("name");
                    newRow["ID"] = (int)car.Attribute("id");
                    newRow["Fuel"] = car.Descendants("specs")
                        .Where(x => x.Attribute("fuel") != null)
                        .Select(x => (string)x.Attribute("fuel"))
                        .FirstOrDefault();
                    newRow["Horsepower"] = car.Descendants("specs")
                        .Where(x => x.Attribute("horsepower") != null)
                        .Select(x => (string)x.Attribute("horsepower"))
                        .FirstOrDefault();
                }
    
            }
        }
    }