Search code examples
c#.netxmllinqxelement

c# Elements of elements using XElement


Not sure how I'm supposed to do this.

Here's the XML I'm working with:

<configuration>
    <tag1>
        <interestingstuff>avalue</interestingstuff>
    </tag1>

    <tag2>
         <item_type1 name="foo">
             <item_type2 name="bar">
                 <property>value1</property>
                 <property>value2</property>
             </item_type2>
             <item_type2 name="pub">
                 <property>valueX</property>
                 <property>valyeY</property>
             </item_type2>
          <item_type1>

          <item_type1 name="foo2">
              <item_type2 name="pub">
                  <property>valueX</property>
              </item_type2>
          </item_type1>
      </tag2>
</configuration>

I'm writing a function that passes a value for item_type and item_type2, and returns the list of property values for that combination.

Here's what I have. It throws a "Object not set to an instance of an object" exception at the point noted.

ArrayList properties = new ArrayList();
XDocument config = new XDocument();
config = XDocument.Parse(XML_Text);
foreach (XElement item1 in config.Root.Element("tag2").Nodes())
{
    if (item1.Attribute("name").Value.ToString() == passed_item1_value)
    {
      //this is where it's breaking
      foreach (XElement item2 in item1.Elements("item_type2").Nodes())
      {
        if item2.Attribute("name").Value.ToString() == passed_item2_value)
        {
           foreach (XElement property in item2.Elements("property").Nodes())
           {
             properties.Add(property.Value.ToString());
           }
           break;
         }
       }
       break;
     }
}

I KNOW this doesn't make sense - but I can't make it make sense.


Solution

  • I would do it this way:

    public IEnumerable<string> findValues(string item1, string item2)
    {
        config = XDocument.Parse(XML_Text)
        var res = config.Descendants("item_type1")
                        .Where(x=>x.Attribute("name").Value == item1)
                        .Descendants("item_type2")
                        .Where(x=>x.Attribute("name").Value == item2);
        return res.Descendants("property").Select(x=>x.Value);
    }