Search code examples
c#xmlxmlreader

Confusion about the proper way to read child nodes with XmlReader


Let's suppose i have the following Xml:

<Sections>
   <Section>
      <Item>
         <Field> myfield </Field>
         <Field> myfield </Field>
      </Item>
      <Item>
         <Field> myfield </Field>
         <Field> myfield </Field>
      </Item>
   </Section>
   <Section>
      <Item>
         <Field> myfield </Field>
         <Field> myfield </Field>
      </Item>
   </Section>
</Sections>

Now what i want is to loop though Sections, and work on each item separately, so i was thinking to do something like the following:

reader.ReadToDescendant("Section")
do
{
    Console.WriteLine("Section");
    reader.ReadToDescendant("Item");
    do
    {
        var element = (XElement)XNode.ReadFrom(reader);
        foreach (XElement el in element.Elements())
        {
            Console.WriteLine(el.Value);
        }
    }while(reader.ReadToNextSibling("Item"));
}while (reader.ReadToNextSibling("Section"))

My question is. If i repeat the same do-while loop for Item nodes, does the reader stop when it finds the closing Section tag or it will search in all the xml? Should i use reader.ReadSubtree() before the inner loop?

Note that i'm not looking for standard answer like "Use XDocument". I know that dom are easier to use, but they are not suitable for my situation


Solution

  • Use ReadSubtree to create inner reader to work with current node. Without this, the reader will not stop and continue the search until the end of the document.

    reader.ReadToDescendant("Section");
    do
    {
        Console.WriteLine("Section");
        using (var innerReader = reader.ReadSubtree())
        {
            while (innerReader.ReadToFollowing("Field"))
            {
                Console.WriteLine("field");
            }
        }
    } while (reader.ReadToNextSibling("Section"));