Question

So I'm trying to parse an xml file:

 <?xml version="1.0" encoding="utf-8" ?>
<Root>    
  <att1 name="bob" age="unspecified" xmlns="http://foo.co.uk/nan">    
  </att1>    
</Root>

Using the following code:

XElement xDoc= XElement.Load(filename);
var query = from c in xDoc.Descendants("att1").Attributes() select c;
foreach (XAttribute a in query)
{
    Console.WriteLine("{0}, {1}",a.Name,a.Value);
}

Nothing is written to the console unless I delete xmlns="http://foo.co.uk/nan" from the xml file, after which, I get a list of attribute names and values as one would expect, and as I need!

Edit: Formatting.

Was it helpful?

Solution

You have to use the same namespace in your code:

XElement xDoc= XElement.Load(filename);
XNamespace ns = "http://foo.co.uk/nan";
var query = from c in xDoc.Descendants(ns + "att1").Attributes() select c;
foreach (XAttribute a in query)
{
    Console.WriteLine("{0}, {1}",a.Name,a.Value);
}

Attributes don't pick up the default (xmlns=....) namespace, so you don't need to qualify them. The namespace tag (xmln:tags=....)is purely local to the document or API use, the names are really namespace + local name always so you have to always specify the namespace.

OTHER TIPS

Your call to Descendants is querying for an element named "att1" in no namespace.

If you called Descendants("{http://foo.co.uk/nan}att1") you would select the namespaced element but not the non-namespaced element.

You could select elements named "att1" in any or no namespace like this:

var query = from c in xDoc.Descendants() where c.Name.LocalName == "att1" select c.Attributes;

You need to specify the namespace in the Descendants call, like this:

XNamespace ns = "http://foo.co.uk/nan";
foreach (XAttribute a in xDoc.Descendants(ns + "att1"))
{
    Console.WriteLine("{0}, {1}",a.Name,a.Value);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top