Search code examples
.netxmlxmlnodexmlnodelist

How populate XmlNodeList with all the children of a node with the same name?


Given a XmlNode containing the following XML fragment, how do I fill XmlNodeList with book nodes?

XMLNode nodeLibrary contains:

<library>
  <book>
      <title>Three Little Pigs</title>
  </book>
  <book>
      <title>Batman</title>
  </book>
  <address>123 Main St.</address>
  <phone>111-111-1111</phone>
</library>

This should be really easy but I can't figure it out:

A) Cannot implicitly convert type 'System.Xml.XmlElement' to 'System.Xml.XmlNodeList':

XmlNodeList books = nodeLibrary["book"];

I guess the method property shortcut above assumes there's a SINGLE child named book, not multiple!

B) XmlNode doesn't have a GetChildren() method:

XmlNodeList books = nodeLibrary.GetChildren("book");

C) XmlNode's ChildNodes property gets ALL children, not just book nodes.

D) I tried using SelectNodes() method but the root is the larger document, not the library fragment in the current XmlNode that was selected from a larger document earlier using SelectNodes.

Any ideas? Pete


Solution

  • You can use SelectNodes, and in the XPath query pass a '.' to start searching from that node:

    public class StackOverflow_6618097
    {
        const string XML = @"<buildings>
     <library>
      <book>
       <title>Three Little Pigs</title>
      </book>
      <book>
       <title>Batman</title>
      </book>
      <address>123 Main St.</address>
      <phone>111-111-1111</phone>
      <hidden>
       <book>
        <title>The Hidden Treasure</title>
       </book>
      </hidden>
     </library>
     <bookstore>
      <book>
       <title>Cat in the Hat</title>
      </book>
     </bookstore>
    </buildings>";
    
        public static void Test()
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(XML);
            XmlNode libraryNode = doc.SelectSingleNode("//library");
            XmlNodeList libraryBooks = libraryNode.SelectNodes(".//book");
            Console.WriteLine("Books: {0}", libraryBooks.Count);
            foreach (XmlNode node in libraryBooks)
            {
                Console.WriteLine(node.OuterXml);
            }
        }
    }