如何编写一个捕获所有传递所有参数的XSL模板?

时间:2012-01-13 04:18:11

标签: templates xslt transform parameter-passing xslt-2.0

我正在编写一个“扩展”模板的模板,但它有一些问题。

<xsl:template match="*[@condition]" mode="#all">
<xsl:element name="condition">
  <xsl:attribute name="name">
    <xsl:value-of select="@condition"></xsl:value-of>
  </xsl:attribute>
  <xsl:apply-imports>
  </xsl:apply-imports>
</xsl:element>

问题是使用<xsl:apply-imports>调用的模板缺少参数。 params列表是未知的,因为此模板试图扩展许多不同的模板(因此mode="#all")。

这有什么好方法吗?


附加示例:

考虑两个最终模板(只读):

<xsl:template match="*" mode="mode1">
    <param name="p1"/>
</xsl:template>

<xsl:template match="*" mode="mode2">
    <param name="p2"/>
</xsl:template>

他们被称为某处(只读):

<xsl:apply-templates mode="mode1">
    <xsl:with-param name="mode1" select="$mode1"/>
</xsl:apply-templates>

<xsl:apply-templates mode="mode2">
    <xsl:with-param name="mode2" select="$mode2"/>
</xsl:apply-templates>

可能有100个mode1,mode2,mode3,mode4 ......并且名称没有模式。

我希望有一个全局模板,可以围绕最终模板包含其他信息。类似的东西:

<xsl:template match="*" mode="#all">
    <xsl:next-match/>
</xsl:element>

问题是上面的全局模板没有将params传递给模板。

2 个答案:

答案 0 :(得分:1)

如果问题在于,当您致电<xsl:apply-imports>时,它不包含传递给当前模板的参数,您可以使用隧道参数。在您扩展的模板中标记您的参数,如下所示:

<xsl:param name="foo" tunnel="yes"/>

此外,当您传递参数时:

<xsl:with-param name="foo" tunnel="yes"/>

我还建议使用<xsl:next-match>代替<xsl:apply-imports>

答案 1 :(得分:1)

您可以使用Max Toro建议的隧道参数,也可以只传递一个参数,其子项是不同模板需要和识别的参数。

像这样

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pComposite" as="element()*">
   <param for="templateX" name="pA">
    12
   </param>
   <param for="templateY" name="pB">
    Some String
   </param>
 </xsl:param>

 <xsl:template match="*[@condition]">
  <condition name="{@condition}">
   <xsl:apply-imports>
     <xsl:with-param name="pComposite"
      select="$pComposite"/>
   </xsl:apply-imports>
  </condition>
 </xsl:template>
</xsl:stylesheet>