通过 XSLT 在两个自闭合标签之间选择文本

Selecting text between two self closing tags via XSLT

我正在尝试 select 与某些自闭合标记元素相邻的文本。这是我到目前为止所得到的。

来源:

<markers>
    <self_closing_marker id="1"/> Some content, possible <othernodes>nodes with text</othernodes>
    <self_closing_marker id="2-3"/> Some more content
</markers>

XSLT:

<xsl:template name="markers" match="self_closing_marker">
    <xsl:value-of select="following-sibling::text()" />
</xsl:template>

问题是下面的兄弟将 select 所有内容,直到当前包装结束。我发现了一些解决方案,将当前兄弟姐妹用作变量并基于此使用先前的兄弟姐妹,但每当我实施它们时,我都会得到空标签。

最终目标是按照

<markers>
    <marker id="1">Some content, possible nodes with text</marker>
    <marker id="2-3">Some more content</marker>
</markers>

一种方法是用 following-sibling:: 轴上的第一个 self_closing_marker 元素分配一个变量 end

然后,对 following:: 轴上的 text() 节点应用谓词过滤器以测试是否存在 $end 以及紧随其后的第一个 self_closing_marker 元素通过比较生成的id值,text()$end相同。

<xsl:template name="markers" match="self_closing_marker">
    <xsl:variable name="end" select="following-sibling::self_closing_marker[1]"/>
    <xsl:value-of select="following::text()[
                            $end 
                            and generate-id(following::self_closing_marker[1]) = generate-id($end)
                          ]" />
</xsl:template>

你可以从相反的方向看:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="txt" match="text()" use="generate-id(preceding::self_closing_marker[1])" />

<xsl:template match="/markers">
    <xsl:copy>
        <xsl:apply-templates select="self_closing_marker"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="self_closing_marker">
    <marker id="{@id}">
        <xsl:copy-of select="key('txt', generate-id())"/>
    </marker>
</xsl:template>

</xsl:stylesheet>

演示:https://xsltfiddle.liberty-development.net/bwe3bR/1


如果不想输出空标记节点,在模板的匹配模式中添加谓词:

<xsl:template match="self_closing_marker[key('txt', generate-id())]">

如果您准备使用 Saxon 扩展函数(需要 PE 或更高版本),您可以使用:

saxon:leading(
   following-sibling::node(), 
   function($x){exists($x/self::marker)})

http://www.saxonica.com/documentation/index.html#!functions/saxon/leading

函数 returns 序列中的所有项目,直到提供的谓词 returns 为真的第一个项目。

你也可以自己实现这个函数,但是因为它使用了高阶函数,所以还是需要Saxon-PE或者更高版本。

否则,请使用其他人建议的解决方案之一。