mirokai
mirokai

Reputation: 125

Parse XML with namespace prefix in vb .net

I am pretty new to vb .net and it has been a very long time since I dealt with XML parsing.

I got the following XML file:

<?xml version="1.0" encoding="ISO-8859-15"?>
<tns:keyitem_list_test xmlns:tns="http://someurl.com/abc/def">
  <tns:name>test.keyitem</tns:name>
  <tns:type>test.IKeyItemListDataObject</tns:type>
  <tns:keyitem>
    <tns:cataloge>testCat</tns:cataloge>
    <tns:seq_nr>1</tns:seq_nr>
    <tns:keyvalue>01</tns:keyvalue>
    <tns:keyvalue_alt>test1</tns:keyvalue_alt>
    <tns:keytext>test text 1</tns:keytext>
    <tns:keyhelpertext />
    <tns:is_temp>false</tns:is_temp>
  </tns:keyitem>
  <tns:keyitem>
    <tns:cataloge>testCat</tns:cataloge>
    <tns:seq_nr>2</tns:seq_nr>
    <tns:keyvalue>02</tns:keyvalue>
    <tns:keyvalue_alt>test2</tns:keyvalue_alt>
    <tns:keytext>test text 2</tns:keytext>
    <tns:keyhelpertext />
    <tns:is_temp>false</tns:is_temp>
  </tns:keyitem>
...
</tns:keyitem_list_test>

The XML is returned from a POST request and saved in a variable. I want to extract all tns:keyvalue tags.

Dim doc = New Xml.XmlDocument()
doc.LoadXml(retVal.return)

Dim nsm = New Xml.XmlNamespaceManager(doc.NameTable)
nsm.AddNamespace("tns", "http://someurl.com/abc/def")
Dim value = doc.SelectSingleNode("/tns:keyvalue", nsm).InnerText

My problem is that value is always "Nothing". I tried different things but none work and I have no clue why. I think it has something to do with the namespace prefixes.

Upvotes: 0

Views: 1679

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1501103

The immediate problem is in your XPath expression:

Dim value = doc.SelectSingleNode("/tns:keyvalue", nsm).InnerText

That's only looking for a root element called keyvalue. If you change it to look for descendants, you'll find the first keyvalue node:

Dim value = doc.SelectSingleNode("//tns:keyvalue", nsm).InnerText

Or to look for all nodes rather than just the first:

Dim nodes = doc.SelectNodes("//tns:keyvalue", nsm)
For Each node as Xml.XmlNode in nodes
    Console.WriteLine(node.InnerText)
Next

However, if you can, I'd recommend using LINQ to XML, which has much cleaner namespace support, and better support for querying without using XPath:

Dim doc = XDocument.Parse(retVal.return)
Dim ns As XNamespace = "http://someurl.com/abc/def"
Dim elements = doc.Descendants(ns + "keyvalue")
For Each element in elements
    Console.WriteLine(element.Value)
Next

Upvotes: 1

Related Questions