我有一个像这样的xml:
<span reference="1">Reference Text 1</span>
<term reference="2">Reference Text 2</term>
我需要它成为这个:
<span class="referenceText">Reference Text 1</span> <a href="1">[1]</a>
<i>Reference Text 2</i> <a href="2">[2]</a>
因此,基本上,如果具有reference
属性的元素是一个范围,我们只需保留原样,添加class="referenceText"
。但是,如果它是任何其他元素,那么我们还应该应用为此元素创建的模板。这就是<term>
成为<i>
的原因 - 我有一个模板:
<xsl:template match="term">
<i><xsl:apply-templates select="@* |node()"/></i>
</xsl:template>
对于具有reference
属性的所有元素的转换,我有这个模板:
<xsl:template match="*[@reference]">
<xsl:param name="href" select="./@reference"/>
<xsl:choose>
<xsl:when test="name() = 'span'">
<span class="referenceText">
<xsl:value-of select="."/>
</span>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
<xsl:text> </xsl:text><a href="#{$href}">[<xsl:value-of select="./@href"/>]</a>
</xsl:template>
不幸的是,这导致以下输出:
<span class="referenceText">Reference Text 1</span> <a href="1">[1]</a>
<term>Reference Text 2</term> <a href="2">[2]</a>
因此,<term>
未转换为<i>
。看起来我需要某种递归来重新应用模板到生成的内容,但我无法想出任何东西。
答案 0 :(得分:2)
如果您正在使用XSLT 1.0,则可以捕获变量中的输出,然后使用exslt:node-set函数将模板应用于变量。尽量避免无限递归:)
<xsl:variable name="foo">
...
</xsl:variable>
<xsl:apply-templates select="exslt:node-set($foo)"/>
(编辑:纳入与此答案相关的其他评论)
为了使用EXSLT扩展,第一步是声明其命名空间。 EXSLT项目网站建议您在<xsl:stylesheet>
节点上执行此操作:
使用EXSLT中描述的扩展的第一步是为EXSLT模块定义相关的命名空间。您应该在样式表中的xsl:stylesheet元素上声明命名空间。
<xsl:stylesheet xmlns:exslt="http://exslt.org/common">
//...
</xsl:stylesheet>
此外,extension-element-prefixes
属性可用于防止扩展名称空间被添加到结果文档中:
<xsl:stylesheet xmlns:exslt="http://exslt.org/common" extension-element-prefixes="exslt">
//...
</xsl:stylesheet>