You need to enable JavaScript to run this app. XSLT 1.0环境下基于DocEntry与LineNum实现XML多级分组咨询
优惠活动
大模型
产品
解决方案
定价
更多

XSLT 1.0环境下基于DocEntry与LineNum实现XML多级分组咨询

XSLT 1.0 二级分组实现方案(按DocEntry+LineNum分组)

核心实现思路

  • 采用XSLT 1.0原生支持的Muenchian分组法实现二级层级分组,性能优于not(preceding::)的判断写法,适配所有支持XSLT 1.0的运行环境
  • 一级分组维度:DocEntry,用于聚合同一单据的所有行数据
  • 二级分组维度:DocEntry与LineNum拼接的组合键,用于在同一单据下按行号聚合行属性、序列号等关联数据

完整实现代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 定义一级分组键:按DocEntry分组所有行节点 -->
    <xsl:key name="docKey" match="Row" use="DocEntry"/>
    <!-- 定义二级分组键:按DocEntry+LineNum组合分组同一单据下的同行数据 -->
    <xsl:key name="lineKey" match="Row" use="concat(DocEntry, '|', LineNum)"/>

    <xsl:template match="/">
        <xsl:for-each select="//Row[count(. | key('docKey', DocEntry)[1]) = 1]">
            <object>
                <string name="DocEntry">
                    <xsl:value-of select="DocEntry"/>
                </string>
                <string name="DocDate">
                    <xsl:value-of select="DocDate"/>
                </string>
                <array name="transferLines">
                    <!-- 二级分组:取当前DocEntry下所有唯一LineNum的节点 -->
                    <xsl:for-each select="key('docKey', DocEntry)[count(. | key('lineKey', concat(DocEntry, '|', LineNum))[1]) = 1]">
                        <object>
                            <string name="LineNum">
                                <xsl:value-of select="LineNum"/>
                            </string>
                            <string name="ItemCode">
                                <xsl:value-of select="ItemCode"/>
                            </string>
                            <string name="Quantity">
                                <xsl:value-of select="Quantity"/>
                            </string>
                            <array name="SerialNumbers">
                                <!-- 遍历当前行下的所有序列号节点 -->
                                <xsl:for-each select="key('lineKey', concat(DocEntry, '|', LineNum))">
                                    <object>
                                        <xsl:if test="SerialNumber != ''">
                                            <string name="SerialNumber">
                                                <xsl:value-of select="SerialNumber"/>
                                            </string>
                                        </xsl:if>
                                    </object>
                                </xsl:for-each>
                            </array>
                        </object>
                    </xsl:for-each>
                </array>
            </object>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

关键逻辑说明

  1. 分组键用|作为分隔符拼接,避免DocEntry和LineNum拼接后出现歧义,比如DocEntry为12、LineNum为3,和DocEntry为1、LineNum为23的场景不会被误识别为同一分组
  2. 序列号节点输出时做了空值判断,无序列号的行输出空object,有多个序列号的行输出对应数量的object,完全匹配要求的输出结构
  3. 所有XSLT语法均为1.0标准语法,无扩展依赖,可直接在仅支持XSLT 1.0的环境中运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 22:42:04