VB.NET中解析带命名空间前缀的XML
解决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:keyitem> <!-- 这里应该还有更多keyitem节点 --> </tns:keyitem_list_test>
我懂你现在的状态——刚接触VB.NET,又好久没碰XML解析,面对带命名空间的XML确实容易犯懵。别担心,这个问题的核心就是处理好XML里的tns命名空间,下面给你两种常用的解析方案,选你顺手的来就行:
方案一:LINQ to XML(推荐,代码更简洁)
LINQ to XML是VB.NET中处理XML的现代方式,语法直观,维护起来也方便。
' 1. 加载XML(两种方式选其一) ' 从字符串加载 Dim xmlContent As String = "你的XML字符串内容" Dim xmlDoc As XDocument = XDocument.Parse(xmlContent) ' 或者从文件加载(注意编码匹配XML的ISO-8859-15) ' Dim xmlDoc As XDocument = XDocument.Load(New StreamReader("your_file.xml", Encoding.GetEncoding("ISO-8859-15"))) ' 2. 定义命名空间(必须和XML里的URL完全一致) Dim tns As XNamespace = "http://someurl.com/abc/def" ' 3. 获取单个节点内容,比如<tns:name> Dim listName As String = xmlDoc.Descendants(tns + "name").FirstOrDefault()?.Value If Not String.IsNullOrEmpty(listName) Then Console.WriteLine($"列表名称:{listName}") End If ' 4. 遍历所有<tns:keyitem>节点 For Each keyItem In xmlDoc.Descendants(tns + "keyitem") ' 读取子节点内容,注意空节点判断避免报错 Dim cataloge As String = keyItem.Element(tns + "cataloge")?.Value ?? "" Dim seqNr As Integer = 0 Integer.TryParse(keyItem.Element(tns + "seq_nr")?.Value, seqNr) Dim keyValue As String = keyItem.Element(tns + "keyvalue")?.Value ?? "" Console.WriteLine($"分类:{cataloge},序号:{seqNr},键值:{keyValue}") Next
方案二:传统XmlDocument(适合习惯旧API的场景)
如果你更熟悉传统的XmlDocument操作,也可以用这种方式:
' 1. 加载XML Dim xmlDoc As New XmlDocument() ' 从字符串加载 xmlDoc.LoadXml("你的XML字符串内容") ' 或者从文件加载 ' xmlDoc.Load(New XmlTextReader("your_file.xml") With {.Encoding = Encoding.GetEncoding("ISO-8859-15")}) ' 2. 创建命名空间管理器 Dim nsManager As New XmlNamespaceManager(xmlDoc.NameTable) nsManager.AddNamespace("tns", "http://someurl.com/abc/def") ' 3. 获取单个节点 Dim nameNode As XmlNode = xmlDoc.SelectSingleNode("//tns:name", nsManager) If nameNode IsNot Nothing Then Console.WriteLine($"列表名称:{nameNode.InnerText}") End If ' 4. 遍历所有keyitem节点 Dim keyItemNodes As XmlNodeList = xmlDoc.SelectNodes("//tns:keyitem", nsManager) For Each node As XmlNode In keyItemNodes Dim cataloge As String = node.SelectSingleNode("tns:cataloge", nsManager)?.InnerText ?? "" Dim seqNr As Integer = 0 Integer.TryParse(node.SelectSingleNode("tns:seq_nr", nsManager)?.InnerText, seqNr) Dim keyValue As String = node.SelectSingleNode("tns:keyvalue", nsManager)?.InnerText ?? "" Console.WriteLine($"分类:{cataloge},序号:{seqNr},键值:{keyValue}") Next
几个关键注意点
- 命名空间必须完全匹配:XML里的命名空间URL(
http://someurl.com/abc/def)要和你代码里写的一模一样,大小写、斜杠都不能错,否则会找不到节点。 - 处理空节点:实际场景中可能存在缺失的子节点,所以一定要用
?.或者IsNot Nothing做判断,避免空引用异常。 - 编码问题:你的XML是
ISO-8859-15编码,如果加载时遇到乱码,记得指定对应的编码(比如上面代码里的StreamReader方式)。
内容的提问来源于stack exchange,提问作者mirokai
相关产品推荐
相关产品推荐

