You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用XSLT动态生成元素名并按下划线分组转换XML

解决动态下划线元素名的多层分组XML转换问题

嘿,我完全懂你作为XSLT新手的困扰——面对这种全是下划线分隔的动态元素名,硬编码肯定行不通,用substring也没法处理多层嵌套的分组。咱们换个思路,用递归模板配合tokenize()函数来搞定这个动态层级问题,完美适配你的需求!

完整XSLT解决方案

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <!-- 匹配根节点,生成新的<data>根元素 -->
    <xsl:template match="/data">
        <data>
            <!-- 按元素名的第一个下划线前缀分组(比如fruits、animal) -->
            <xsl:for-each-group select="*" group-by="tokenize(local-name(), '_')[1]">
                <!-- 动态创建分组的顶层元素 -->
                <xsl:element name="{current-grouping-key()}">
                    <!-- 调用递归模板处理每个元素的剩余名称片段 -->
                    <xsl:apply-templates select="current-group()">
                        <xsl:with-param name="remaining-parts" select="tokenize(local-name(), '_')[position() > 1]"/>
                    </xsl:apply-templates>
                </xsl:element>
            </xsl:for-each-group>
        </data>
    </xsl:template>

    <!-- 递归核心模板:处理剩余的名称片段,自动生成嵌套元素 -->
    <xsl:template match="*">
        <xsl:param name="remaining-parts" as="xs:string*"/>
        
        <!-- 情况1:只剩最后一个片段,直接创建元素并赋值 -->
        <xsl:if test="count($remaining-parts) = 1">
            <xsl:element name="{$remaining-parts[1]}">
                <xsl:value-of select="."/>
            </xsl:element>
        </xsl:if>
        
        <!-- 情况2:还有多个片段,继续按当前第一个片段分组 -->
        <xsl:if test="count($remaining-parts) > 1">
            <xsl:for-each-group select="." group-by="$remaining-parts[1]">
                <xsl:element name="{current-grouping-key()}">
                    <!-- 递归调用,传递去掉第一个片段后的剩余部分 -->
                    <xsl:apply-templates select="current-group()">
                        <xsl:with-param name="remaining-parts" select="$remaining-parts[position() > 1]"/>
                    </xsl:apply-templates>
                </xsl:element>
            </xsl:for-each-group>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

关键逻辑解释

  1. 初始分组:在根模板里,用tokenize(local-name(), '_')把每个元素名拆分成下划线分隔的片段,然后按第一个片段(比如fruits、animal)分组,自动生成顶层的<fruits>、<animal>元素。
  2. 递归嵌套:递归模板是核心——每次接收剩余的名称片段,判断剩余数量:
    • 如果只剩1个片段,直接创建元素并填入原元素的数值;
    • 如果还有多个片段,继续按当前第一个片段分组,创建父元素后递归处理剩下的片段,自动生成多层嵌套结构。
  3. 完全动态适配:全程用xsl:element动态生成元素名,不需要硬编码任何层级的名称,不管你的真实数据有多少层下划线分隔,都能自动生成对应的嵌套XML。

注意事项

  • 这个方案需要你的XSLT处理器支持XSLT 2.0或更高版本(比如Saxon、Altova XMLSpy,或者一些现代在线XSLT工具);
  • 把你的示例数据输入进去,运行这个XSLT就能得到你期望的输出结果,完全匹配需求。

内容的提问来源于stack exchange,提问作者maverick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:07:52