2015-10-13 57 views
1

我正在使用XPATH 1.0从XML文档中获取某些节点,该文档在根节点和具有属性的节点上使用默认名称空间。模式上设置了attributeFormDefault = "qualified"限定属性的xpath

<Transaction xmlns="http://example.com/transaction"> 
    <someElement/> 
    <collection> 
     <value p0:Name="SomeName" xmlns:p0="http://example.com/transaction">some value</value> 
     <value p1:Name="SomeOtherName" xmlns:p1="http://example.com/transaction">some other value</value> 
    </collection> 
    <differentCollection> 
     <value p2:Name="SomeName" xmlns:p2="http://example.com/transaction">not this one</value> 
    </differentCollection> 
</Transaction> 

我的目的是得到/Transaction/collection/value[@Name='SomeName']节点。

到目前为止我发现的唯一的解决办法似乎有点宽泛:

//*[@*='SomeName'] 

我还可以通过使用得到<value>节点的整个集合:

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

与命名空间限制在记住,是否有更清晰,更精确的方法来获得我之后的节点?第三方JavaScript库不是一个选项。


编辑

感谢您的快速反应。我会在这里指出,通过添加默认的命名空间前缀,解决了XPath查询表达式:

<t:Transaction xmlns:t="http://example.com/transaction"> 

现在我可以这样做:

/t:Transaction/t:collection/t:value[@t:Name='SomeName'] 

回答

2

你真的想选择以下:

/t:Transaction/t:collection/t:value[@t:Name = 'SomeName'] 

...因为您已声明t为前缀评估XPath表达式之前的"http://example.com/transaction"名称空间。

对于示例XML,您显示可以将其压缩到//t:value[@t:Name = 'SomeName']

在任何情况下,您都不会忽略输入文档中的名称空间。 attributeFormDefault是一个红鲱鱼的问题。


如何定义选择名称空间取决于您用于评估XPath表达式的API。

浏览器集成的API支持名称空间解析器函数,该函数将表达式中使用的前缀映射到相应的名称空间URI。进一步阅读:MDN: Introduction to using XPath in JavaScript

简单的域名解析应该是这样的:

function nsResolver(prefix) { 
    var ns = { 
     t: "http://example.com/transaction", 
    }; 
    return ns[prefix] || null; 
} 

注意,在XPath的命名空间前缀没有与XML命名空间前缀同意。然而,他们指出的URI必须同意。

1

,而不是试图裙子命名空间,follow best practices并绑定前缀使用命名空间前缀的命名空间,然后写你的XPath:

  1. 绑定p0http://example.com/transaction使用机制 由您的XPath处理器提供。
  2. 然后利用在XPath表达式中的命名空间前缀:

    /p0:Transaction/p0:collection/p0:value[@p0:Name='SomeName']