1

我有一个 XPath 查询,它看起来对我来说是正确的,但没有返回任何结果。

它正在测试的 XML 文档:

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Deployment.Parts>
    <AssemblyPart x:Name="foo" Source="foo.dll" />
  </Deployment.Parts>
</Deployment>

编码:

Xml = new XmlDocument();
Xml.LoadXml(text);
Manager = new XmlNamespaceManager(Xml.NameTable);
//use constants for namespaces to make more readable
Manager.AddNamespace("a", NS_DEPLOYMENT_2007); //use 'a' for default namespace here so xpath is easier
Manager.AddNamespace("x", NS_XAML_2006); 

string xpath="//a:Deployment.Parts/a:AssemblyPart[@a:Source='foo.dll']";
var tmp = Xml.SelectNodes(xpath, Manager);

我的 XPath 查询有什么问题?

4

2 回答 2

3

您需要从属性中删除命名空间前缀:

string xpath="//a:Deployment.Parts/a:AssemblyPart[@Source='foo.dll']";

如果属性明确定义了命名空间,则只需为其指定命名空间,因此当您想要查询该Name属性时,您必须添加它:

string xpath="//a:Deployment.Parts/a:AssemblyPart[@x:Name='foo']";
于 2013-02-07T16:11:31.283 回答
1

怀疑这部分是你的问题:

@a:Source='foo.dll'

与元素名称不同,属性名称不继承命名空间。您的文档没有为该属性指定名称空间,因此我认为您也不应该这样做。

试试:

@Source='foo.dll'

(顺便说一句,我个人会使用 LINQ to XML 而不是 XPath - 我发现它通常更简单。YMMV,但它可能值得考虑 - 如果您使用的是 .NET 3.5 或更高版本,当然。)

来自“XML 1.0(第 3 版)中的命名空间”第 6.2 节(强调我的):

默认命名空间声明的范围从它出现的开始标签的开头延伸到相应的结束标签的末尾,不包括任何内部默认命名空间声明的范围。在空标签的情况下,范围是标签本身。

默认命名空间声明适用于其范围内的所有无前缀元素名称。默认命名空间声明不直接应用于属性名称;无前缀属性的解释由它们出现的元素决定。

于 2013-02-07T16:11:22.537 回答