如何从特定节点而不是根节点开始选择文本节点的前面节点?

时间:2010-05-06 18:21:54

标签: xslt xpath xslt-2.0 xpath-2.0

如何从我知道id的特定节点开始选择文本节点的前面节点,而不是从根节点获取文本节点?

当我从文本节点的模板匹配中调用下面的部分时, 我从根获取所有前面的文本节点。我想修改上面的代码片段,只选择在具有特定id的节点后出现的文本节点123.即类似// * [@ id ='123']

          <xsl:template match="text()[. is $text-to-split]"> 
          <xsl:variable name="split-index" as="xsd:integer" 
           select="$index - sum(preceding::text()/string-length(.))"/> 
          <xsl:value-of select="substring(., 1, $split-index - 1)"/> 
          <xsl:copy-of select="$new"/> 
          <xsl:value-of select="substring(., $split-index)"/> 
          </xsl:template> 

         <xsl:variable name="text-to-split" as="text()?" 
         select="descendant::text()[sum((preceding::text(), .)/string-length(.)) ge $index][1]"/> 

如何在我使用前面:: text的地方包含条件,以便相对于我知道的特定节点的id选择前面的文本节点?

2 个答案:

答案 0 :(得分:1)

在XPath 2.0中,您可以使用运算符<<>>来比较节点排序。例如:

preceding-sibling::text()[. >> $foo]

将选择当前文本节点之前的所有兄弟文本节点,这些节点按文档顺序跟随节点$foo。当然,您可以使用表达式而不是$foo - 在您的情况下,//*[@id='123'] - 尽管将其绑定到变量然后在过滤器中使用它可能更容易让XSLT处理器进行优化。 / p>

有关这些运营商的详细规范,请参阅this

答案 1 :(得分:1)

以下是您可以使用的一些变体

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:strip-space elements="*"/>
 <xsl:output method="text"/>

 <xsl:variable name="vStart" select="/*/*[@myId='123']/text()"/>
 <xsl:variable name="vEnd" select="/*/*[last()]"/>

    <xsl:template match="/">
      <xsl:value-of select=
       "*/*[last()]
             /sum(preceding::text()
                 intersect
                  $vStart/following::text()
                  )
     "/>
---------------
      <xsl:value-of select=
       "*/*[last()]
             /sum(preceding::text()[. >> $vStart])
     "/>
--------------- 
      <xsl:value-of select=
       "sum(/*/*[. >> $vStart and . &lt;&lt; $vEnd])
     "/>
    </xsl:template>
</xsl:stylesheet>

将此转换应用于以下XML文档

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num myId='123'>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>010</num>
</nums>

产生了预期的结果

30
---------------
      30
--------------- 
      30