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

XSLT分组问题:按ExternalBatchNo前缀分组machine与part失败求助

问题

需要实现基于单个元素的双条件分组:将ExternalBatchNo中-之前部分相同的machine和part归为一组,拆分出多个<Document>节点,每个节点包含同前缀的machine和part。

输入XML

<Document>
    <DocumentLine>
        <ExternalBatchNo>KEC36770</ExternalBatchNo>
        <Attribute01>machine</Attribute01>
    </DocumentLine>
    <DocumentLine>
        <ExternalBatchNo>KEC36770-2</ExternalBatchNo>
        <Attribute01>part</Attribute01>
    </DocumentLine>
    <DocumentLine>
        <ExternalBatchNo>KEC36771</ExternalBatchNo>
        <Attribute01>machine</Attribute01>
    </DocumentLine>
    <DocumentLine>
        <ExternalBatchNo>KEC36771-2</ExternalBatchNo>
        <Attribute01>part</Attribute01>
    </DocumentLine>
    <DocumentLine>
        <ExternalBatchNo>KEC36771-3</ExternalBatchNo>
        <Attribute01>part</Attribute01>
    </DocumentLine>
</Document>

期望输出

<Document>
    <DocumentLine>
        <ExternalBatchNo>KEC36770</ExternalBatchNo>
        <Attribute01>machine</Attribute01>
    </DocumentLine>
    <DocumentLine>
        <ExternalBatchNo>KEC36770-2</ExternalBatchNo>
        <Attribute01>part</Attribute01>
    </DocumentLine>
</Document>

<Document>
    <DocumentLine>
        <ExternalBatchNo>KEC36771</ExternalBatchNo>
        <Attribute01>machine</Attribute01>
    </DocumentLine>
    <DocumentLine>
        <ExternalBatchNo>KEC36771-2</ExternalBatchNo>
        <Attribute01>part</Attribute01>
    </DocumentLine>
    <DocumentLine>
        <ExternalBatchNo>KEC36771-3</ExternalBatchNo>
        <Attribute01>part</Attribute01>
    </DocumentLine>
</Document>

尝试的代码问题

使用以下代码时,machine对应的分组ID为空,只能对part完成分组:

<xsl:for-each-group select="Message/Documents/Document/DocumentLine" group-by="substring-before(ExternalBatchNo,'-')">
解决方案

问题出在substring-before(ExternalBatchNo,'-')——当ExternalBatchNo中没有-时,这个函数会返回空字符串,导致machine条目无法和对应前缀的part条目归为一组。

可以通过给无-的ExternalBatchNo拼接一个-来统一处理,确保substring-before总能获取到正确的前缀:

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

    <xsl:template match="/Document">
        <!-- 按处理后的前缀分组 -->
        <xsl:for-each-group select="DocumentLine" group-by="substring-before(concat(ExternalBatchNo, '-'), '-')">
            <!-- 生成每个分组对应的Document节点 -->
            <Document>
                <!-- 输出当前分组下的所有DocumentLine -->
                <xsl:copy-of select="current-group()"/>
            </Document>
            <!-- 添加空行分隔不同Document节点 -->
            <xsl:text>&#10;&#10;</xsl:text>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

代码说明

  1. concat(ExternalBatchNo, '-'):给所有ExternalBatchNo末尾拼接-,比如KEC36770变成KEC36770-,KEC36770-2变成KEC36770-2-。
  2. substring-before(..., '-'):此时无论原字符串是否有-,都能提取到第一个-之前的正确前缀,比如KEC36770和KEC36770-2的前缀都是KEC36770。
  3. current-group():获取当前分组下的所有DocumentLine节点,直接复制输出即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:59:51