0

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.

3
  • Do you have to use XmlDocument rather than LINQ to XML (XDocument etc)? LINQ to XML has much cleaner namespace support IMO. Commented Apr 23, 2018 at 9:54
  • I don't know what that is. I digged through some old books for this. Commented Apr 23, 2018 at 9:58
  • LINQ to XML is a more modern XML API. I'd strongly recommend using it if you possibly can. Commented Apr 23, 2018 at 10:00

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your post. The solution with SelectNodes works. But I can't get Linq to work. Tells me XDocument is not defined. Tried to Import some classes but System.Xml.Linq does not exist.
@mirokai: Importing System.Xml.Linq should work fine so long as you're using .NET 3.5 or above. (You may need to add an assembly reference, but that will entirely depend on what kind of project you're writing, and also what version of the framework you're targeting, as I believe it's changed location over time.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.