XSLT多级缩进问题求助:嵌套食品列表无法正确缩进子项
问题解决方案
核心思路
- 计算每个食品节点的嵌套深度,根据深度动态生成缩进样式(如
padding-left或margin-left) - 用递归模板遍历所有层级的子节点,传递当前深度参数
示例代码与修复方案
假设你的XML结构如下(通用嵌套食品结构):
<foods> <food name="主食"> <food name="米饭"> <food name="白米饭"/> <food name="杂粮饭"/> </food> <food name="面条"> <food name="拉面"/> </food> </food> <food name="蔬菜"> <food name="绿叶菜"/> </food> </foods>
修复后的XSLT代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes"/> <!-- 初始调用,设置根层级深度为0 --> <xsl:template match="/foods"> <table border="1"> <xsl:apply-templates select="food"> <xsl:with-param name="depth" select="0"/> </xsl:apply-templates> </table> </xsl:template> <!-- 递归处理每个food节点,传递深度参数 --> <xsl:template match="food"> <xsl:param name="depth"/> <tr> <!-- 每层级增加20px缩进,数值可按需调整 --> <td style="padding-left: {$depth * 20}px;"> <xsl:value-of select="@name"/> </td> </tr> <!-- 递归处理子节点,深度+1 --> <xsl:if test="food"> <xsl:apply-templates select="food"> <xsl:with-param name="depth" select="$depth + 1"/> </xsl:apply-templates> </xsl:if> </xsl:template> </xsl:stylesheet>
关键点说明
- 递归+参数传递:通过
<xsl:param>在模板间传递当前节点的嵌套层级,子节点处理时深度自动+1,确保所有层级都能计算正确缩进 - 动态样式计算:用
{$depth * 20}px将深度转化为具体的缩进值,替代固定的第一级样式 - 全层级遍历:通过递归调用
<xsl:apply-templates select="food",覆盖所有嵌套子节点,避免仅处理第一级子项
学习方向
- 掌握XSLT递归模板调用:这是处理XML嵌套结构的核心技巧,重点理解参数传递与模板匹配的逻辑
- 熟悉XSLT变量与参数:学会用参数在模板间传递状态(如嵌套深度)
- 了解XSLT与HTML样式结合:可通过动态生成inline样式或CSS类名,实现更灵活的层级可视化
- 复习XPath节点轴:也可通过
count(ancestor::food)直接计算节点深度,两种方式均可实现层级判断
内容的提问来源于stack exchange,提问作者n00b
相关产品推荐
相关产品推荐

