Cainnech
Cainnech

Reputation: 459

Iterating through a list of elements inside an element with a specific index

I have an XML-document that I'm trying to extract data from.

<folder>
<list index="1">
<item index="1" >
<field type="IMAGE">
<url>https://www.test.com/0001.png</url>
</field>
</item>
<item index="2">
<field type="IMAGE">
<url>https://www.test.com/0002.png</url>
</field>
</item>
</list>

etc...

I'm trying to get a list of all the fields that have the type "IMAGE" inside of the list with the index 1. There are multiple lists in the xml but they have other indexes, but I only want to extract the ones from the list with index 1. How do I go about?

I tried to do:

foreach (var list in xmlDoc.Descendants("list"))
{
   if (list.Attribute("index").Value == "1") // GET THE LIST
   {
       foreach (var field in list)
       {
           if (field.Attribute("type") != null && field.Attribute("type").Value == "IMAGE")
           {
               MessageBox.Show(field.Element("url").Value);
           }
       }
   }
}

but this is giving me an error message:

Error 2 foreach statement cannot operate on variables of type 'System.Xml.Linq.XElement' because 'System.Xml.Linq.XElement' does not contain a public definition for 'GetEnumerator'

How can I resolve this?

Upvotes: 0

Views: 254

Answers (2)

splash58
splash58

Reputation: 26153

Because the question has xpathtag :)

//list[@index="1"]//field[@type="IMAGE"]/url/text() 

Upvotes: 1

Charles Mager
Charles Mager

Reputation: 26213

You're trying to iterate an element directly, you'd need to iterate its descendant field elements, so instead of:

foreach (var field in list)

You want:

foreach (var field in list.Descendants("field"))

That said, an easier way of doing this is to make use of LINQ:

var urls = xmlDoc.Descendants("list")
    .Where(e => (int)e.Attribute("index") == 1)
    .Descendants("field")
    .Where(e => (string)e.Attribute("type") == "IMAGE")
    .Select(e => (string)e.Element("url"));

Upvotes: 3

Related Questions