How do I use xsl:apply-templates on the node that is itself generated with xsl?

岁酱吖の 提交于 2020-01-03 03:03:46

问题


I have an xml like this:

<span reference="1">Reference Text 1</span>
<term reference="2">Reference Text 2</term>

And I need it to become this:

<span class="referenceText">Reference Text 1</span> <a href="1">[1]</a>
<i>Reference Text 2</i> <a href="2">[2]</a>

So, basically, if the element with the reference attribute is a span, we just leave it as is, adding class="referenceText". If, however it is any other element, then we should also apply templates created for this element. That's why <term> should become <i> - I have a template for it:

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

For the transformation of all elements with a reference attribute I have this template:

<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>

Unfortunately, this results in the following output:

<span class="referenceText">Reference Text 1</span> <a href="1">[1]</a>
<term>Reference Text 2</term> <a href="2">[2]</a>

So, <term> is not converted into <i>. It looks like I need some sort of recursion to re-apply the templates to what's been generated, but I can't come up with anything.


回答1:


If you're using XSLT 1.0, you can capture the output in a variable and then use the exslt:node-set function to apply templates to the variable. Try to avoid infinite recursion, though :)

<xsl:variable name="foo">
...
</xsl:variable>
<xsl:apply-templates select="exslt:node-set($foo)"/>

(EDIT: incorporating additional comments relevant to this answer)

In order to use an EXSLT extension, the first step is to declare its namespace. The EXSLT project website recommends doing so on your <xsl:stylesheet> node:

The first step to using the extensions described in EXSLT is to define the relevant namespace for the EXSLT module. You should declare the namespace on the xsl:stylesheet element in your stylesheet.

<xsl:stylesheet xmlns:exslt="http://exslt.org/common">
  //...
</xsl:stylesheet>

In addition, the extension-element-prefixes attribute can be used to prevent the extensions namespaces from being added to the resulting document:

<xsl:stylesheet xmlns:exslt="http://exslt.org/common" extension-element-prefixes="exslt">
  //...
</xsl:stylesheet>


来源:https://stackoverflow.com/questions/14740673/how-do-i-use-xslapply-templates-on-the-node-that-is-itself-generated-with-xsl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!