Search code examples
c#xmlreader

XmlReader stops at nested while


I have this xml:

<Root>
   <Client>
     <Name>Some Name</Name>
     <Messages>
         <Type name="mail" value="a@a.com"></Type>
         <Type name="chat" value="some-username"></Type>
     </Messages>
   </Client>
   ...................MORE CLIENTS HERE
</Root>

I loop through it with xmlreader and It is working as expected.
the problem is when I try to loop on nodes "<Type", this is where the first code get stop.

The code reads the xml correctly, but it stop after the first iteration of the nested while:

using (XmlReader reader = XmlReader.Create(new StringReader(xmlString), settings))
{
    while (reader.ReadToFollowing("Client"))
    {
         reader.ReadToFollowing("Name");
         var message = reader.ReadElementContentAsString();
         Trace.WriteLine("message: " + message);

         while (reader.ReadToFollowing("Type")){
              var value = reader.GetAttribute("value");
              var name = reader.GetAttribute("name");

         }//everything stops here///
    }
}

How can I continue after the first client?
thanks


Solution

  • This should work , the main difference is that :

    • ReadToFollowing reads data through the whole document which means through all client nodes not just a subtree
    • To solve this you need to first read to Message element and the create a reader for subtree (ReadSubtree) to keep your data withing Client node

      using (XmlReader reader = XmlReader.Create(new StringReader(xmlString), settings))
          {
              while (reader.ReadToFollowing("Client"))
              {
                  reader.ReadToFollowing("Name");
                  var message = reader.ReadElementContentAsString();
      
                  //advance to <Message> element
                  reader.ReadToFollowing("Messages");
      
                  //create sub-tree reader to restrict the scope
                  var typeReader = reader.ReadSubtree();
      
                  while (typeReader.ReadToFollowing("Type"))
                  {
                      var value = reader.GetAttribute("value");
                      var name = reader.GetAttribute("name");
                  }//everything stops here///
              }
          }