根据标题值和lineItems使用xsl1.0对XML进行分组

时间:2020-06-09 16:37:51

标签: xslt

我有一个Orders XML输入文件,其中基于匹配的'ref'XML标签和'Shipto'XML标签,应使用多个批处理订单拆分订单。

输入xml:

<Purchase>
    <Order>
        <Header>
        <Ref>13400</Ref>
            <ShipToDetails>
                <ShipTo>AAA</ShipTo>                
            </ShipToDetails>
        </Header>
        <Items>
            <LineItem>800100</LineItem>
        </Items>
    </Order>
    <Order>
        <Header>
        <Ref>13400</Ref>
            <ShipToDetails>
                <ShipTo>BBB</ShipTo>
            </ShipToDetails>            
        </Header>
        <Items>
            <LineItem>800100</LineItem>
        </Items>
    </Order>
    <Order>
        <Header>
        <Ref>13401</Ref>
            <ShipToDetails>
                <ShipTo>CCC</ShipTo>
            </ShipToDetails>            
        </Header>
        <Items>
            <LineItem>800100</LineItem>
        </Items>
    </Order>
        <Order>
        <Header>
        <Ref>13401</Ref>
            <ShipToDetails>
                <ShipTo>CCC</ShipTo>
            </ShipToDetails>            
        </Header>
        <Items>
            <LineItem>800101</LineItem>
        </Items>
    </Order>
</Purchase>

预期输出:

        <Header>
        <Ref>13400</Ref>
            <ShipToDetails>
                <ShipTo>AAA</ShipTo>                
            </ShipToDetails>
        </Header>
        <Items>
            <LineItem>800100</LineItem>
        </Items>
</Batchorder>
<Batchorder>
        <Header>
        <Ref>13400</Ref>
            <ShipToDetails>
                <ShipTo>BBB</ShipTo>                
            </ShipToDetails>
        </Header>
        <Items>
            <LineItem>800100</LineItem>
        </Items>
</Batchorder>
<Batchorder>
        <Header>
        <Ref>13401</Ref>
            <ShipToDetails>
                <ShipTo>CCC</ShipTo>                
            </ShipToDetails>
        </Header>
        <Items>
            <LineItem>800100</LineItem>
        </Items>
        <Items>
            <LineItem>800101</LineItem>
        </Items>
</Batchorder>

我尝试使用以下 XSL1.0 ,但仅获得部分输出

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="Orders" match="Header" use="Ref"/>
    <xsl:template match="Purchase">
            <xsl:for-each select="/Purchase/Order/Header[generate-id() = generate-id(key('Orders',Ref)[1])]">
                    <Batchorder>
                        <header>
                                <OrderType>
                                    <xsl:value-of select="../Ref"/>
                                </OrderType>                                
                                <ShipToDetails>                                 
                                    <ShipTo>
                                        <xsl:value-of select="ShipTo"/>
                                    </ShipTo>                               
                                </ShipToDetails>                                
                            </header>
                            <Items>
                                <LineItem>
                                    <xsl:value-of select="../../Items/LineItem"/>
                                </LineItem>
                            </Items>
                    </Batchorder>
            </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

我正在寻找 xsl1.0 解决方案,我们将为您提供帮助。谢谢!

1 个答案:

答案 0 :(得分:1)

将XSLT代码更改为以下内容。它使用xsl:key的连接字符串将RefShipTo的值组合为索引。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="Orders" match="Order" use="concat(Header/Ref,'_',Header/ShipToDetails/ShipTo)"/>

    <xsl:template match="Purchase">
            <xsl:for-each select="Order[generate-id() = generate-id(key('Orders',concat(Header/Ref,'_',Header/ShipToDetails/ShipTo))[1])]">
                    <Batchorder>
                        <Header>
                            <xsl:copy-of select="Header/Ref | Header/ShipToDetails"/>
                        </Header>
                        <xsl:for-each select="key('Orders',concat(Header/Ref,'_',Header/ShipToDetails/ShipTo))">
                            <Items>
                                <LineItem>
                                    <xsl:value-of select="Items/LineItem"/>
                                </LineItem>
                            </Items>
                        </xsl:for-each>
                    </Batchorder>
            </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

其输出为

<?xml version="1.0"?>
<Batchorder>
    <Header>
        <Ref>13400</Ref>
        <ShipToDetails>
            <ShipTo>AAA</ShipTo>

        </ShipToDetails>
    </Header>
    <Items>
        <LineItem>800100</LineItem>
    </Items>
</Batchorder>
<Batchorder>
    <Header>
        <Ref>13400</Ref>
        <ShipToDetails>
            <ShipTo>BBB</ShipTo>
        </ShipToDetails>
    </Header>
    <Items>
        <LineItem>800100</LineItem>
    </Items>
</Batchorder>
<Batchorder>
    <Header>
        <Ref>13401</Ref>
        <ShipToDetails>
            <ShipTo>CCC</ShipTo>
        </ShipToDetails>
    </Header>
    <Items>
        <LineItem>800100</LineItem>
    </Items>
    <Items>
        <LineItem>800101</LineItem>
    </Items>
</Batchorder>

输出不符合XML-1.0,因为它没有单个根元素。如果需要,可以向模板中添加<xsl:copy>来复制<Purchase>元素。