Query for value where a default namespace node exists
I have the following XML that is provided to me and I cannot change it:
<Parent>
<Settings Version="1234" xmlns="urn:schemas-stuff-com"/>
</Parent>
I am trying to retrieve the "Version" attribute value using XPath. It appears since the xmlns is defined without an alias it automatically assigns that xmlns to the Settings node. When I read this XML into an XMLDocument and view the namespaceURI value for the Settings node it is set to "urn:schemas-stuff-com".
I have tried:
//Parent/Settings/@Version - returns Null
//Parent/urn:schemas-stuff-com:Settings/@开发者_运维百科Version - invalid syntax
The solution depends on which version of XPath you are using. In XPath 2.0 the following should work:
declare namespace foo = "urn:schemas-stuff-com";
xs:string($your_xml//Parent/foo:Settings/@Version)
In XPath 1.0, on the other hand, the only solution I've managed to get to work was:
//Parent/*[name() = Settings and namespace-uri() = "urn:schemas-stuff-com"]/@Version
It seems to me that the XPath processor doesn't change the default namespace when it changes between nodes, though I am not sure whether this is really the case.
Hope this helps.
Use an 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
}
In addition to Martin Honnen's correct answer, which unfortunately is implementation and programming-language specific, here is a pure XPath solution:
/*/*[name()='Settings ']/@Version
精彩评论