Search code examples
c#xmllinqxelement

XElement and XName crashes when xml has namespace to root node


Hi i was fiddeling around with xml files and i notised something i have a bit problem of solving.

I have a Xml that starts with a root node and then has another child node that can change name for example:

<root>
  <Child1>
</root>

So given that "Child1" can be changed to "Child2" or "Child3" i made this linq be able to extract the name from whatever comes my way.

first:

XElement root = XElement.Parse(xml);

var childType = root.Descendants().First(x => x.Name == "Child1" || x.Name == "Child2"|| x.Name == "Child3").Name;

So when i have my xml without a namespace, as shown above, it workes fine, i manage to extract the name from the node tag.

But when i have a namespace into the root tag it throws an error:

<root xmlns="namespace">
  <Child1>
</root>

That xml going through the same linq, throws:

Sequence contains no matching element


Solution

  • Your root element has a namespace defined (xmlns="namespace") thus all child elements are associated with the same namespace. I.e. Child1 element will be in the same namespace, and its name will contain both namespace prefix and local name ("Child1"). So you can either specify full name when searching for Child1 element:

    var ns = root.GetDefaultNamespace();
    var childType = root.Descendants()
       .First(x => x.Name == ns +"Child1" || x.Name == ns + "Child2"|| x.Name == ns + "Child3")
       .Name;
    

    Or you can look for x.Name.LocalName (but I don't recommned this approach, though it's unlikely you will have Child1 elements from another namespace).

    Note: your Child element does not have closing tag (probably it's a misprint)

    Further reading: Xml Namespaces