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"))

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())

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.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Carl TawnSystems and Integration DeveloperCommented:
You basically have this:

1) Read() call moves pointer to the "xml" directive
2) ReadToFollowing() call moves pointer to first "chapter" element
3) Read() call moves pointer to second "chapter" element
4) ReadToFollowing() finds nothing because it is searching from the current location, and doesn't include the current node.

So your problem is that the Read() in the loop is pushing the pointer past the second "chapter".

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BobHavertyComhAuthor Commented:
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.
Carl TawnSystems and Integration DeveloperCommented:
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:
   <chapter>Chapter 1</chapter>
   <somethingelse />
   <chapter>Chapter 2</chapter>

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
BobHavertyComhAuthor Commented:
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.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.