Search code examples
c#xpathxpathnavigator

How do I extract child nodes from XML file using XPath when both child nodes must exist?


I am trying to extract certain values from an xml document. In the example below, I want to store the values stored in the 'c' and 'd' nodes in a list, but only where the 'b' node contains both 'c' AND 'd'. The code I have so far loops through all of the 'b' nodes, but I am uncertain what to put in the while loop, or if this is the best approach.

XmlDocument attrsXML = new XmlDocument();
attrsXML.LoadXml(dbReader["SampleXml"].ToString());

XPathNavigator nav = attrsXML.CreateNavigator();

XPathNodeIterator attribNodes = nav.Select("/a/b");

while (attribNodes.MoveNext())
{
    // What do I need to put here in order to extract the 'c' and 'd' nodes?
    // Any other nodes can be ignored (such as 'e' above). I am only interested
    // when 'b' contains both 'c' AND 'd'.
}

Where 'SampleXml' loaded from the database is:

<a>
    <b>
        <c>Extract this</c>
        <d>And this</d>
        <e>not this</e>
    </b>
    <b>
        <c>not this</c>
        <e>not this</e>
    </b>
    <b>
        <c>Extract this</c>
        <d>And this</d>
    </b>
</a>

Any help appreciated.


Solution

  • You can use the following code:

    XmlDocument attrsXML = new XmlDocument();
    attrsXML.LoadXml(dbReader["SampleXml"].ToString());
    
    
    XmlNodeList nodeList = attrsXML.SelectNodes("/a/b[c and d]");
    
    foreach (XmlNode xmlNode in nodeList)
    {
      string cText = xmlNode.SelectSingleNode("c").InnerText;
      string dText = xmlNode.SelectSingleNode("d").InnerText;
    }
    

    The XPath "/a/b[c and d]" returns all b elements which contain c and d elements as children, which means you don't need to check it inside the loop manually.