XPATHS和默认命名空间

XPath背后的故事和对命名空间的支持是什么? 作为规范的XPath是否在名称空间之前? 如果我有一个文档的元素已被赋予一个默认的名称空间:

<foo xmlns="uri" /> 

看起来好像某些XPath处理器库不会识别//foo因为命名空间,而其他的会。 我的团队考虑的选项是使用正则expression式向XPath添加一个名称空间前缀(可以通过XmlNameTable添加一个名称空间前缀),但是这看起来很脆弱,因为XPath在节点testing中是一种非常灵活的语言。

有没有适用于此的标准?

我的做法有点ha but,但似乎工作正常; 我使用search/replace来删除xmlns声明,然后应用XPath。

 string readyForXpath = Regex.Replace(xmldocument, "xmlns=\".+\"", String.Empty ); 

这是一个公平的方法,或有任何人解决这个不同?

我尝试了一些类似于古马提议的方法,但却无法实现。 由于我从发布的服务获取数据,我无法更改xml。 我结束了使用XmlDocument和XmlNamespaceManager像这样:

 XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlWithBogusNamespace); XmlNamespaceManager nSpace = new XmlNamespaceManager(doc.NameTable); nSpace.AddNamespace("myNs", "http://theirUri"); XmlNodeList nodes = doc.SelectNodes("//myNs:NodesIWant",nSpace); //etc 

你需要local-name():

http://www.w3.org/TR/xpath#function-local-name

要从http://jcooney.net/archive/2005/08/09/6517.aspx婴儿床:;

 <foo xmlns='urn:foo'> <bar> <asdf/> </bar> </foo> 

这个expression式将匹配“bar”元素:

  //*[local-name()='bar'] 

这个不会:

  //bar 

问题是没有命名空间的元素被声明在NULL空间中 – 因此,如果// foo与名为空的命名空间相匹配,那么将无法引用空名称空间中的元素。

还要记住,名称空间的前缀只是一个简写约定,真正的元素名称(Qualified Name,简称QName)由完整名称空间和本地名称组成。 更改名称空间的前缀不会更改元素的“标识” – 如果它位于相同的名称空间和相同的本地名称中,则它是相同types的元素,即使前缀不同。

XPath 2.0(或者说XSLT 2.0)具有“默认xpath命名空间”的概念。 您可以在xsl:stylesheet元素上设置xpath-default-namespace属性。

如果您尝试使用xslt,则可以将名称空间添加到样式表声明中。 如果你这样做,你必须确保有一个前缀,否则将无法正常工作。 如果源XML没有前缀,那么仍然可以在样式表中添加自己的前缀。

样式表

 <xsl:stylesheet xmlns:fb="uri" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="fb:foo/bar"> <!-- do stuff here --> </xsl:template> </xsl:stylsheet> 

或类似的东西。