Search code examples
c#xmlxpathxml-parsinghl7-v3

Xpath in XML not working because of xml namespace field


I have the following XML:

<?xml version="1.0" encoding="UTF-8" ?>
<bookstore xmlns="urn:hl7-org:v3" xmlns:voc="urn:hl7-org:v3/voc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hl7-org:v3 PORT_MT020001.xsd" type="Observation" classCode="OBS" moodCode="EVN">
    <book>
        <title lang="en">Harry Potter</title>
        <price>29.99</price>
    </book>

    <book>
        <title lang="en">Learning XML</title>
        <price>39.95</price>
    </book>
</bookstore>

When I try to use XMLDocument.SelectNodes() on the above xml like this:

XmlNodeList xmlNodelist = doc.SelectNodes("//book");
Console.WriteLine(xmlNodelist.Count);

I get a result of:

0

When I change the xmlns attribute value in root node to empty like this:

<bookstore xmlns="" ...........>

then I get back the proper result of:

2

Why is this happening? The xmlns attribute value in root node is vital to me. Is there any solution to this problem?


Solution

  • Reason why your Count shows 0 for books is because books comes under a specific namespace. If it was outside the tags that had a namespace, then your query would have resulted in 2.

    To make your queries work for tags that are part of a namespace (parent tags with namespace means all children inherits that namespace), you can use the code like this,

        XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
        nsmgr.AddNamespace("x", doc.DocumentElement.NamespaceURI);
    
        XmlNodeList xmlNodelist = doc.DocumentElement.SelectNodes("//x:book", nsmgr);
        Console.WriteLine(xmlNodelist.Count); // Prints 2
    

    What this does is creates a NamespaceManager with default namespaceUri of the document and uses x (or you can use any letter / word) to associate the tags with in searches. When you search for nodes, use this letter and the namespacemanager to get the results you need.