通过 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或者更高版本。
否则,请使用其他人建议的解决方案之一。
我正在尝试 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或者更高版本。
否则,请使用其他人建议的解决方案之一。