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

使用XSLT转换XML时的分组问题(不支持for-each-group)

解决XSLT分组转换问题(不支持for-each-group场景)

在使用XSLT将XML转换为XML时,遇到分组信息丢失的问题:无法保留输入XML中的组名称及多组结构,只能生成固定名称的组。注意:系统不支持for-each-group和current-group()函数,使用会触发解析错误。同时需要将所有transaction组统一放入transactions父节点中。


示例输入XML

<?xml version="1.0" encoding="UTF-8"?>
<Statement xmlns:xsi="http://www.w.org/2001/XMLSchemainstance">
<field name="statementNumber"> 25 </field>
<field name="Online"> Yes </field>
<field name="iban"> xxxx </field>
<group name="addressFields">
<member name="addressLine1"> flat 2 ted apartments </member>
<member name="addressLine2"> samurai street </member>
<member name="town"> Jaisalmer </member>
<member name="postCode"> 678222 </member>
<member name="country"> Indonesia </member>
</group>
<group name="transaction">
<member name="type"> cash </member>
<member name="amount"> 5228 </member>
<member name="txnDate"> 28 oct 2022 </member>
<member name="reference"> ATM withdrawal </member>
</group>
<group name="transaction">
<member name="type"> card </member>
<member name="amount"> 3378 </member>
<member name="txnDate"> 28 nov 2022 </member>
<member name="reference"> Super market purchase </member>
</group>
</Statement>

原有XSLT代码片段

<xsl:output method="xml" indent="yes">
<xsl:template match="/">
<Statement>
  <xsl:for-each select="Statement/field">
    <xsl:element name="{@name}">
    <xsl:value-of select="."/>
    </xsl:element>
  </xsl:for-each>
  <xsl:element name="grouping">
    <xsl:for-each select="Statement/group/member">
      <xsl:element name="{@name}">
        <xsl:value-of select="."/>
      </xsl:element>
    </xsl:for-each>     
   </xsl:element>
</Statement>

当前错误输出

<?xml version="1.0" encoding="UTF-8"?>
<Statement>
<statementNumber>25</statementNumber>
<Online>Yes</Online>
<iban>xxxx</iban>
<grouping>
<addressLine1>flat 2 ted apartments</addressLine1>
<addressLine2>samurai street</addressLine2>
<town>Jaisalmer</town>
<postCode>678222</postCode>
<country>Indonesia</country>
<type>cash</type>
<amount>5228</amount>
<txnDate>28 oct 2022</txnDate>
<reference>ATM withdrawal</reference>
<type>card</type>
<amount>3378</amount>
<txnDate>28 nov 2022</txnDate>
<reference>Super market purchase</reference>
</grouping>
</Statement>

期望输出XML

<?xml version="1.0" encoding="UTF-8"?>
<Statement>
<statementNumber>25</statementNumber>
<Online>Yes</Online>
<iban>xxxx</iban>
<grouping>
<addressFields>
<addressLine1>flat 2 ted apartments</addressLine1>
<addressLine2>samurai street</addressLine2>
<town>Jaisalmer</town>
<postCode>678222</postCode>
<country>Indonesia</country>
</addressFields>
<transactions>
<transaction>
<type>cash</type>
<amount>5228</amount>
<txnDate>28 oct 2022</txnDate>
<reference>ATM withdrawal</reference>
</transaction>
<transaction>
<type>card</type>
<amount>3378</amount>
<txnDate>28 nov 2022</txnDate>
<reference>Super market purchase</reference>
</transaction>
</transactions>
</grouping>
</Statement>

修正后的XSLT代码

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

    <xsl:template match="/">
        <Statement>
            <!-- 处理field节点 -->
            <xsl:for-each select="Statement/field">
                <xsl:element name="{normalize-space(@name)}">
                    <xsl:value-of select="normalize-space(.)"/>
                </xsl:element>
            </xsl:for-each>

            <grouping>
                <!-- 处理非transaction的组 -->
                <xsl:for-each select="Statement/group[@name != 'transaction']">
                    <xsl:element name="{normalize-space(@name)}">
                        <xsl:for-each select="member">
                            <xsl:element name="{normalize-space(@name)}">
                                <xsl:value-of select="normalize-space(.)"/>
                            </xsl:element>
                        </xsl:for-each>
                    </xsl:element>
                </xsl:for-each>

                <!-- 处理transaction组,包裹到transactions节点中 -->
                <xsl:if test="Statement/group[@name = 'transaction']">
                    <transactions>
                        <xsl:for-each select="Statement/group[@name = 'transaction']">
                            <transaction>
                                <xsl:for-each select="member">
                                    <xsl:element name="{normalize-space(@name)}">
                                        <xsl:value-of select="normalize-space(.)"/>
                                    </xsl:element>
                                </xsl:for-each>
                            </transaction>
                        </xsl:for-each>
                    </transactions>
                </xsl:if>
            </grouping>
        </Statement>
    </xsl:template>
</xsl:stylesheet>

逻辑说明

  1. 字段处理:保留原有field节点的转换逻辑,同时用normalize-space()去除内容和属性值的多余空格
  2. 普通组处理:遍历所有非transaction的group节点,直接以组的@name作为元素名,内部遍历member生成子节点
  3. transaction组处理:先判断是否存在transaction组,若存在则生成transactions父节点,再遍历所有transaction组,每个组生成transaction子节点,内部处理member生成对应字段
  4. 全程未使用for-each-group或current-group()函数,适配系统限制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:11:31