无法在xmlns中使用Descendants()或Elements()函数

11

我刚开始学习处理XML,在尝试从一个spring.net配置文件中获取特定标签时遇到了奇怪的问题。通过使用测试XML文件来缩小问题范围,我发现采用以下代码:

List<XElement> nodes = xmlFile.Descendants("B").ToList();

提供一个非空列表,其中包含以下文件:

<?xml version="1.0" encoding="utf-8" ?>
<A fakeAttribute="aaa">
  <B id="DbProvider"/>
</A>

但是对于以下文件,它提供一个空字符串:

<?xml version="1.0" encoding="utf-8" ?>
<A xmlns="aaa">
  <B id="DbProvider"/>
</A>
唯一的区别在于文件的属性。我无法想象这背后的解释。感谢您的帮助。
3个回答

10

你需要在该命名空间中搜索标记:

XNamespace ns = "aaa";

xmlFile.Descendants(ns + "B").ToList()

谢谢!那个方法起作用了 - 但同时也带来了另一个问题。我可以获取名为"B"的后代元素,但无法获取名为"db:provider"的后代元素(无论是使用"db"还是"db:provider"都不行),而这恰恰是我需要做的事情。 - Tomata
数据库被列为不同的命名空间。我的错。 - Tomata
4
如果你想忽略命名空间,可以这样写:var lst = doc.Descendants().Where(p => p.Name.LocalName == "B").ToList(); - xanatos

10

为了完整起见:

var lst = doc.Descendants("{aaa}B").ToList();

(其他人说的是正确的,但我想提供另一种选择 :-) )

为了达到极致完整性,如果你想忽略命名空间进行搜索:

var lst = doc.Descendants().Where(p => p.Name.LocalName == "B").ToList();

7

查询元素时应指定命名空间。

您可以使用GetDefaultNamespace方法来避免硬编码。如果您事先不知道它是什么,这也很有用。

示例:

var ns = xmlFile.GetDefaultNamespace();
var nodes = xmlFile.Descendants(ns + "B").ToList();

1
在某种情况下,.GetDefaultNamespace无法工作,因为XML模式作者并未使用xmlns而是使用xmlns:foo。您可以使用:var ns = xDoc.Root.GetNamespaceOfPrefix("foo"); - Stonetip

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接