Search code examples
c#xmlxpathlinq-to-xml

Getting an XElement with a namespace via XPathSelectElements


I have an XML e.g.

    <?xml version="1.0" encoding="utf-8"?>
    <A1>
       <B2>
          <C3 id="1">
             <D7>
                <E5 id="abc" />
             </D7>
             <D4 id="1">
                <E5 id="abc" />
             </D4>
             <D4 id="2">
                <E5 id="abc" />
             </D4>
          </C3>
       </B2>
    </A1>

This is may sample code:

    var xDoc = XDocument.Load("Test.xml");
    string xPath = "//B2/C3/D4";
    //or string xPath = "//B2/C3/D4[@id='1']";

    var eleList = xDoc.XPathSelectElements(xPath).ToList();
    foreach (var xElement in eleList)
    {
        Console.WriteLine(xElement);
    }

It works perfectly, but if I add a namespace to the root node A1, this code doesn't work. Upon searching for solutions, I found this one, but it uses the Descendants() method to query the XML. From my understanding, this solution would fail if I was searching for <E5> because the same tag exists for <D7>, <D4 id="1"> and <D4 id="2">

My requirement is to search if a node exists at a particular XPath. If there is a way of doing this using Descendants, I'd be delighted to use it. If not, please guide me on how to search using the name space.

My apologies in case this is a duplicate.


Solution

  • To keep using XPath, you can use something link this:

        var xDoc = XDocument.Parse(@"<?xml version='1.0' encoding='utf-8'?>
            <A1 xmlns='urn:sample'>
                <B2>
                    <C3 id='1'>
                        <D7><E5 id='abc' /></D7>
                        <D4 id='1'><E5 id='abc' /></D4>
                        <D4 id='2'><E5 id='abc' /></D4>
                    </C3>
                </B2>
            </A1>");
    
        // Notice this
        XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
        nsmgr.AddNamespace("sample", "urn:sample");
    
        string xPath = "//sample:B2/sample:C3/sample:D4";
    
        var eleList = xDoc.XPathSelectElements(xPath, nsmgr).ToList();
        foreach (var xElement in eleList)
        {
            Console.WriteLine(xElement);
        }