如何使用XPath以特定顺序选择元素

时间:2013-03-11 15:00:56

标签: java xpath

我有一个XML文件,节点(Z)包含随机顺序的子节点(H,W,P):

<X>
  <Y>
    <Z>
      <H>Hello</H>
      <W>World</W>
      <P>!</P>
    </Z>
    <Z>
      <P>!</P>
      <W>World</W>
      <H>Hello</H>
    </Z>
  </Y>
</X>

我想按给定的顺序选择子节点的内容。

我把它绑起来了:

/X/Y/Z/*[self::H or self::W or self::P]/text()

但这会保持错误的顺序:

Hello World !
! World Hello

我需要一些方法来选择序列中相对于H的W和P.我怎么能这样做?

我试过了:

/X/Y/Z/(H,W,P)/text()

但顺序仍然是错误的。

编辑:问题表明我只需要文本部分,但我需要节点而不仅仅是文本。原因是,XPath text()函数似乎与CDATA部分有问题。

2 个答案:

答案 0 :(得分:3)

对于XPath 2:

使用/来选择节点将始终按文档顺序返回节点,无论您如何编写它。

但是,如果您选择原子值而不是节点,它将保留顺序:

/X/Y/Z/concat(H,W,P)

您还可以使用永不改变顺序的for-in-return:

for $z in /X/Y/Z return ($z/H,$z/W,$z/P)

对于XPath 3:

在真实的现代实现中,您也可以使用!而不是/也将始终保持顺序,否则与/相同(并且它也将保留重复):

 /X/Y/Z ! (H,W,P) ! text()

答案 1 :(得分:0)

XPath将始终采用XML文档树本身的结构,因此XPath [self::H or self::W or self::P]/text()将始终按照它们出现的顺序返回H,W和P节点,这就是为什么你看到“你好,世界 !”和“!世界你好”。

由于你只需要这里的文本,你可以使用如下的连接函数:

concat(/X/Y/Z/H, /X/Y/Z/W, /X/Y/Z/P)