XPath Query On XML File Created From DataSet Returns Zero Records

Scenario

I had an XML file called LocationExtract.xml which I had created using DataSet.WriteXMLSchema. I wanted to modify the content of some of the nodes, so I used the SelectNodes method on the DocumentElement node of the XML file to select those nodes, but SelectNodes always returned zero records.

Solution

I had to to use the .NET XMLNamespaceManager object to add the namespace of the XML document to the collection of namespaces in the scope of my local XPath query. An XPath query needs to know the namespaces which it is operating on because it is by namespaces that XPath identifies XML documents. This MSDN document XML Namespaces and How They Affect XPath and XSLT explains this in detail.

Finding The XMLNamespace Of Your DataSet

If you inspect an XML file created from a strongly-typed DataSet you will find a line in it similar to the following: xmlns:http://tempuri.org/LocationExtractDataSet.xsd. That means that the XMLNamespace of the DataSet (.xsd file) named LocationExtractDataSet is http://tempuri.org/LocationExtractDataSet.xsd

Here’s The Code which allows an XPath Query to run against the XML file created from that DataSet (crucial bits in bold)

Dim reader As XmlTextReader = New XmlTextReader(Server.MapPath("LocationExtract.xsd"))
Dim doc As XmlDocument = New XmlDocument()
doc.Load(reader)
Dim topNode As XmlElement = doc.DocumentElement

'Set XPath Namespace
Dim topNode As XmlElement = doc.DocumentElement
Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(doc.NameTable)
nsmgr.AddNamespace("loc", topNode.NamespaceURI)

Dim loc As XmlNodeList = topNode.SelectNodes("//ext:Location", nsmgr)

For Each locNode As XmlNode In loc
locNode.InnerText.Replace("Sugar", "Cinnamon")
Next

You will notice that I create an XMLNamespaceManager and add the namespace of my XML File to it with an associated prefix. The prefix is “ext” and the namespace is http://tempuri.org/LocationExtractDataSet.xsd. The weird thing is that the namespace is NOT available in doc.NamespaceURI. You have to get it from a Node in the document such as the DocumentElement

Having done this my XPath Query topNode.SelectNodes(“//ext:Location”, nsmgr) returns all the Location Nodes in the document LocationExtract.xml because it is in the namespace associated with the prefix “ext” . I then replace “Sugar” with “Cinnamon” in the manner approved by Jerry Seinfeld.

In short, if your XPath Query is returning zero records, you probably need to load the namespace of your XML file into an XMLNamespaceManager. Twenty Billion XPath Queries can’t be wrong.

Advertisements

Tags: ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: