Link to home
Start Free TrialLog in
Avatar of Arnold Layne
Arnold LayneFlag for United States of America

asked on

XMLReader Read verses ReadToFollow Method

This code works.  It prints out two values from the xml file like it should
reader = XmlReader.Create("c:\\test.xml");
      while (reader.ReadToFollowing("chapter"))
      {
        Console.WriteLine(reader.ReadInnerXml());
      }
      reader.Close();

Open in new window


This code only prints the value once and does not print the second instance of the value of a second element with the same name which is in the XML file
reader = XmlReader.Create("c:\\test.xml");
      while (reader.Read())
      {
          reader.ReadToFollowing("chapter");
          Console.WriteLine(reader.ReadInnerXml());
      }
      reader.Close();

Open in new window


I thought that even though it might be an awkward way to do it, the example that doesn't work is walking through each node and then reading to the next chapter element. So why would this only get the first value but not eventually the second, even if in a non efficient manner? Seems like it has something to do with cursor position but I don't know exactly what.

How I see it is that it goes to the first node, and then goes to the chapter element and gets the value, and then the Read method would read the next node after the first chapter element that readtofollowing("chapter") took the cursor to, and then go to the second chapter element following the node that it is currently on, and then walk through any other nodes remaining and fail on an attempt of readtofollowing("chapter") because there would be no more chapter elements left.

So I am missing something very fundamental and important.
ASKER CERTIFIED SOLUTION
Avatar of Carl Tawn
Carl Tawn
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Arnold Layne

ASKER

Hi Carl, I understand your answer. Is this not working simply because the next node  just so happens to be another chapter element and that's why the Read method takes you to the next chapter element upon second iteration of the while? If there was only one chapter element in the chapters start element, and there was another chapter element in another start element such as "novel", would the Read method eventually get to that node via readtofiollowing within the while loop?

How I vision this is that in the first iteration of the while, the Read method takes me to the first node. Then the readtofollowing method within the while loop takes me to the chapters element after the first node. Then, on second iteration of the while loop, the Read method takes me to the next node after the first chapter element. So if the next node did not have a second chapter element, wouldn't it then go from the node it is at and find the second chapter element in the "novels" element through it's call to reaftofollowing within the while loop?

Your answer makes sense and I think I already know the answer to the second question I am asking, but I would like confirmation. Thanks.
All of the methods of the XmlReader operate from the node which the pointer currently points to. So, ReadToFollowing() literally means "move to the next element with this name that comes after the node i'm currently pointing at".

Read() on the other hand simply pushes the pointer to the next node in the document. So, if your XML looked like:
<chapters>
   <chapter>Chapter 1</chapter>
   <somethingelse />
   <chapter>Chapter 2</chapter>
</chapters>

Open in new window

Then the code you have would work fine because the logic would now be:

1) Read() call moves to XML declaration
2) ReadToFollowing() moves to first "chapter" element
3) Read() in the loop moves to the "somethingelse" element
4) ReadToFollowing() moves to the second "chapter" element
Ran this through the debugger. Seems like the difference is the following.

Since Read reads one node at a time, then just getting to the element node itself is not good enough to use the .Value property to get the text. The text portion of an element is a separate node from the element node itself. So Read is actually going to the text node for the element before asking for it's value, whereas Readtofollowing is merely going to the element node rather than the text node portion for that element, and therefore needs ReadInnerXML to get the text node portion of that element rather than using .Value because the cursor is not on that value after when using Readtofollowing.