Я новичок в vb .net, и прошло очень много времени с тех пор, как я занимался синтаксическим анализом XML.
У меня получился следующий XML-файл:
<?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>
XML возвращается из запроса POST и сохраняется в переменной. Я хочу извлечь все теги tns: keyvalue.
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
Моя проблема в том, что значение всегда равно «Ничего». Я пробовал разные вещи, но ничего не получалось, и я понятия не имею, почему. Я думаю, это как-то связано с префиксами пространств имен.
Я не знаю, что это такое. Я покопался для этого в некоторых старых книгах.
LINQ to XML - это более современный XML API. Я настоятельно рекомендую использовать его, если возможно.





Проблема немедленный находится в вашем выражении XPath:
Dim value = doc.SelectSingleNode("/tns:keyvalue", nsm).InnerText
Это только поиск элемента корень с именем keyvalue. Если вы измените его для поиска потомков, вы найдете первый узел keyvalue:
Dim value = doc.SelectSingleNode("//tns:keyvalue", nsm).InnerText
Или искать все узлы, а не только первый:
Dim nodes = doc.SelectNodes("//tns:keyvalue", nsm)
For Each node as Xml.XmlNode in nodes
Console.WriteLine(node.InnerText)
Next
Однако, если вы можете, я бы рекомендовал использовать LINQ to XML, который имеет гораздо более чистую поддержку пространства имен и лучшую поддержку запросов без использования 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
Спасибо за ваше сообщение. Решение с SelectNodes работает. Но я не могу заставить работать Linq. Сообщает мне, что XDocument не определен. Пытался импортировать некоторые классы, но System.Xml.Linq не существует.
@mirokai: Импорт System.Xml.Linq должен работать нормально, если вы используете .NET 3.5 или выше. (Возможно, вам потребуется добавить ссылку на сборку, но это будет полностью зависеть от того, какой проект вы пишете, а также от того, на какую версию фреймворка вы нацеливаетесь, поскольку я считаю, что со временем местоположение менялось.)
Используете ли вы имеют для использования XmlDocument, а не LINQ to XML (XDocument и т. д.)? LINQ to XML имеет гораздо более чистую поддержку пространства имен IMO.