xquery ---使用与当前节点不同的值到达下一个节点

时间:2012-11-24 03:57:13

标签: xml xpath xquery

这是我正在使用的xml,我正在尝试我遇到的第一个不同pd值的id号。

<result>
  <pd>a</pd>
  <id>1</id>
  <pd>a</pd>
  <id>2</id>

  <pd>b</pd>
  <id>8</id>

  <pd>c</pd>
  <id>9</id>
  <pd>c</pd>
  <id>4</id>

  <pd>d</pd>
  <id>7</id>
</result>

所以我期待的结果是:

 <pd>a</pd>
 <id>1</id>

 <pd>b</pd>
 <id>8</id>

 <pd>c</pd>
 <id>9</id>

 <pd>d</pd>
 <id>7</id>

我使用了follow-sibling :: * [2]来获取下一个pd并将其与当前节点进行比较但是它只给了我b,而不是c和d。你们中的任何人都可以给我一个关于如何遍历整个xml以获得所需输出的提示吗?谢谢!

2 个答案:

答案 0 :(得分:1)

可能有更优雅的解决方案,但我采取的策略是收集pd元素中的所有不同值,然后循环遍历所有的pd元素并抓住第一个兄弟pd元素中的值与不同值的当前迭代中的值匹配。

for $distinct-pd in fn:distinct-values($xml//pd)
  for $pd in $xml//pd[./text() eq $distinct-pd][1]
    return ($pd, $pd/following-sibling::*[1])

对于您的代码,这会产生

<pd>a</pd>
<id>1</id>
<pd>b</pd>
<id>8</id>
<pd>c</pd>
<id>9</id>
<pd>d</pd>
<id>7</id>

答案 1 :(得分:1)

实现相同目标的另一种方法 - 对于不长的序列来说足够好:

/*/pd[not(. = preceding-sibling::pd)]
               /(.|following-sibling::id[1])

根据提供的XML文档评估此XPath 2.0表达式(和XQuery)时:

<result>
  <pd>a</pd>
  <id>1</id>
  <pd>a</pd>
  <id>2</id>

  <pd>b</pd>
  <id>8</id>

  <pd>c</pd>
  <id>9</id>
  <pd>c</pd>
  <id>4</id>

  <pd>d</pd>
  <id>7</id>
</result>

产生了想要的正确结果

<pd>a</pd>
<id>1</id>
<pd>b</pd>
<id>8</id>
<pd>c</pd>
<id>9</id>
<pd>d</pd>
<id>7</id>