Finding element in XDocument?

Royi Namir picture Royi Namir · Dec 10, 2011 · Viewed 145.1k times · Source

I have a simple XML

<AllBands>
  <Band>
    <Beatles ID="1234" started="1962">greatest Band<![CDATA[lalala]]></Beatles>
    <Last>1</Last>
    <Salary>2</Salary>
  </Band>
  <Band>
    <Doors ID="222" started="1968">regular Band<![CDATA[lalala]]></Doors>
    <Last>1</Last>
    <Salary>2</Salary>
  </Band>
</AllBands>

However ,

when I want to reach the "Doors band" and to change its ID :

  using (var stream = new StringReader(result))
            {
                XDocument xmlFile = XDocument.Load(stream);

                var query = from c in xmlFile.Elements("Band")

                            select c;
                             ...

query has no results

But

If I write xmlFile.Elements().Elements("Band") so it Does find it.

What is the problem ?

Is the full path from the Root needed ?

And if so , Why did it work without specify AllBands ?

Does the XDocument Navigation require me to know the full level structure down to the required element ?

Answer

BrokenGlass picture BrokenGlass · Dec 10, 2011

Elements() will only check direct children - which in the first case is the root element, in the second case children of the root element, hence you get a match in the second case. If you just want any matching descendant use Descendants() instead:

var query = from c in xmlFile.Descendants("Band") select c;

Also I would suggest you re-structure your Xml: The band name should be an attribute or element value, not the element name itself - this makes querying (and schema validation for that matter) much harder, i.e. something like this:

<Band>
  <BandProperties Name ="Doors" ID="222" started="1968" />
  <Description>regular Band<![CDATA[lalala]]></Description>
  <Last>1</Last>
  <Salary>2</Salary>
</Band>