Search code examples
c#xmlreader

Use XmlReader to just get children


I have this XML:

<root>
  <row>
     <data1>Data</data1>
     <data2>Data</data2>
     <data3>Data
         <subdata>SubData</subdata>
     </data3>
  </row>
</root>

and I want to use an XmlReader to read only the <dataX> elements, without knowing the exact name of dataX. I found the ReadToNextSibling method, but it needs a name, which I do not know.


Solution

  • You can use the following XPath to filter the elements to just the <dataN> elements:

    /root/row/*[substring(name(), 0,5) = 'data']

    /root/row/*[starts-with(name(),'data')]
    

    However, XmlReader cannot use xPath nor wildcards for element names in any of its navigation methods such as ReadToNextSibling


    You could use XPathReader, which can be instantiated from an XmlReader object, as follows:

    XPathReader xpr  = new XPathReader("MyXml.xml", "/root/row/*[substring(name(), 0,5) = 'data']"); 
    
    while (xpr.ReadUntilMatch()) {
       Console.WriteLine(xpr.ReadString()); 
    } 
    

    (You can download XPathReader from Microsoft here: https://www.microsoft.com/en-us/download/details.aspx?id=22677)


    If you don't like the idea of XPathReader, you can do the following with XmlDocument:

    XmlDocument xDoc = new XmlDocument();
    xDoc.LoadXml(xml);
    XmlNode root = xDoc.DocumentElement;
    
    foreach (XmlNode item in root.SelectNodes(@"/root/row/*[substring(name(),0,5) = 'data']"))
    {
        Console.WriteLine(item.Value);
    }
    

    EDIT

    A better XPath would actually be:

    /root/row/*[starts-with(name(),'data')]