Search code examples
c#xmlreader

XmlReader.ReadSubTree() always return NONE


I have the code below which use to handle XML file, the xml format as:

<?xml version="1.0" encoding="UTF-8"?>
<Operation>
   <A>
      <First>F</First>
      <Second>S</Second>
   </A>
   <B>
      <Third>T</Third>
   </B>
</Operation>

the code to read the subtree is:

XmlReader reader = XmlReader.Create(strReader, settings);
String name = reader.Name;
if (name.ToLower().Equals("operation"))
{
    XmlReader read = reader.ReadSubtree();  
    Console.WriteLine("Start is {0}", read.Name);
}

but the function reader.ReadSubTree() always return as NONE, instead of a subtree.

What could be wrong here?


Solution

  • As per MSDN the ReadSubTree will return

    A new XML reader instance set to ReadState.Initial. Calling the Read method positions the new reader on the node that was current before the call to the ReadSubtree method.

    This is why your new reader is still at initial location. The next Read() call will place it at Operation where the parent reader was.

    You can use either ReadToFollowing(nameOfNode) to directly read to that node if you know the name of in the xml. Or call Read method on the subtree reader until you reach the desired node. Remember whitespaces if preserved are also elements, so it will traverse through those as well. So one option is to use XMLReaderSettings while creating the reader and set IgnoreWhiteSpace property to true so that it will only give you elements (xml elements, declaration, comments etc.)

    See this MSDN link:

    http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.readsubtree(v=vs.110).aspx

    EDIT:

    You can also use XElement if you want to traverse elements in any order since XMLReader is forward only.

    XElement operationReader = XElement.Load(strReader);
    
    //You can use this collection to do your stuff. It will give you child of operation element
    IEnumerable<XElement> foo = operationReader.Elements();
    

    Further Reading XElement on MSDN