扁平XML靠属性(如parentId)隐含父子关系,嵌套结构用标签包裹实现层级;XSLT通过key()索引子节点并递归模板将扁平数据转为嵌套树形结构。

理解扁平XML和嵌套结构的区别
扁平XML通常指所有元素都在同一层级,靠属性(如 id、parentId)隐含父子关系,比如菜单项、组织架构或树形数据。嵌套结构则是用实际的父子标签包裹,比如 。XSLT 的核心任务就是根据 parentId(或类似字段)把“散装”的节点组装成树。
关键:用 key() 和递归模板匹配父子关系
XSLT 不支持循环建树,必须靠递归。先用 key() 快速索引子节点,再用模板调用自身处理后代。
- 定义 key:
(假设每个item有@parentId) - 从根节点开始(例如
@parentId = ''或@parentId = '0'或不存在): - 在 item 模板里,用
key('children', @id)找出所有直接子节点,并递归应用模板
一个可运行的简化示例
输入(扁平):
输出(嵌套):
对应 XSLT 片段(XSLT 1.0):
注意事项和常见坑
- 确保 parentId 值与父节点的 id 完全一致(包括空字符串、'0'、null 表示根 —— 需统一判断)
- XSLT 1.0 不支持
current()在 key 中动态计算,所以 key 必须基于原始属性值建立 - 如果存在环(比如 A 的 parentId 是 B,B 的 parentId 是 A),会无限递归 —— 生产环境建议加深度限制或预检
- 想保留原始顺序?key 返回节点集默认无序,用
select="item[@parentId = $id]"替代 key 可维持文档顺序(但性能略低)










