2

我的 XML 的结构

<root>
    <Q id="a">1</Q>
    <Q id="b">2</Q>
    <Q id="c">3</Q>
      <x> 
          <Q id="d">3.1</Q> 
          <Q id="e">3.2</Q>
          <Q id="f">3.3</Q>
      </x>
    <Q id="g">4</Q>
    <Q id="h">5</Q>
</root>

这是我的 XPath 表达式:

//Q[@id=$CurrentQid]/preceding::Q

当我在"a", "b", "c",节点上时,无论当前位置如何(我将当前位置作为参数传递给我的 xslt),我都试图获取前面 Q 节点的列表"g""h"它会返回正确的前面节点列表。但是当我打开"d""e""f"它不能正常工作。

例如:当我的当前节点"g"返回时,

a,b,c,d,e,f

但是当我的当前节点是"f"它时它只返回

d,e,f

虽然我希望它是

a,b,c,d,e

如果有人能找到一个非常好的解决方案。

谢谢你。

4

1 回答 1

2

使用

($yourNode/preceding::Q | $yourNode/ancestor::Q)/@id 

基于 XSLT 的验证

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vQg" select="(//Q[@id='g'])[1]"/>
 <xsl:variable name="vQf" select="(//Q[@id='f'])[1]"/>

 <xsl:template match="/">
  "Preceding" $vQg:

  <xsl:for-each select=
  "($vQg/preceding::Q | $vQg/ancestor::Q)/@id">
   <xsl:value-of select="concat(., ' ')"/>
  </xsl:for-each>
=====================

  "Preceding" $vQf:

  <xsl:for-each select=
  "($vQf/preceding::Q | $vQf/ancestor::Q)/@id">
   <xsl:value-of select="concat(., ' ')"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<root>
    <Q id="a">1</Q>
    <Q id="b">2</Q>
    <Q id="c">3</Q>
      <x>
          <Q id="d">3.1</Q>
          <Q id="e">3.2</Q>
          <Q id="f">3.3</Q>
      </x>
    <Q id="g">4</Q>
    <Q id="h">5</Q>
</root>

XPath 表达式被评估两次(对于Q您问题中的两个元素),结果的字符串值以空格分隔输出

  "Preceding" $vQg:

  a b c d e f 
=====================

  "Preceding" $vQf:

  a b c d e 

说明

preceding::轴不会按文档顺序选择所有前面的节点——要做到这一点还需要使用轴ancestor::

来自W3C XPath 1.0 规范

"•前轴包含与上下文节点在同一文档中按文档顺序位于上下文节点之前的所有节点,不包括任何祖先,不包括属性节点和命名空间节点"

于 2013-05-10T02:55:53.160 回答