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

如何将XML中P01/P02/P03按PositionNo分组嵌套入<Position>元素并排序

XML结构转换方案

转换要求

  • 新增<Position></Position>作为父节点
  • 相同PositionNo对应的PO1、P02、P03节点需嵌套到同一个<Position>节点内
  • 所有<Position>节点最终按PositionNo的数值升序排序

源XML示例(片段)

<PO1>
  <ClientNo>ABCD</ClientNo>
  <OrderNo>10000014</OrderNo>
  <FunctionNo>10</FunctionNo>
  <PositionNo>1</PositionNo>
  <ArticleNo>148756833112</ArticleNo>
  <QuantityLoading></QuantityLoading>
  <LMSM></LMSM>
  <QuantityUnit1>300000</QuantityUnit1>
  <UnitLevel>1</UnitLevel>
  <Obsolete1></Obsolete1>
  <Obsolete2></Obsolete2>
  <NetWeight>105600</NetWeight>
  <GrossWeight>105600</GrossWeight>
  <WeightUnit></WeightUnit>
  <ArticleDamageStatusFlag>0</ArticleDamageStatusFlag>
  <CustomStatusFlag>F</CustomStatusFlag>
  <PickingAdvice></PickingAdvice>
  <StockManagementFlag></StockManagementFlag>
  <LoadingNo></LoadingNo>
  <MeansOfTransportNo></MeansOfTransportNo>
  <StockNo>STANDARD</StockNo>
  <PackageId></PackageId>
  <PosIndex>101</PosIndex>
  <LMSMID></LMSMID>
  <Unit1Factor>1000</Unit1Factor>
  <Volume>0</Volume>
  <VolumeUnit>CBM</VolumeUnit>
  <LMSMQtyFactor></LMSMQtyFactor>
  <MeasurementUnitLevel></MeasurementUnitLevel>
  <MeasurementName></MeasurementName>
  <MeasurementUnit>1</MeasurementUnit>
  <PercentalExcessDelivery></PercentalExcessDelivery>
  <SmallestIndivisibleUnit></SmallestIndivisibleUnit>
  <AccuracyOfQty></AccuracyOfQty>
  <MTQQty></MTQQty>
  <PackingInstruction></PackingInstruction>
  <PickingListReference></PickingListReference>
</PO1>
<P02>
  <ClientNo>ABCD</ClientNo>
  <OrderNo>10000014</OrderNo>
  <FunctionNo>10</FunctionNo>
  <PositionNo>1</PositionNo>
  <LotNo></LotNo>
  <ArticleNoRecipient></ArticleNoRecipient>
  <ExternalReference></ExternalReference>
  <PositionText1></PositionText1>
  <ExpiryDate></ExpiryDate>
  <ProductionDate></ProductionDate>
  <ProductionTime></ProductionTime>
  <FreeSlotSelectionFlag></FreeSlotSelectionFlag>
  <CustomerOrderNo></CustomerOrderNo>
  <OrderPositionNo></OrderPositionNo>
  <CountryOfOrigin></CountryOfOrigin>
  <ExternalReference2></ExternalReference2>
  <PosIndex>101</PosIndex>
  <Price1>0</Price1>
  <Price2>0</Price2>
  <Document></Document>
  <ArticleVariantNumber></ArticleVariantNumber>
  <SetType></SetType>
  <DestinyStock></DestinyStock>
  <CurrencyPrice1></CurrencyPrice1>
  <CurrencyPrice2></CurrencyPrice2>
  <PrintLanguage></PrintLanguage>
  <ArticleGroup></ArticleGroup>
  <LatestShippingDate></LatestShippingDate>
  <ExpirationDate></ExpirationDate>
  <ShelfLife></ShelfLife>
  <SupplierArticleNumber></SupplierArticleNumber>
</P02>
<P03>
  <ClientNo>ABCD</ClientNo>
  <OrderNo>10000014</OrderNo>
  <FunctionNo>10</FunctionNo>
  <PositionNo>1</PositionNo>
  <PositionText2></PositionText2>
  <PositionText3></PositionText3>
  <PosIndex>101</PosIndex>
  <EAN></EAN>
</P03>
<PO1>
  <ClientNo>ABCD</ClientNo>
  <OrderNo>10000014</OrderNo>
  <FunctionNo>10</FunctionNo>
  <PositionNo>2</PositionNo>
  <ArticleNo>180030550211</ArticleNo>
  <QuantityLoading></QuantityLoading>
  <LMSM></LMSM>
  <QuantityUnit1>200000</QuantityUnit1>
  <UnitLevel>1</UnitLevel>
  <Obsolete1></Obsolete1>
  <Obsolete2></Obsolete2>
  <NetWeight>640000</NetWeight>
  <GrossWeight>640000</GrossWeight>
  <WeightUnit></WeightUnit>
  <ArticleDamageStatusFlag>0</ArticleDamageStatusFlag>
  <CustomStatusFlag>F</CustomStatusFlag>
  <PickingAdvice></PickingAdvice>
  <StockManagementFlag></StockManagementFlag>
  <LoadingNo></LoadingNo>
  <MeansOfTransportNo></MeansOfTransportNo>
  <StockNo>STANDARD</StockNo>
  <PackageId></PackageId>
  <PosIndex>201</PosIndex>
  <LMSMID></LMSMID>
  <Unit1Factor>1000</Unit1Factor>
  <Volume>35945</Volume>
  <VolumeUnit>CBM</VolumeUnit>
  <LMSMQtyFactor></LMSMQtyFactor>
  <MeasurementUnitLevel></MeasurementUnitLevel>
  <MeasurementName></MeasurementName>
  <MeasurementUnit>1</MeasurementUnit>
  <PercentalExcessDelivery></PercentalExcessDelivery>
  <SmallestIndivisibleUnit></SmallestIndivisibleUnit>
  <AccuracyOfQty></AccuracyOfQty>
  <MTQQty></MTQQty>
  <PackingInstruction></PackingInstruction>
  <PickingListReference></PickingListReference>
</PO1>
<P02>
  <ClientNo>ABCD</ClientNo>
  <OrderNo>10000014</OrderNo>
  <FunctionNo>10</FunctionNo>
  <PositionNo>2</PositionNo>
  <LotNo></LotNo>
  <ArticleNoRecipient></ArticleNoRecipient>
  <ExternalReference></ExternalReference>
  <PositionText1></PositionText1>
  <ExpiryDate></ExpiryDate>
  <ProductionDate></ProductionDate>
  <ProductionTime></ProductionTime>
  <FreeSlotSelectionFlag></FreeSlotSelectionFlag>
  <CustomerOrderNo></CustomerOrderNo>
  <OrderPositionNo></OrderPositionNo>
  <CountryOfOrigin></CountryOfOrigin>
  <ExternalReference2></ExternalReference2>
  <PosIndex>201</PosIndex>
  <Price1>0</Price1>
  <Price2>0</Price2>
  <Document></Document>
  <ArticleVariantNumber></ArticleVariantNumber>
  <SetType></SetType>
  <DestinyStock></DestinyStock>
  <CurrencyPrice1></CurrencyPrice1>
  <CurrencyPrice2></CurrencyPrice2>
  <PrintLanguage></PrintLanguage>
  <ArticleGroup></ArticleGroup>
  <LatestShippingDate></LatestShippingDate>
  <ExpirationDate></ExpirationDate>
  <ShelfLife></ShelfLife>
  <SupplierArticleNumber></SupplierArticleNumber>
</P02>
<P03>
  <ClientNo>ABCD</ClientNo>
  <OrderNo>10000014</OrderNo>
  <FunctionNo>10</FunctionNo>
  <PositionNo>2</PositionNo>
  <PositionText2></PositionText2>
  <PositionText3></PositionText3>
  <PosIndex>201</PosIndex>
  <EAN></EAN>
</P03>

预期输出示例

<Position>
  <PO1>
    <ClientNo>ABCD</ClientNo>
    <OrderNo>10000014</OrderNo>
    <FunctionNo>10</FunctionNo>
    <PositionNo>1</PositionNo>
    <!-- 其余节点省略 -->
  </PO1>
  <P02>
    <ClientNo>ABCD</ClientNo>
    <OrderNo>10000014</OrderNo>
    <FunctionNo>10</FunctionNo>
    <PositionNo>1</PositionNo>
    <!-- 其余节点省略 -->
  </P02>
  <P03>
    <ClientNo>ABCD</ClientNo>
    <OrderNo>10000014</OrderNo>
    <FunctionNo>10</FunctionNo>
    <PositionNo>1</PositionNo>
    <!-- 其余节点省略 -->
  </P03>
</Position>
<Position>
  <PO1>
    <ClientNo>ABCD</ClientNo>
    <OrderNo>10000014</OrderNo>
    <FunctionNo>10</FunctionNo>
    <PositionNo>2</PositionNo>
    <!-- 其余节点省略 -->
  </PO1>
  <P02>
    <ClientNo>ABCD</ClientNo>
    <OrderNo>10000014</OrderNo>
    <FunctionNo>10</FunctionNo>
    <PositionNo>2</PositionNo>
    <!-- 其余节点省略 -->
  </P02>
  <P03>
    <ClientNo>ABCD</ClientNo>
    <OrderNo>10000014</OrderNo>
    <FunctionNo>10</FunctionNo>
    <PositionNo>2</PositionNo>
    <!-- 其余节点省略 -->
  </P03>
</Position>

实现代码(XSLT 2.0)

使用XSLT的分组功能可直接实现该需求,代码如下:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <!-- 匹配根节点,可根据实际的根节点名称调整match规则 -->
    <xsl:template match="/*">
        <xsl:copy>
            <!-- 按PositionNo对所有PO1、P02、P03节点分组 -->
            <xsl:for-each-group select="*[self::PO1 or self::P02 or self::P03]" group-by="PositionNo">
                <!-- 按PositionNo数值升序排序 -->
                <xsl:sort select="xs:integer(current-grouping-key())" order="ascending"/>
                <Position>
                    <!-- 按节点名称排序,保证PO1在前、P02次之、P03最后 -->
                    <xsl:apply-templates select="current-group()">
                        <xsl:sort select="name()" order="ascending"/>
                    </xsl:apply-templates>
                </Position>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

    <!-- 节点原样复制模板 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

注意事项

  • 需使用支持XSLT 2.0的处理器运行上述代码,推荐使用Saxon
  • 若源XML存在其他非PO1/P02/P03的节点需要保留,可在根节点匹配模板中添加对应复制逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:36:00