2010-05-14 72 views
1

我提供给我下面的XML和我不能改变它:查询的值,其中默认命名空间节点存在

<Parent> 
    <Settings Version="1234" xmlns="urn:schemas-stuff-com"/> 
</Parent> 

我试图取回使用XPath“版本”的属性值。由于xmlns没有别名定义,它会自动将xmlns分配给Settings节点。当我将这个XML读入XMLDocument并查看Settings节点的namespaceURI值时,它被设置为“urn:schemas-stuff-com”。

我曾尝试:

//父/设置/ @版本- 返回Null

//父/瓮:架构 - 东西-COM:设置/ @版本- 无效语法

+0

好的问题(+1)。查看我的答案,了解不依赖于特定实现或特定编程语言的解决方案。 :) – 2010-05-15 16:09:06

回答

0

解决方案取决于您正在使用的XPath版本。在XPath 2.0以下应该工作:

declare namespace foo = "urn:schemas-stuff-com"; 
xs:string($your_xml//Parent/foo:Settings/@Version) 

在XPath 1.0,而另一方面,唯一的解决办法我已经成功地得到工作是:

//Parent/*[name() = Settings and namespace-uri() = "urn:schemas-stuff-com"]/@Version 

在我看来,该当XPath处理器在节点间更改时不会更改默认名称空间,但我不确定这是否真的如此。

希望这会有所帮助。

+0

'namespace()'应该是'namespace-uri()'。 – 2010-05-14 22:53:21

+0

@Mads Hansen - 当然你是对的。固定。 – finrod 2010-05-15 08:22:14

+0

由于其他一些原因,我不得不动态创建“foo”命名空间名称,而我不想这么做,所以我最终使用了XPath 1.0语法。你的例子中有一个错字,但是“Settings”应该用单引号括起来。 感谢您的帮助。 – Jay 2010-05-17 11:41:23

0

使用的XmlNamespaceManager的:

XmlDocument doc = new XmlDocument(); 
doc.Load("file.xml"); 

XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable); 
mgr.AddNamespace("foo", "urn:schemas-stuff-com"); 

XmlElement settings = doc.SelectSingleNode("Parent/foo:Settings", mgr) as XmlElement; 
if (settings != null) 
{ 
    // access settings.GetAttribute("version") here 
} 

// or alternatively select the attribute itself with XPath e.g. 
XmlAttribute version = doc.SelectSingleNode("Parent/foo:Settings/@Version", mgr) as XmlAttribute; 
if (version != null) 
{ 
    // access version.Value here 
} 
0

除了马丁Honnen的正确答案,不幸的是执行和编程语言特定,这里是一个纯粹的XPath的解决方案

/*/*[name()='Settings ']/@Version 
+0

这与我的下面非常相似,只有它(可能)也可以捕捉其他节点 – finrod 2010-05-15 20:52:01

相关问题