如何从我知道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选择前面的文本节点?
答案 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 . << $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