Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 通过XSLT在两个自动关闭标记之间选择文本_Xml_Xslt_Saxon - Fatal编程技术网

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()(这就是我理解需求的方式),那么这可能是可以的