怎么把一个扁平的XML结构转换成嵌套结构 XSLT教程

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

理解扁平XML和嵌套结构的区别

扁平XML通常指所有元素都在同一层级,靠属性(如 idparentId)隐含父子关系,比如菜单项、组织架构或树形数据。嵌套结构则是用实际的父子标签包裹,比如 ...。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 可维持文档顺序(但性能略低)
基本上就这些。不复杂但容易忽略 key 定义位置和根节点判定条件。