Xml 通过XSLT在两个自动关闭标记之间选择文本
我试图选择与某些自动关闭标记元素相邻的文本。这是我到目前为止得到的 来源:Xml 通过XSLT在两个自动关闭标记之间选择文本,xml,xslt,saxon,Xml,Xslt,Saxon,我试图选择与某些自动关闭标记元素相邻的文本。这是我到目前为止得到的 来源: <markers> <self_closing_marker id="1"/> Some content, possible <othernodes>nodes with text</othernodes> <self_closing_marker id="2-3"/> Some more content </markers> &l
<markers>
<self_closing_marker id="1"/> Some content, possible <othernodes>nodes with text</othernodes>
<self_closing_marker id="2-3"/> Some more content
</markers>
<xsl:template name="markers" match="self_closing_marker">
<xsl:value-of select="following-sibling::text()" />
</xsl:template>
一些内容,可能包含文本的节点
更多内容
XSLT:
<markers>
<self_closing_marker id="1"/> Some content, possible <othernodes>nodes with text</othernodes>
<self_closing_marker id="2-3"/> Some more content
</markers>
<xsl:template name="markers" match="self_closing_marker">
<xsl:value-of select="following-sibling::text()" />
</xsl:template>
问题是以下同级将选择所有内容,直到当前包装结束。我发现了一些解决方案,使用当前同级作为变量,并在此基础上使用前面的同级,但每当我实现它们时,就会得到空标记
最终的目标是使某些东西符合
<markers>
<marker id="1">Some content, possible nodes with text</marker>
<marker id="2-3">Some more content</marker>
</markers>
一些内容,可能包含文本的节点
更多内容
一种方法是在后面的同级轴上指定一个变量end
,该变量带有第一个自动关闭标记
元素:
轴
然后,对以下轴上的text()
节点应用谓词过滤器:
通过比较生成的id值来测试是否存在$end
,以及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>
您可以从相反的方向看: XSLT1.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>
演示:
如果不想输出空标记节点,请向模板的匹配模式添加谓词:
<xsl:template match="self_closing_marker[key('txt', generate-id())]">
如果您准备使用Saxon扩展函数(需要PE或更高版本),您可以使用:
saxon:leading(
following-sibling::node(),
function($x){exists($x/self::marker)})
看
函数返回序列中的所有项,直到提供的谓词返回true的第一个项为止
您也可以自己实现这个函数,但因为它使用高阶函数,所以它仍然需要Saxon PE或更高级别
否则,请使用其他人建议的解决方案。使用
以下同级::text()[1]
将不会选择两个标记之间其他节点的文本值。导致缺少“可能的文本节点”,这是正确的,XSLT 1.0中的公共组以方法开头不会在最后一个轴之后的自关闭标记
轴为空?以下所有文本节点的谓词不是false吗?是的,但是如果目的是选择这些元素之间的text()(这就是我理解需求的方式),那么这可能是可以的