如何高效将XML同级元素列表重组为嵌套结构(XSLT优化)
高效实现List2元素嵌套到List1子元素的XSLT 2.0方案
针对大型XML的性能瓶颈,核心是把线性遍历查找改成索引式查找,用XSLT 2.0的<xsl:key>实现类Muenchian匹配,彻底规避嵌套for-each+谓词的低效遍历逻辑。
核心思路
- 提前用
key为List2的元素建立索引,键值绑定AoId(与List1子元素的Id匹配) - 处理List1的
list1Child节点时,直接通过索引快速拉取对应的List2元素,无需重复遍历整个List2集合
示例实现
假设原XML结构
<Root> <List1> <list1Child Id="1">原内容1</list1Child> <list1Child Id="2">原内容2</list1Child> </List1> <List2> <item AoId="1">关联内容A</item> <item AoId="1">关联内容B</item> <item AoId="2">关联内容C</item> </List2> </Root>
优化后的XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 为List2下的元素建立AoId索引 --> <xsl:key name="list2-by-aoid" match="List2/*" use="@AoId"/> <!-- 身份模板:原样复制未被特殊处理的节点 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理list1Child节点,插入匹配的List2元素 --> <xsl:template match="list1Child"> <xsl:copy> <!-- 保留原list1Child的所有属性和子内容 --> <xsl:apply-templates select="@*|node()"/> <!-- 通过索引快速获取并插入匹配的List2元素 --> <xsl:apply-templates select="key('list2-by-aoid', @Id)"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键说明
- 若List2的匹配键是子元素而非属性,将
use="@AoId"改为use="AoId"即可 - 身份模板保证原XML的其他结构完全保留,仅对
list1Child节点做修改 - 原嵌套
for-each的时间复杂度是O(n*m),索引查找的复杂度为O(n+m),大数据量下性能会有数量级提升
排查你之前key失败的常见原因
match路径错误:比如List2下的元素不是直接子节点,需写全路径(如//List2/item)- 键值类型不匹配:比如List1的
Id是数值型、List2的AoId是字符串,需用string(@Id)或number(@AoId)统一类型 key调用参数顺序错误:正确格式是key(键名, 匹配值),不要颠倒顺序
内容的提问来源于stack exchange,提问作者user10068690
相关产品推荐
相关产品推荐

