How do I determine if a element exists in an xml file?

C

cj

This code might even be useful to some of you. I'm playing with USPS'
interface to validate addresses. How do I deal with the fact that not
all the elements are returned all the time? For instance this inquiry
does not return a firm name. If it doesn't exist it should be blank in
my processing but as is since it doesn't exist my code stops when trying
to update the text box.


Dim URL As String
Dim webReq As Net.HttpWebRequest
Dim webResp As Net.HttpWebResponse
Dim respStr As String

Dim startTime As DateTime
Dim finishTime As DateTime

Try
URL =
"http://testing.shippingapis.com/ShippingAPITest.dll?API=Verify&XML=<AddressValidateRequest%"
& _
"20USERID=""myuserid""><Address ID=""0""><Address1></Address1>" & _
"<Address2>6406 Ivy
Lane</Address2><City>Greenbelt</City><State>MD</State>" & _
"<Zip5></Zip5><Zip4></Zip4></Address></AddressValidateRequest>"

webReq = Net.HttpWebRequest.Create(URL)

startTime = Now
webResp = webReq.GetResponse
finishTime = Now

respStr = New IO.StreamReader(webResp.GetResponseStream).ReadToEnd
Catch ex As Exception
MessageBox.Show("ex.Message = " & ex.Message)
Finally
webResp.Close()
End Try

Dim doc As New Xml.XmlDocument

doc.LoadXml(respStr)

Dim rFirmName As Xml.XmlNodeList = doc.GetElementsByTagName("FirmName")
Dim rAddress1 As Xml.XmlNodeList = doc.GetElementsByTagName("Address1")
Dim rAddress2 As Xml.XmlNodeList = doc.GetElementsByTagName("Address2")
Dim rCity As Xml.XmlNodeList = doc.GetElementsByTagName("City")
Dim rState As Xml.XmlNodeList = doc.GetElementsByTagName("State")
Dim rZip5 As Xml.XmlNodeList = doc.GetElementsByTagName("Zip5")
Dim rZip4 As Xml.XmlNodeList = doc.GetElementsByTagName("Zip4")
Dim rReturnText As Xml.XmlNodeList = doc.GetElementsByTagName("ReturnText")

TextBox3.Text = rFirmName(1).InnerText & vbCrLf & _
rAddress1(1).InnerText & vbCrLf & _
rAddress2(1).InnerText & vbCrLf & _
rCity(1).InnerText & ", " & _
rState(1).InnerText & " " & _
rZip5(1).InnerText & "-" & _
rZip4(1).InnerText & vbCrLf & _
rReturnText(1).InnerText & vbCrLf & _
"Time: " & finishTime.Subtract(startTime).ToString
 
R

rowe_newsgroups

Dim rFirmName As Xml.XmlNodeList = doc.GetElementsByTagName("FirmName")

I would change that to return a single node instead of node list if
you aren't going to use the entire list. Then just do an check on the
node and handle and possible problems. I wrote you a small console app
to demonstrate:

Sub Main()
Dim doc As New XmlDocument()

Dim noProblemsXml As String = "<address><FirmName>FirmName1</
FirmName><FirmName>FirmName2</FirmName></address>"
Dim nullNodeXml As String = "<address><FirmName>FirmName1</
FirmName></address>"
Dim noTextXml As String = "<address><FirmName>FirmName1</
FirmName><FirmName></FirmName></address>"

'//doc.LoadXml(noProblemsXml)
doc.LoadXml(nullNodeXml)
'//doc.LoadXml(noTextXml)

Dim node As XmlNode = doc.GetElementsByTagName("FirmName")(1)
If node Is Nothing Then
node = doc.CreateNode(XmlNodeType.Element, "FirmName", "")
node.InnerText = "FirmName was Nothing"
ElseIf String.IsNullOrEmpty(node.InnerText) Then
node.InnerText = "FirmName had no InnerText"
End If

Console.WriteLine(node.InnerText)
Console.Read()
End Sub

Hope that helps.

Thanks,

Seth Rowe
 
S

Steven Cheng[MSFT]

Hi cj

As for the response XML document, does it have fixed schema or structure
or will the target elements you want to detect/verify always have some
fixed attributes(such as location in the document or have certain attribute
values ...). If so, I think using XPATH query to locate XML element in a
XML document is the reasonable approach. Here are some web articles
introducing using xpath query in .NET xml processing:

#INFO: Roadmap for Executing XPath Queries in .NET Applications
http://support.microsoft.com/kb/313828

#.NET and XML: XPath Queries
http://www.developer.com/xml/article.php/3383961

#.NET and XML: Part 1¡ªXPath Queries
http://www.codeguru.com/csharp/csharp/cs_misc/designtechniques/article.php/c
7589/

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.
 
C

cj

I've read and read and I'm afraid I don't understand. I basically get
the document approach. I can have multiple addresses and each address
can have or not have several items like firmname, addr1, addr2, city,
state, zip, plus4 etc.

I need to be able to read through the addresses and determine what is in
each and get it out so I can update our records.

if I read the xml document then make the node the address and for each
node what do I do to get the individual elements?
 
S

Steven Cheng[MSFT]

Thanks for your reply Cj,

Then, would you give me a simple demo xml fragment and tell me which nodes
you want to query or detect so that I can write some test code demonstrate
using XPATH to select the nodes?

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
C

cj

Consider I've got a database of user entered addresses and I want to
validate the addresses before sending a mailing to all these folks. By
submitting their addresses to USPS (up to 5 at a time) I can get back
addresses in standard format with some missing information etc corrected
like if they left out a zip code or they have a zip but no city and
state. The database consists of the fields: Company, Addr1, Addr2,
City, State, Zip, Plus4 and Notes

Assume I sent a request to validate 3 addresses and I got the below
response. I now need to update the database. The first address has a
company name but the second doesn't. The second address has two address
lines but the first only has 1. The third address returned an error
because it was missing both state and zip--I'd probably want to put the
error description in the notes field of my database for that address. I
will need to use the address id returned to link these addresses to the
ones sent.

<?xml version="1.0"?>
<AddressValidateResponse>
<Address ID="0">
<FirmName>ABC Distribution LLC</FirmName>
<Address2>6406 IVY LN</Address2>
<City>GREENBELT</City>
<State>MD</State>
<Zip5>20770</Zip5>
<Zip4>1441</Zip4>
</Address>
<Address ID="1">
<Address1>APT B</Address1>
<Address2>8 WILDWOOD DR</Address2>
<City>OLD LYME</City>
<State>CT</State>
<Zip5>06371</Zip5>
<Zip4>1844</Zip4>
</Address>
<Address ID="2">
<Error>
<Number>-2147219079</Number>
<Source>;SQLServerTest.UnpackAddressNode</Source>
<Description>Invalid XML Element content is invalid</Description>
<HelpFile></HelpFile>
<HelpContext></HelpContext>
</Error>
<Address>
</AddressValidateResponse>


I still think a document node approach would work best for me and I
believe I can loop through the addresses like this:

doc.LoadXml(xmlfile)
nodelist = doc.SelectNodes("/AddressValidateResponse/Address")
For Each node In nodelist
'what do I do now to check the elements existence and read them?
'also need to read the ID= part of address tag.
Next
 
S

Steven Cheng[MSFT]

Hi Cj,

Well, actually the following code you used here just utilize the XPATH query

nodelist = doc.SelectNodes("/AddressValidateResponse/Address")

and after you get list of address nodes, you can still use XPATH to query
and check the value of each inner child elements(such as the FirmName,
City, State....). Here is a test code program I've written to demonstrate
this:

============================
Module Module1

Sub Main()

ProcessXml()

End Sub


Sub ProcessXml()

Dim doc As New XmlDocument
doc.Load("..\..\data.xml")

Dim addresslist As XmlNodeList


addresslist = doc.SelectNodes("/AddressValidateResponse/Address")

For Each address As XmlElement In addresslist

Console.WriteLine("======address id: {0}=============",
address.Attributes("ID").Value)

Dim err As XmlNode

Dim firmName As XmlNode

Dim city As XmlNode
Dim state As XmlNode
Dim zip4 As XmlNode
Dim zip5 As XmlNode


err = address.SelectSingleNode("./Error")

If Not err Is Nothing Then
Console.WriteLine("This is an incorrect record")
Console.WriteLine("Error Info: {0}", err.InnerXml)

Continue For
End If

firmName = address.SelectSingleNode("./FirmName")
If Not firmName Is Nothing Then
Console.WriteLine("FirmName:{0}", firmName.InnerText)
End If

city = address.SelectSingleNode("./City")
If Not city Is Nothing Then
Console.WriteLine("City:{0}", city.InnerText)
End If

state = address.SelectSingleNode("./State")
If Not state Is Nothing Then
Console.WriteLine("State:{0}", state.InnerText)
End If

zip4 = address.SelectSingleNode("./Zip4")
If Not zip4 Is Nothing Then
Console.WriteLine("Zip4:{0}", zip4.InnerText)
End If

zip5 = address.SelectSingleNode("./Zip5")
If Not zip5 Is Nothing Then
Console.WriteLine("Zip5:{0}", zip5.InnerText)
End If

Console.WriteLine()
Next

End Sub
End Module

==============================

Also, I'm not sure whether there will be discretionary number of the child
"Addrews[n]" elements or there won't be much more than "Address3"? If the
number is liimted, you can also use the above approach to query them
through static xpath, otherwise, you may need to dyanmically construct the
child element's xpath and perform the query. How do you think?

Please feel free to let me know if you have anything unclear on this.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
Top