How do I use XmlReader on an XmlDocument passed as a parameter

T

Thirsty Traveler

All of the XmlReader examples assume that the XmlDocument is being read from
a file. However, I would like to use it with an XmlDocument passed as a
method parameter, but am not sure how.

Any suggestions?
 
M

Martin Honnen

Thirsty said:
All of the XmlReader examples assume that the XmlDocument is being read from
a file. However, I would like to use it with an XmlDocument passed as a
method parameter, but am not sure how.

XmlReader is a fast, forward only non caching way to parse XML. If you
have an XmlDocument instance then XML has already been parsed into a
navigable tree model on which you can do DOM and XPath operations. So I
am not sure why you think you need an XmlReader once you have an
XmlDocument. If you nevertheless want to use the XmlReader API then
there is XmlNodeReader e.g.
XmlReader reader = new XmlNodeReader(xmlDocumentInstanceOrOtherXMLNode);
 
M

Marc Gravell

What exactly are you trying to do? Read the XmlDocument? If you already have
an XmlDocument, then XPath/XQuery (.SelectNodes(), .SelectSingleNode()) and
the object-model (.GetAttribute() etc) would seem the natural choice - as it
is already too late to beefit from the efficiencies of XmlReader... plus it
is a lot easier to get right! Unless you need to pass a corresponding
xml-reader to another method?

Marc
 
T

Thirsty Traveler

I have an XML document that is passed from a web service that contains 1 to
many transaction requests to our mainframe. I need to map the values in this
XML document to the mainframe transaction and call it one or more times
(once for each transaction in the XML document). I was thinking XmlReader
would be faster for this purpose.
 
J

Jon Skeet [C# MVP]

Thirsty Traveler said:
I have an XML document that is passed from a web service that contains 1 to
many transaction requests to our mainframe. I need to map the values in this
XML document to the mainframe transaction and call it one or more times
(once for each transaction in the XML document). I was thinking XmlReader
would be faster for this purpose.

Faster than what? If you've already got an XmlDocument, all the parsing
has already been done. XML parsing is basically what the reader is for,
so it's redundant at this point.
 
T

Thirsty Traveler

Hmmm... so in that case, what if I have a document such as this:

<REQUEST_GROUP>
<REQUEST >
<REQUEST_DATA>
<FLOOD_REQUEST _ActionType="Original"
OriginalFloodDeterminationLoanIdentifier="00001238">
- <BORROWER _FirstName="Firstname1" _LastName="Lastname1" >
<_RESIDENCE _City="San Rafael" _County=""
_PostalCode="94903" _State="CA" _StreetAddress="1234 Sugarhill Drive" />
</BORROWER>
- <BORROWER _FirstName="Firstname2" _LastName="Lastname2">
<_RESIDENCE _City="Tustin" _County=""
_PostalCode="92780" _State="CA" _StreetAddress="5678 Tustin Ranch Rd."
_StreetAddress2="" />
</BORROWER>
</FLOOD_REQUEST >
<FLOOD_REQUEST _ActionType="Original"
OriginalFloodDeterminationLoanIdentifier="00001238">
- <BORROWER _FirstName="Firstname3" _LastName="Lastname3" >
<_RESIDENCE _City="San Rafael" _County=""
_PostalCode="94903" _State="CA" _StreetAddress="9012 Sugarhill Drive" />
</BORROWER>
- <BORROWER _FirstName="Firstname4" _LastName="Lastname4">
<_RESIDENCE _City="Tustin" _County=""
_PostalCode="92780" _State="CA" _StreetAddress="3456 Tustin Ranch Rd."
_StreetAddress2="" />
</BORROWER>
</FLOOD_REQUEST >
</REQUEST_DATA>
<REQUEST >
<REQUEST_GROUP>

The data from this example would need to be parsed into two flood
transactions, each with two co-borrowers and associated residences. However,
doing something like
XmlNodeList nodeList = xml.GetElementsByTagName("BORROWER") returns an array
of four, when I really want two for each request. Other than using the
XmlReader, I am not sure of the best way to do this.
 
J

Jon Skeet [C# MVP]

The data from this example would need to be parsed into two flood
transactions, each with two co-borrowers and associated residences. However,
doing something like
XmlNodeList nodeList = xml.GetElementsByTagName("BORROWER") returns an array
of four, when I really want two for each request. Other than using the
XmlReader, I am not sure of the best way to do this.

You should get each FLOOD_REQUEST one at a time, and then find the
BORROWER elements underneath that FLOOD_REQUEST.
 
M

Marc Gravell

Like so:

foreach(XmlElement flood in
doc.SelectNodes("/REQUEST_GROUP/REQUEST/REQUEST_DATA/FLOOD_REQUEST")) {
Console.WriteLine("Flood " +
flood.GetAttribute("OriginalFloodDeterminationLoanIdentifier"));
foreach (XmlElement borrower in
flood.SelectNodes("BORROWER")) {
Console.WriteLine("Borrower " +
borrower.GetAttribute("_FirstName") + " " +
borrower.GetAttribute("_LastName"));
}
}


Note that this is a simple example of the SelectNodes and
SelectSingleNode methods; they can handle far more expressive queries,
such as "where"-style clauses, parent/child/sibling/ancestor/descendant
queries, etc. Read up on XPath and XQuery for more information.

Marc
 
T

Thirsty Traveler

Cool, this works great.

I am curious why XmlElements can be extracted from an XmlNodeList? For
example, XmlElement x = flood.SelectSingleNode("BORROWER") generates a
compile error.
 
T

Thirsty Traveler

Actially, I got it to work by casting it.

Thirsty Traveler said:
Cool, this works great.

I am curious why XmlElements can be extracted from an XmlNodeList? For
example, XmlElement x = flood.SelectSingleNode("BORROWER") generates a
compile error.
 
J

Jon Skeet [C# MVP]

Thirsty Traveler said:
Cool, this works great.

I am curious why XmlElements can be extracted from an XmlNodeList? For
example, XmlElement x = flood.SelectSingleNode("BORROWER") generates a
compile error.

That's because SelectSingleNode returns a Node, not an Element - you
might have selected an attribute or a text node, for instance, neither
of which are elements.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top