2

我有一个这样的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>. 看起来我需要某种递归来将模板重新应用于生成的内容,但我想不出任何东西。

4

1 回答 1

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>
于 2013-02-06T23:23:19.447 回答