2

我有一个带有节点(Z)的 XML 文件,其中包含随机顺序的子节点(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 部分的问题。

4

2 回答 2

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()
于 2013-03-11T15:16:28.820 回答
0

XPath 将始终遵循 XML 文档树本身的结构,因此 XPath[self::H or self::W or self::P]/text()将始终按照出现的顺序返回 H、W 和 P 节点,这就是您看到“Hello World!”的原因。和“!世界你好”。

由于您只需要此处的文本,因此可以像这样使用连接函数:

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

于 2013-03-11T15:18:16.520 回答