I'm trying to read the following Xml document as fast as I can and let additional classes manage the reading of each sub block.
<ApplicationPool>
<Accounts>
<Account>
<NameOfKin></NameOfKin>
<StatementsAvailable>
<Statement></Statement>
</StatementsAvailable>
</Account>
</Accounts>
</ApplicationPool>
However, I'm trying to use the XmlReader object to read each Account and subsequently the "StatementsAvailable". Do you suggest using XmlReader.Read and check each element and handle it?
I've thought of seperating my classes to handle each node properly. So theres an AccountBase class that accepts a XmlReader instance that reads the NameOfKin and several other properties about the account. Then I was wanting to interate through the Statements and let another class fill itself out about the Statement (and subsequently add it to an IList).
Thus far I have the "per class" part done by doing XmlReader.ReadElementString() but I can't workout how to tell the pointer to move to the StatementsAvailable element and let me iterate through them and let another class read each of those proeprties.
Sounds easy!
My experience of
XmlReader
is that it's very easy to accidentally read too much. I know you've said you want to read it as quickly as possible, but have you tried using a DOM model instead? I've found that LINQ to XML makes XML work much much easier.If your document is particularly huge, you can combine
XmlReader
and LINQ to XML by creating anXElement
from anXmlReader
for each of your "outer" elements in a streaming manner: this lets you do most of the conversion work in LINQ to XML, but still only need a small portion of the document in memory at any one time. Here's some sample code (adapted slightly from this blog post):I've used this to convert the StackOverflow user data (which is enormous) into another format before - it works very well.
EDIT from radarbob, reformatted by Jon - although it's not quite clear which "read too far" problem is being referred to...
This should simplify the nesting and take care of the "a read too far" problem.
This takes care of "a read too far" problem because it implements the classic while loop pattern:
You can loop through xmlnode and get the data...... C# XML Reader
I am not experiented .But i think XmlReader is unnecessary. It is very hard to use.
XElement is very easy to use.
If you need performance ( faster ) you must change file format and use StreamReader and StreamWriter classes.
For sub-objects,
ReadSubtree()
gives you an xml-reader limited to the sub-objects, but I really think that you are doing this the hard way. Unless you have very specific requirements for handling unusual / unpredicatable xml, useXmlSerializer
(perhaps coupled withsgen.exe
if you really want).XmlReader
is... tricky. Contrast to:We do this kind of XML parsing all the time. The key is defining where the parsing method will leave the reader on exit. If you always leave the reader on the next element following the element that was first read then you can safely and predictably read in the XML stream. So if the reader is currently indexing the
<Account>
element, after parsing the reader will index the</Accounts>
closing tag.The parsing code looks something like this:
The
Statements
class just reads in the<StatementsAvailable>
nodeThe
Statement
class would look very much the sameThe following example navigates through the stream to determine the current node type, and then uses XmlWriter to output the XmlReader content.
The following example uses the XmlReader methods to read the content of elements and attributes.