如何在XSLT中嵌套模板?call-template与apply-template可行方案
可行实现方案
你碰到的是XSLT的语法限制:<xsl:call-template>的子节点只能是<xsl:with-param>,无法直接嵌套另一个<xsl:call-template>。以下是两种符合你"积木式组合表格"需求的实现方案:
方案1:带参数的模板扩展(基于call-template)
核心思路是给表格模板设计可选参数,允许传入需要嵌套的内容(包括其他表格模板的调用),在模板内部预留的位置渲染这些内容。
模板定义
<!-- Table1模板:接受可选的inner-content参数,用于插入嵌套内容 --> <xsl:template name="Table1"> <xsl:param name="inner-content" select="''"/> <table class="table1"> <tr><th>Table1 表头</th></tr> <!-- 预留的嵌套内容插入位置 --> <xsl:copy-of select="$inner-content"/> </table> </xsl:template> <!-- Table2模板:独立可复用 --> <xsl:template name="Table2"> <table class="table2"> <tr><th>Table2 表头</th></tr> <tr><td>Table2 内容</td></tr> </table> </xsl:template>
调用方式
- 单独调用:
<!-- 仅渲染Table1 --> <xsl:call-template name="Table1"/> <!-- 仅渲染Table2 --> <xsl:call-template name="Table2"/>
- 嵌套调用:
<!-- 将Table2作为嵌套内容传入Table1,同时添加自定义代码 --> <xsl:call-template name="Table1"> <xsl:with-param name="inner-content"> <xsl:call-template name="Table2"/> <p>Additional Code here!</p> </xsl:with-param> </xsl:call-template>
如果使用XSLT 2.0+,可以将参数类型指定为节点序列,进一步提升内容传递的灵活性。
方案2:模式化模板组合(基于apply-templates)
核心思路是给不同表格模板指定专属模式(mode),通过<xsl:apply-templates>在需要的位置触发对应模式的模板,实现灵活的嵌套与组合。
模板定义
<!-- 带table1模式的模板 --> <xsl:template match="." mode="table1"> <table class="table1"> <tr><th>Table1 表头</th></tr> <!-- 触发table2模式的模板,实现嵌套 --> <xsl:apply-templates select="." mode="table2"/> </table> </xsl:template> <!-- 带table2模式的模板 --> <xsl:template match="." mode="table2"> <table class="table2"> <tr><th>Table2 表头</th></tr> <tr><td>Table2 内容</td></tr> </table> </xsl:template> <!-- 自定义组合模板:Table1嵌套Table2 + 额外代码 --> <xsl:template match="." mode="table1-with-custom"> <table class="table1"> <tr><th>Table1 表头</th></tr> <xsl:apply-templates select="." mode="table2"/> <p>Additional Code here!</p> </table> </xsl:template>
调用方式
- 单独调用:
<!-- 仅渲染Table1 --> <xsl:apply-templates select="." mode="table1"/> <!-- 仅渲染Table2 --> <xsl:apply-templates select="." mode="table2"/>
- 嵌套调用:
<!-- 使用预定义的嵌套模板 --> <xsl:apply-templates select="." mode="table1"/> <!-- 使用自定义组合的模板 --> <xsl:apply-templates select="." mode="table1-with-custom"/>
如果需要动态控制是否嵌套,还可以结合参数和条件判断:
<xsl:template name="FlexTable"> <xsl:param name="include-table2" select="false()"/> <table class="flex-table"> <tr><th>灵活组合表头</th></tr> <xsl:if test="$include-table2"> <xsl:apply-templates select="." mode="table2"/> </xsl:if> </table> </xsl:template>
调用时只需传递参数即可切换状态:
<xsl:call-template name="FlexTable"> <xsl:with-param name="include-table2" select="true()"/> </xsl:call-template>
内容的提问来源于stack exchange,提问作者feuerdoggo
相关产品推荐
相关产品推荐

