0
votes

I am struggling with parsing XPathDocument with XPathNavigator where XML document contains xmlns tag, but no namesapce prefix is used.

<?xml version="1.0" encoding="UTF-8"?>
<Order version="1" xmlns="http://example.com">
    <Data>
        <Id>1</Id>
        <b>Aaa</b>
    </Data>
</Order>

SelectSingleNode method requires namespace manager with namespace defined.

XmlNamespaceManager nsmgr = new XmlNamespaceManager(nav.NameTable);
nsmgr.AddNamespace("ns","http://example.com");

As a result I have to start using ns prefix in all XPath expressions, although the original XML file does not use prefixes, for e.g.:

nav.SelectSingleNode("/ns:Order/ns:Data/ns:Id", nsmgr)

This adds an unnecessary complexity.

Is there any way to push XPathNavigator to ignore namespace and its prefixes? Ot at least use of prefixes, as namespace definition itself exists only once, so not much effort

1
I couldn't agree more, the only way that I've found is to match on localname(), which is just as ugly as prefixing every element with a namespace. Apparently in Saxon XPath v3, name spaces are only matched if you specify them, by default things match on localname(). I wish they thought of that in XPath 1.0, which sadly in the Microsoft C# world we are stuck with, unless you use Saxon or similar. - William Walseth

1 Answers

0
votes

The XML has a default namespace. So each and every XML element is bound to it, visible or not.

It is better to use LINQ to XML.

It is a preferred XML API, and available in the .Net Framework since 2007.

c#

void Main()
{
    XDocument xdoc = XDocument.Parse(@"<Order version='1' xmlns='http://example.com'>
            <Data>
                <Id>1</Id>
                <b>Aaa</b>
            </Data>
        </Order>");

    XNamespace ns = xdoc.Root.GetDefaultNamespace();

    foreach (XElement elem in xdoc.Descendants(ns + "Data"))
    {
        Console.WriteLine("ID: {0}, b: {1}"
            , elem.Element(ns + "Id")?.Value
            , elem.Element(ns + "b")?.Value);
    }
}