-1

What is the suggested way to investigate XML recursively?
XMLReader / XMLDocument/XMLTextReader /other option ?

I'm a little bit confused why we have so much ways to read XML.

Important Note: I have a constraint which is the Xml reading object should be able to create itself from a given Stream reference object.

JavaSa
  • 5,813
  • 16
  • 71
  • 121
  • It's not clear what you are trying to do, but most convenient way to work with xml is LINQ to XML. You can load XDocument from stream. – Sergey Berezovskiy Dec 22 '12 at 13:14
  • @lazyberezovsky: I'm willing to avoid the `LINQ` queries right now, because I need more time to learn how to use it properly, so right now I need the most suitable way to be able to do recursion on hierarchical xml. My recursion end condition should be based on if current element hasn't children, then I will get some info from this level and return. Else I want to drill down with recursion on the current element, to start inspect his own children – JavaSa Dec 22 '12 at 13:22

2 Answers2

3

Both XDocument and XmlDocument support random access of the document and therefore support bi-directional traversing of the node hierarchy. Therefore, either of those would be good choices for a recursive method.

XDocument is designed for working with LINQ whereas XmlDocument is more convenient when querying the document with XPath. It's really a matter of preference and what you need at the time. Both are equally valid options and provide very similar functionality.

XMLTextReader is more efficient because it simply reads one node at a time from a stream, without validating the entire document graph. However, it is forward-only, so you can't traverse back up a node tree to get back to a parent node, therefore it's probably not a good choice for what you are doing.

XMLReader is the abstract base class for the XMLTextReader (among others), so it cannot be used directly.

UPDATE

Since you mentioned in a comment, above, that all you are really trying to do is find all the leaf elements, you don't really need to use recursion at all. You can take advantage of LINQ or XPath to do all the work for you. Since you said you didn't want to use LINQ, here's how to do it with XPath via XmlDocument:

XmlNodeList leafElements = doc.SelectNodes("//*[not(node())]");

Or with XDocument:

IEnumerable<XElement> leafElements = doc.XPathSelectNodes("//*[not(node())]");
Steven Doggart
  • 43,358
  • 8
  • 68
  • 105
  • 3
    You can use XPathSelectElement with XDocument – Sergey Berezovskiy Dec 22 '12 at 13:28
  • Well just to mention that `XMLReader` can be used directly and even can be created which is somehow strange because it's abstract. see:http://msdn.microsoft.com/en-us/library/756wd7zs.aspx – JavaSa Dec 22 '12 at 13:29
  • 1
    @lazyberezovsky Yes, it's really no more difficult. I suppose I should have said that it's "more commonly used" with XPath rather than saying that it's "more convenient". – Steven Doggart Dec 22 '12 at 13:29
  • Anyway back to the main subject, do everybody agree that using `Xdocument` with `XPathSelectElement` will be the most simple and suitable regarding my comment back to lazyberezovsky – JavaSa Dec 22 '12 at 13:32
  • @JavaSa Well, `XMLReader.Create` returns a new object that is of a type that is derived from the base `XMLReader` class. It obviously doesn't create an `XMLReader` object, since it's an abstract class, therefore there's no such thing. – Steven Doggart Dec 22 '12 at 13:32
  • @StevenDoggart: I'm not trying to just find leafs. I'm parsing back an XML which represent XML information on a class I just serialized by myself, therefore I need it in order to deSerialize back from XML info to class instances, so I guess I still need to drill each level, because in each one I will need to connect each class or primitive under his parent Class instance. By finding just the leafs you will not be able to do so – JavaSa Dec 22 '12 at 13:51
  • @StevenDoggart: By the way I know that I don't have to implement xml serialization myself, but it is part of an exercise – JavaSa Dec 22 '12 at 13:52
1

I've always been partial to XDocument myself. You'd want to use XDocument.Load(Stream) (or one of its overloads) to read in the data from a stream.

mlorbetske
  • 5,529
  • 2
  • 28
  • 40