使用Linq to XML的Descendant获取number节点值遇空值问题求助
如何用一行代码获取XML中所有location节点下的number值
首先看你提供的Sample XML:
<?xml version="1.0" encoding="utf-8"?> <customers xmlns="http://example.com/ns/" si="0" records="2"> <customer id="123456789"> <dob>2017-12-10T16:22:27.033Z</dob> <location> <number>444555666777</number> </location> <link rel="self" href="http://example.com" /> </customer> <customer id="987654321"> <dob>2017-12-11T17:00:00.033Z</dob> <location> <number>555666999888</number> </location> <link rel="self" href="http://example.com" /> </customer> <link rel="self" href="http://example.com" /> </customers>
你最初尝试了循环读取,之后想改成一行代码获取所有location下的number值,但多次尝试都返回null/nothing。核心问题其实是你的XML带有默认命名空间,而查询时没有指定,这是LINQ to XML查询中非常常见的坑。
可行的一行代码实现
直接上可以运行的代码,这里把命名空间的处理和查询整合到一行:
Dim numbers = XDocument.Load("C:\XMLFile1.xml").Descendants(XNamespace.Get("http://example.com/ns/") + "location").Elements(XNamespace.Get("http://example.com/ns/") + "number").Select(Function(n) n.Value)
如果想拆分得更清晰(可读性更好),可以写成:
Dim xd As XDocument = XDocument.Load("C:\XMLFile1.xml") Dim ns As XNamespace = "http://example.com/ns/" ' 定义XML的默认命名空间 Dim numbers As IEnumerable(Of String) = xd.Descendants(ns + "location").Elements(ns + "number").Select(Function(n) n.Value)
为什么之前的代码失效?
- 命名空间缺失:XML根节点的
xmlns="http://example.com/ns/"意味着所有子节点(customer、location、number等)都属于这个命名空间。LINQ to XML中,不带命名空间的节点名称无法匹配带命名空间的节点,所以你之前的查询根本找不到对应的元素。 - 逻辑错误:你之前的
xe.Descendants.Where(Function(x) x.Element("number").Value)写法有问题:Descendants会返回所有后代节点,其中大部分节点没有number子节点,会导致空引用异常;同时也没有过滤出location节点,逻辑方向不对。
验证结果
如果要输出结果,也可以用一行代码完成(不用foreach):
Console.WriteLine(String.Join(vbNewLine, numbers))
执行后会输出:
444555666777 555666999888
内容的提问来源于stack exchange,提问作者Computer
相关产品推荐
相关产品推荐

