递归替换XSLT中的元素

时间:2016-08-11 12:35:35

标签: xslt recursion

我需要将<tref>元素替换为文档中其他位置的其他标记。例如,我有:

<tref id="57236"/>

<Topic>
    <ID>57236</ID>
    <Text>
        <p id="4">
            <cs id="56792">1090-189-01 </cs>
            <href id="57237">
                  <cs id="56792">Document Name</cs>
            </href>
        </p>
    </Text>
</Topic>

获取以下内容不是问题:

<p id="4">
    <cs id="56792">1090-189-01 </cs>
    <href id="57237">
        <cs id="56792">Document Name</cs>
    </href>
</p>

使用此样式表:

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="tref">
    <xsl:variable name="NodeID"><xsl:value-of select="@id"/></xsl:variable>
    <xsl:copy-of select="//Topic[ID = $NodeID]/Text/p/node()"/>
</xsl:template>

我不能做的是替换嵌套在其他trefs中的trefs。例如,请考虑以下事项:

<tref id="57236"/>

<Topic>
    <ID>57236</ID>
    <Text>
        <p id="251">
            <tref id="37287"/>
        </p>
    </Text>
</Topic>

我的样式表适当地将tref替换为标签的内容 - 其中还包含一个tref:

<p id="251">
    <tref id="37287"/>
</p>

我目前的解决方案是从两个不同的样式表中调用<xsl:template match="tref">。它完成了这项工作,但它不是很优雅,如果trefs嵌套在更深的层次会怎样?递归是XSLT的基础。

是否有解决方案以递归方式替换XSLT中的所有trefs?

1 个答案:

答案 0 :(得分:2)

不使用bp::child c("ls", bp::stdout > "my_file"); ,而是使用xsl:copy-of

xsl:apply-templates

或者,消除使用varianle

<xsl:apply-templates select="//Topic[ID = $NodeID]/Text/p/node()"/>

请注意,您可以使用<xsl:apply-templates select="//Topic[ID = current()/@id]/Text/p/node()"/> 查找xsl:key元素

Topic

然后你可以写这个

<xsl:key name="topic" match="Topic" use="ID" />

如果<xsl:apply-templates select="key('topic', @id)/Text/p/node()"/> 引用了tref作为其祖先,请注意无限递归。