我的属性搜索XPath查询有什么问题

时间:2013-02-07 16:07:54

标签: c# xml xpath xml-namespaces xmldocument

我有一个看起来正确的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查询有什么问题?

2 个答案:

答案 0 :(得分:3)

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

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

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

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

答案 1 :(得分:1)

怀疑这部分是你的问题:

@a:Source='foo.dll'

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

尝试:

@Source='foo.dll'

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

来自"Namespaces in XML 1.0 (3rd edition)" section 6.2(强调我的):

  

默认命名空间声明的范围从它出现的start-tag的开头延伸到相应的end-tag的末尾,不包括任何内部默认命名空间声明的范围。对于空标记,范围是标记本身。

     

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