4

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

Daniele Sartori
  • 1,674
  • 22
  • 38
  • Sounds like something you can easily test yourself – Evk Apr 06 '18 at 14:29
  • Frankly, the only good answer I can give here is: "carefully". I work with serialization APIs *all the time*, and `XmlReader` is *far and away* the most awkward one to work with - figuring out which operations advance the reader to where is often a case of trial and `Exception`. – Marc Gravell Apr 06 '18 at 14:56
  • @MarcGravell that's why i was asking. I honestly find the documentation on msdn about XmlReader method pretty frustrating, and it's not easy for me to figure out which method is more suitable and when. I was looking for someone more experienced then me to clarify something – Daniele Sartori Apr 06 '18 at 15:00
  • 2
    @DanieleSartori well, based on years of working with those APIs, I can clarify exactly two things: 1) you're not wrong - the documentation is unclear, and 2) the API is awkward to use – Marc Gravell Apr 06 '18 at 15:01

1 Answers1

8

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"));
Alexander Petrov
  • 13,457
  • 2
  • 20
  • 49
  • Check my edit. I added the code for the inner loop. From my test, it seems that it gives the same output. In which case it is better to use theReadSubtree? – Daniele Sartori Apr 06 '18 at 15:26
  • 1
    @DanieleSartori - `XElement` will read all `Item` content in memory. If it is large, then memory may not be enough. Then you need to go to inner xmlreader. – Alexander Petrov Apr 06 '18 at 15:39