XSLT中xsl:apply-templates使用困惑:为何未输出预期的姓名与年龄
问题原因与修复方案
注:你提供的运行结果中的
Sam nkmk应为输入笔误,实际正确输出应为Sam Brown。
你的问题核心是自定义的person模板中断了XSLT的默认递归处理逻辑:
当XSLT匹配到节点时,若没有自定义模板,会使用内置默认模板——默认模板匹配元素节点时,会自动执行<xsl:apply-templates/>递归处理所有子节点。但一旦你编写了自己的person模板,就完全替代了默认模板的行为,而你的模板仅实现了输出name的逻辑,没有触发对age等子节点的处理,导致age模板根本没有执行机会。
修复方法
在person模板中添加子节点处理逻辑,有两种常用方式:
方式1:精准处理age节点
在person模板中添加<xsl:apply-templates select="age"/>,仅触发age节点的模板处理:
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:output method="html" /> <xsl:template match="/"> <html> <body> <xsl:apply-templates /> </body> </html> </xsl:template> <xsl:template match="person"> <p> <xsl:value-of select="name/text()" /> </p> <!-- 触发age节点的模板 --> <xsl:apply-templates select="age"/> </xsl:template> <xsl:template match="age"> <p> <xsl:value-of select="text()" /> </p> </xsl:template> </xsl:stylesheet>
方式2:处理所有子节点
若需要处理person的所有子节点(比如后续要输出occupation),可以直接添加<xsl:apply-templates/>:
<xsl:template match="person"> <p> <xsl:value-of select="name/text()" /> </p> <!-- 处理所有子节点,包括age、occupation等 --> <xsl:apply-templates/> </xsl:template>
预期输出
<html> <body> <p>John Doe</p> <p>30</p> <p>Jane Smith</p> <p>28</p> <p>Sam Brown</p> <p>35</p> </body> </html>
进阶优化:合并输出
如果希望将姓名和年龄放在同一个段落中,无需单独的age模板,直接在person模板中拼接即可:
<xsl:template match="person"> <p> <xsl:value-of select="name/text()" /> - 年龄:<xsl:value-of select="age/text()" /> </p> </xsl:template>
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

