<xsl:apply-templates> vs <xsl:call-template/>

本文介绍了XSLT中&lt;xsl:apply-templates&gt;与&lt;xsl:call-template&gt;的区别及其使用场景。通过示例说明了&lt;xsl:apply-templates&gt;适用于自动处理节点,而&lt;xsl:call-template&gt;则提供更精细的控制,允许创建特殊模板以实现更复杂的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

On a very basic level, you use <xsl:apply-templates> when you want to let the processor handle nodes automatically, and you use <xsl:call-template/> when you want finer control over the processing. So if you have:

<foo>
    <boo>World</boo>
    <bar>Hello</bar>
</foo>

And you have the following XSLT:

<xsl:template match="foo">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="bar">
    <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="boo">
    <xsl:value-of select="."/>
</xsl:template>

You will get the result WorldHello. Essentially, you've said "handle bar and boo this way" and then you've let the XSLT processor handle these nodes as it comes across them. In most cases, this is how you should do things in XSLT.

Sometimes, though, you want to do something fancier. In that case, you can create a special template that doesn't match any particular node. For example:

<xsl:template name="print-hello-world">
    <xsl:value-of select="concat( bar, ' ' , boo )" />
</xsl:template>

And you can then call this template while you're processing <foo> rather than automatically processing foo's child nodes:

<xsl:template match="foo">
    <xsl:call-template name="print-hello-world"/>
</xsl:template>

In this particular artificial example, you now get "Hello World" because you've overriden the default processing to do your own thing.

<xsl:template match="w:tbl"> <xsl:variable name="colCount" select="count(w:tblGrid/w:gridCol)"/> <fo:table table-layout="fixed" width="100%" border-collapse="collapse"> <xsl:for-each select="w:tblGrid/w:gridCol"> <fo:table-column column-width="{@w:w div 20}pt"/> </xsl:for-each> <fo:table-body> <xsl:if test="count(w:tr[1]/w:tc) > $colCount"> <fo:table-row> <fo:table-cell number-columns-spanned="{$colCount}"> <fo:block color="red">表格列数溢出警告</fo:block> </fo:table-cell> </fo:table-row> </xsl:if> <xsl:apply-templates select="w:tr"/> </fo:table-body> </fo:table> </xsl:template> <xsl:template match="w:tr"> <fo:table-row> <xsl:apply-templates select="w:tc"/> </fo:table-row> </xsl:template> <xsl:template match="w:tc"> <fo:table-cell border="1pt solid black" padding="2pt" display-align="center"> <xsl:variable name="currentGridSpan" select="w:tcPr/w:gridSpan/@w:val"/> <xsl:if test="$currentGridSpan"> <xsl:attribute name="number-columns-spanned"> <xsl:value-of select="$currentGridSpan"/> </xsl:attribute> </xsl:if> <xsl:variable name="precedingSpanSum"> <xsl:choose> <xsl:when test="preceding-sibling::w:tc"> <xsl:value-of select="sum(preceding-sibling::w:tc/w:tcPr/w:gridSpan/@w:val) + count(preceding-sibling::w:tc[not(w:tcPr/w:gridSpan)])"/> </xsl:when> <xsl:otherwise>0</xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:if test="w:tcPr/w:vMerge[@w:val='restart']"> <xsl:variable name="currentRow" select="ancestor::w:tr"/> <xsl:variable name="currentPos" select="$precedingSpanSum + 1"/> <xsl:variable name="rowSpan"> <xsl:call-template name="calculateRowSpan"> <xsl:with-param name="remainingRows" select="$currentRow/following-sibling::w:tr"/> <xsl:with-param name="targetColumn" select="$currentPos"/> <xsl:with-param name="accumulator" select="1"/> </xsl:call-template> </xsl:variable> <xsl:attribute name="number-rows-spanned"> <xsl:value-of select="$rowSpan"/> </xsl:attribute> </xsl:if> <fo:block linefeed-treatment="ignore" white-space-collapse="true"> <xsl:apply-templates select=".//w:p"/> </fo:block> </fo:table-cell> </xsl:template> <xsl:template name="calculateRowSpan"> <xsl:param name="remainingRows"/> <xsl:param name="targetColumn"/> <xsl:param name="accumulator"/> <xsl:choose> <xsl:when test="$remainingRows[1]/w:tc[$targetColumn]/w:tcPr/w:vMerge[@w:val='continue']"> <xsl:call-template name="calculateRowSpan"> <xsl:with-param name="remainingRows" select="$remainingRows[position() > 1]"/> <xsl:with-param name="targetColumn" select="$targetColumn"/> <xsl:with-param name="accumulator" select="$accumulator + 1"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$accumulator"/> </xsl:otherwise> </xsl:choose> </xsl:template> 上述xlst样式表使用后报错The column-number or number of cells in the row overflows the number of fo:table-columns specified for the table. (See position 1:10790),怎么修改,请直接给出修改好的样式表,注意这是word的xml转xls-fo的xlst样式表,且版本均为1.0,请直接给出修改结果
03-08
<xsl:template match="w:tc"><fo:table-cell border="1pt solid black"padding="2pt"display-align="center"><xsl:variable name="totalCols"select="count(ancestor::w:tbl/w:tblGrid/w:gridCol)"/><xsl:variable name="precedingSpanSum"><xsl:choose><xsl:when test="preceding-sibling::w:tc"><xsl:value-of select="sum(preceding-sibling::w:tc/w:tcPr/w:gridSpan/@w:val) + count(preceding-sibling::w:tc[not(w:tcPr/w:gridSpan)])"/></xsl:when><xsl:otherwise>0</xsl:otherwise></xsl:choose></xsl:variable><xsl:if test="w:tcPr/w:gridSpan"><xsl:variable name="declaredSpan"select="w:tcPr/w:gridSpan/@w:val"/><xsl:variable name="remainingCols"select="$totalCols - $precedingSpanSum"/><xsl:attribute name="number-columns-spanned"><xsl:choose><xsl:when test="$declaredSpan > $remainingCols"><xsl:value-of select="$remainingCols"/></xsl:when><xsl:otherwise><xsl:value-of select="$declaredSpan"/></xsl:otherwise></xsl:choose></xsl:attribute></xsl:if><!--修正的行合并逻辑--><xsl:if test="w:tcPr/w:vMerge[@w:val='restart']"><xsl:variable name="currentPos"select="count(preceding-sibling::w:tc) + 1"/><xsl:variable name="rowSpan"><xsl:call-template name="calculateRowSpan"><!--修正点1:直接取后续所有行--><xsl:with-param name="remainingRows"select="../following-sibling::w:tr"/><xsl:with-param name="position"select="$currentPos"/><xsl:with-param name="count"select="1"/></xsl:call-template></xsl:variable><xsl:attribute name="number-rows-spanned"><xsl:value-of select="$rowSpan"/></xsl:attribute></xsl:if><fo:block linefeed-treatment="ignore"white-space-collapse="true"><xsl:apply-templates select=".//w:p"/></fo:block></fo:table-cell></xsl:template><!--新增递归模板--><xsl:template name="calculateRowSpan"><xsl:param name="remainingRows"/><xsl:param name="position"/><xsl:param name="count"/><xsl:choose><!--修正点2:增加空行判断--><xsl:when test="count($remainingRows) = 0"><xsl:value-of select="$count"/></xsl:when><xsl:otherwise><xsl:variable name="currentRow"select="$remainingRows[1]"/><xsl:variable name="targetCell"select="$currentRow/w:tc[$position]"/><!--修正点3:处理单元格位置偏移--><xsl:variable name="precedingSpan"select="sum($currentRow/w:tc[position() < $position]/w:tcPr/w:gridSpan/@w:val)"/><xsl:choose><!--修正点4:精准定位合并目标单元格--><xsl:when test="$targetCell/w:tcPr/w:vMerge[@w:val='continue'] and ($position - $precedingSpan) <= count($currentRow/w:tc)"><xsl:call-template name="calculateRowSpan"><xsl:with-param name="remainingRows"select="$remainingRows[position() > 1]"/><xsl:with-param name="position"select="$position"/><xsl:with-param name="count"select="$count + 1"/></xsl:call-template></xsl:when><xsl:otherwise><xsl:value-of select="$count"/></xsl:otherwise></xsl:choose></xsl:otherwise></xsl:choose></xsl:template>解决一下单元格行合并失效的问题,一定要注意这是word的xml转xls-fo的xslt样式表,且xslt版本为1.0,请直接给出修改结果
03-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值