如何对XSLT模板的输出进行第二次转换
我只有基本的XSLT技能,如果这是基本的或不可能的,我深表歉意 我有一个paginator模板,它在我所看到的网站上随处可见。有一个bug,其中一个特定的搜索需要在页面链接的href中附加categoryId参数。我不能改变paginator样式表,否则我只会在其中添加一个参数。我想做的是按原样应用模板,然后根据其输出进行第二次转换。这可能吗?其他人通常如何扩展库模板 到目前为止,我一直在考虑对输出进行递归复制,并在处理HREF时将模板应用于它们。我有点想不起它的语法,尤其是我甚至不确定它是否可能如何对XSLT模板的输出进行第二次转换,xslt,Xslt,我只有基本的XSLT技能,如果这是基本的或不可能的,我深表歉意 我有一个paginator模板,它在我所看到的网站上随处可见。有一个bug,其中一个特定的搜索需要在页面链接的href中附加categoryId参数。我不能改变paginator样式表,否则我只会在其中添加一个参数。我想做的是按原样应用模板,然后根据其输出进行第二次转换。这可能吗?其他人通常如何扩展库模板 到目前为止,我一直在考虑对输出进行递归复制,并在处理HREF时将模板应用于它们。我有点想不起它的语法,尤其是我甚至不确定它是否可
编辑-在Dabbler的回答和Michael Kay的评论之间,我们得到了答案。这是我的完整测试
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<!-- note we require the extensions for this transform -->
<!--We call the template to be extended here and store the result in a variable-->
<xsl:variable name="output1">
<xsl:call-template name="pass1"/>
</xsl:variable>
<!--The template to be extended-->
<xsl:template name="pass1">
<a href="url?param1=junk">foo</a>
</xsl:template>
<!--the second pass. we lock this down to a mode so we can control when it is applied-->
<xsl:template match="a" mode="pass2">
<xsl:variable name="href" select="concat(@href, '&', 'catid', '=', 'stuff')"/>
<a href="{$href}"><xsl:value-of select="."/></a>
</xsl:template>
<xsl:template match="/">
<html><head></head><body>
<!--the node-set extension function turns the first pass back into a node set-->
<xsl:apply-templates select="ext:node-set($output1)" mode="pass2"/>
</body></html>
</xsl:template>
</xsl:stylesheet>
这在XSLT2中是可能的;您可以将数据存储在变量中,并在该变量上调用apply templates 基本示例:
<xsl:variable name="MyVar">
<xsl:element name="Elem"/> <!-- Or anything that creates some output -->
</xsl:variable>
<xsl:apply-templates select="$MyVar"/>
在样式表的某个地方有一个匹配Elem的模板。您还可以使用单独的模式在两个阶段(构建变量和处理变量)之间保持清晰的区别,特别是当两个阶段都使用匹配相同节点的模板时。下面是一个完整的示例,说明如何使用XSLT 1.0完成多过程处理:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*" mode="mPass2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="mPass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="vrtfPass1Result">
<xsl:apply-templates/>
</xsl:variable>
<xsl:apply-templates mode="mPass2"
select="ext:node-set($vrtfPass1Result)/*"/>
</xsl:template>
<xsl:template match="num/text()">
<xsl:value-of select="2*."/>
</xsl:template>
<xsl:template match="/*" mode="mPass2">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates mode="mPass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="num/text()" mode="mPass2">
<xsl:value-of select="3 + ."/>
</xsl:template>
</xsl:stylesheet>
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
<nums>
<num>5</num>
<num>7</num>
<num>9</num>
<num>11</num>
<num>13</num>
<num>15</num>
<num>17</num>
<num>19</num>
<num>21</num>
<num>23</num>
</nums>
在XSLT1.0中,您可以对提供exsl:node-set()扩展名的任何处理器执行相同的操作:只需将应用模板中的select替换为select=“exsl:node-set($MyVar)”。