Linq to XML 使用后代获取值

Linq to XML using descendant to get values

样本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>

我设法使用

查询文件
Dim X As XElement = Xelement.Load("C:\XMLFile1.xml")
Dim Customers As IEnumerable(Of XElement) = Xelement.Elements()

' Read the entire XML
For Each c In Customers
    Console.WriteLine(c)
Next

目标是获取所有数值(在位置下),但我想更进一步,看看我是否可以在一行中获取这个元素,而不是每个循环都有一个(不确定这是否是也可能吗?)。所以我将代码更改为

Dim xd As XDocument = XDocument.Load("C:\XMLFile1.xml")
Dim xe As XElement = Xd.Root
Dim nums As IEnumerable(Of XElement) = xe.Descendants.Where(Function(x) x.Element("number").Value)
'Dim nums As IEnumerable(Of XElement) = xe.Descendants.Where(Function(x) x.Element("location").Element("number").Value)

返回为 null/nothing。我尝试了不同的变体,将元素与后代混合并添加多个选择,但我认为我需要一个工作示例来真正理解正在发生的事情以及我在哪里犯了错误。在网上看到例子并没有真正帮助,因为我想我最终把自己弄糊涂了。

我读了几篇文章,但有些文章指出要添加命名空间,但我真的不想走那条路,直到我了解发生了什么以及我是否真的需要它吗?

需要注意的重要一点是,您的 XML 在根元素处声明了 default namespace,其 URI 为 "http://example.com/ns/"。根据默认命名空间的定义,根元素连同所有在你的 XML 中没有前缀的后代元素都属于这个命名空间,因此我们需要使用 XNamespace 结合元素的本地名称来正确引用命名空间中的元素:

Dim ns As XNamespace = "http://example.com/ns/"
Dim numbers As IEnumerable(Of XElement) = xe.Descendants(ns+"number")
For Each number As XElement In numbers
    Console.WriteLine(number.Value)
Next

dotnetfiddle demo