XSLT实现匹配首个item并在全列表中正常渲染(避免重复匹配)
问题描述
需求:匹配列表中的首个item并输出特定内容FIZZ,同时渲染完整item列表时,首个item使用通用item模板输出BUZZ,预期最终输出为 FIZZ BUZZ BUZZ。
给定XML
<page> <set> <item><name>One</name></item> <item><name>Two</name></item> </set> </page>
原XSLT代码
<xsl:template match="page"> <xsl:apply-templates select="set/item[1]"/> <xsl:apply-templates select="set"/> </xsl:template> <xsl:template match="set"> <xsl:apply-templates select="item"/> </xsl:template> <!-- 仅匹配首个item --> <xsl:template match="set/item[1]"> FIZZ </xsl:template> <!-- 匹配所有item(包括首个) --> <xsl:template match="item"> BUZZ </xsl:template>
问题现象
实际运行后输出为 FIZZ FIZZ BUZZ,原因是执行<xsl:apply-templates select="item"/>时,首个item依然匹配了优先级更高的set/item[1]模板,而非通用的item模板。
可选调整XML(移除<set>节点):
<item><name>One</name></item> <item><name>One</name></item>
解决方案
要实现预期效果,需让第二次处理首个item时强制使用通用item模板,最清晰的实现方式是使用**模板模式(mode)**区分两次调用:
<xsl:template match="page"> <!-- 首次处理首个item,指定专属模式 --> <xsl:apply-templates select="set/item[1]" mode="first"/> <xsl:apply-templates select="set"/> </xsl:template> <xsl:template match="set"> <xsl:apply-templates select="item"/> </xsl:template> <!-- 仅在mode="first"时匹配首个item --> <xsl:template match="set/item[1]" mode="first"> FIZZ </xsl:template> <!-- 默认模式匹配所有item(包括首个) --> <xsl:template match="item"> BUZZ </xsl:template>
运行调整后的XSLT,即可得到预期输出:FIZZ BUZZ BUZZ
内容的提问来源于stack exchange,提问作者A Boston
相关产品推荐
相关产品推荐

