2

如何从我知道其 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]"/> 

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

4

2 回答 2

1

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

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

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

有关这些运算符的详细说明,请参见此处。

于 2010-05-06T18:27:32.967 回答
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
于 2010-05-06T18:53:01.307 回答