XPath表达式

时间:2011-09-13 05:52:29

标签: xml xpath

我有一个像这样的XML文件:

<lib:library>    
    <lib:book> XML </lib:book>
    <lib:book> XPath </lib:book>
    <lib:book> XSLT </lib:book>
    <lib:book> Java </lib:book>
    <lib:book> C++ </lib:book>    
</lib:library>

我想去读书[2] ...我当然可以做像//lib:Book [2] ......这样的工作。可能会发生在我所拥有的相同XML文件中,例如,相同的标记名称但名称空间不同;在这种情况下,我的XPath表达式不起作用...

我可以替换它:

// * [local-name()=“book”]

这个表达式返回XML文件中包含的所有书...但是如果我想得到数字[2]怎么...我应该如何重写XPath表达式添加数字条件?当然我不想考虑命名空间,它必须对每个使用过的命名空间都有效。

由于 卢卡

2 个答案:

答案 0 :(得分:4)

当前选择的答案错误

实际上//someExpression[2]可以选择多个节点。

例如,如果我们有以下XML文档

<lib:library xmlns:lib="UNDEFINED!!!">
  <topic name="XML">
      <lib:book> XML </lib:book>
  </topic>
  <topic name="XPath">
      <lib:book> XPath </lib:book>
  </topic>
  <topic name="XSLT">
     <lib:book> XSLT1 </lib:book>
     <lib:book> XSLT2 </lib:book>
  </topic>
  <topic name="Imperative PLs">
     <lib:book> Java </lib:book>
     <lib:book> C++ </lib:book>
  </topic>
</lib:library>

表达式

   //*[local-name() = "book"][2]
根据上面的文档评估

选择了两个节点(并且它们都不是文档中具有所需属性的第二个节点):

<lib:book xmlns:lib="UNDEFINED!!!"> XSLT2 </lib:book>
<lib:book xmlns:lib="UNDEFINED!!!"> C++ </lib:book>

解决方案:在整个文档中选择N(比如说​​第二个)节点(比如lib:book)的一种方法是:

   (//*[local-name() = "book"])[2]

在上面的文档中评估此表达式时,会选择正确的单个节点:

<lib:book xmlns:lib="UNDEFINED!!!"> XPath </lib:book>

解释:根据 W3C XPath recommendations 中的定义:

  

///descendant-or-self::node()/

的缩写

因此:

//someName[2]

是:

的简写
/descendant-or-self::node()/someName[2]

,这将选择名为someName的文档中的任何元素,这是其父级的第二个someName子级。

换句话说,[]运算符比//伪运算符绑定更强(具有更高的优先级)。这就是我们需要括号来覆盖默认运算符优先级的原因。

答案 1 :(得分:0)

//*[local-name() = "book"][2]怎么样?它应该工作。

如评论中所述,除非您确定自己在做什么,否则应避免使用//