我有一个看起来正确的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查询有什么问题?
答案 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的末尾,不包括任何内部默认命名空间声明的范围。对于空标记,范围是标记本身。
默认名称空间声明适用于其范围内的所有未加前缀的元素名称。 默认命名空间声明不直接应用于属性名称;对无前缀属性的解释由它们出现的元素决定。