每个组订单的每个行项目的 XSLT

XSLT for each line items per group order

我是 XSLT 映射的新手 space,我想就我的转换请教一些专家建议。我有一个平面 XML 文件,我希望按装运编号及其相应的行项目和行项目编号对其进行结构化。任何帮助将不胜感激。

这是我的XML

<?xml version="1.0" encoding="UTF-8"?>
<Orders>
<Line_Items>
    <Delivery_Date>2014-03-25T06:00:00.000+1000</Delivery_Date>
    <SAP_Order>518748492</SAP_Order>
    <SAP_Delivery>416065495</SAP_Delivery>
    <SAP_Shipment>2653107 - 6:00 AM - R/L</SAP_Shipment>
    <External_ID>BRBC69J250314</External_ID>
    <Time_Slot>1899/12/31</Time_Slot>
    <Customer_Order>R-41542740A</Customer_Order>
    <Outlet_Number>4202629</Outlet_Number>
    <Material>951586</Material>
    <Material_Description>1.25 PET X12 MT FRK LSPK</Material_Description>
    <Order_Qty>48</Order_Qty>
    <Pallets>22</Pallets>
    <Gross_Weight>19329.08</Gross_Weight>
    <Dispatcher_Message>AWH</Dispatcher_Message>
    <Driver_Message>R/L - 1R4228V</Driver_Message>
    <Pallet_Count>22</Pallet_Count>
    <Shipping_Point>1043</Shipping_Point>
</Line_Items>
<Line_Items>
    <Delivery_Date>2014-03-25T06:00:00.000+1000</Delivery_Date>
    <SAP_Order>518748492</SAP_Order>
    <SAP_Delivery>416065495</SAP_Delivery>
    <SAP_Shipment>2653107 - 6:00 AM - R/L</SAP_Shipment>
    <External_ID>BRBC69J250314</External_ID>
    <Time_Slot>1899/12/31</Time_Slot>
    <Customer_Order>R-41542740A</Customer_Order>
    <Outlet_Number>4202629</Outlet_Number>
    <Material>950064</Material>
    <Material_Description>1.25 PET X12 DIET COKE</Material_Description>
    <Order_Qty>192</Order_Qty>
    <Pallets>22</Pallets>
    <Gross_Weight>19329.08</Gross_Weight>
    <Dispatcher_Message>AWH</Dispatcher_Message>
    <Driver_Message>R/L - 1R4228V</Driver_Message>
    <Pallet_Count>22</Pallet_Count>
    <Shipping_Point>1043</Shipping_Point>
</Line_Items>
<Line_Items>
    <Delivery_Date>2014-03-25T09:00:00.000+1000</Delivery_Date>
    <SAP_Order>518748492</SAP_Order>
    <SAP_Delivery>416065496</SAP_Delivery>
    <SAP_Shipment>2653108 - 9:00 AM - R/L</SAP_Shipment>
    <External_ID>BRBC70J250314</External_ID>
    <Time_Slot>1899/12/31</Time_Slot>
    <Customer_Order>R-41542740A</Customer_Order>
    <Outlet_Number>4202629</Outlet_Number>
    <Material>950055</Material>
    <Material_Description>2.0 PET X8 COCA-COLA</Material_Description>
    <Order_Qty>1056</Order_Qty>
    <Pallets>22</Pallets>
    <Gross_Weight>19294.88</Gross_Weight>
    <Dispatcher_Message>AWH</Dispatcher_Message>
    <Driver_Message>R/L - 1R4228C</Driver_Message>
    <Pallet_Count>22</Pallet_Count>
    <Shipping_Point>1043</Shipping_Point>
</Line_Items>
</Orders>

我希望这是目标 XML

<?xml version="1.0"?>       
<WhsDockets>    
    <WhsDocket>
        <Identifier>
            <Reference>2653107 - 6:00 AM - R/L</Reference>
            <DocketType>ORD</DocketType>
        </Identifier>
        <DocketDetail>
            <WarehouseCode>ROC</WarehouseCode>
        </DocketDetail>
        <DocketLines>
            <DocketLine>
                <LineNumber>1</LineNumber>
                <Product>951586</Product>
                <Description>1.25 PET X12 MT FRK LSPK</Description>
                <QuantityFromClientOrder>48</QuantityFromClientOrder>
                <ProductUQ>CAS</ProductUQ>
            </DocketLine>
            <DocketLine>
                <LineNumber>2</LineNumber>
                <Product>950064</Product>
                <Description>1.25 PET X12 DIET COKE</Description>
                <QuantityFromClientOrder>192</QuantityFromClientOrder>
                <ProductUQ>CAS</ProductUQ>
            </DocketLine>
        </DocketLines>
    </WhsDocket>
    <WhsDocket>
        <Identifier>
            <Reference>2653108 - 9:00 AM - R/L</Reference>
            <DocketType>ORD</DocketType>
        </Identifier>
        <DocketDetail>
            <WarehouseCode>ROC</WarehouseCode>
        </DocketDetail>
        <DocketLines>
            <DocketLine>
                <LineNumber>1</LineNumber>
                <Product>950055</Product>
                <Description>2.0 PET X8 COCA-COLA</Description>
                <QuantityFromClientOrder>1056</QuantityFromClientOrder>
                <ProductUQ>CAS</ProductUQ>
            </DocketLine>
        </DocketLines>
    </WhsDocket>
</WhsDockets>

但我需要在相同的参考编号下有相应的行项目,并添加一个行项目编号来区分它,但这就是我得到的。

<WhsDocket>
            <Identifier>
                <Reference>2653107 - 6:00 AM - R/L</Reference>
                <DocketType>ORD</DocketType>
            </Identifier>
            <DocketDetail>
                <WarehouseCode>ROC</WarehouseCode>
            </DocketDetail>
            <DocketLines>
                <DocketLine>
                    <Product>951586</Product>
                    <Description>1.25 PET X12 MT FRK LSPK</Description>
                    <QuantityFromClientOrder>48</QuantityFromClientOrder>
                    <ProductUQ>CAS</ProductUQ>
                </DocketLine>
            </DocketLines>
        </WhsDocket>
        <WhsDocket>
            <Identifier>
                <Reference>2653107 - 6:00 AM - R/L</Reference>
                <DocketType>ORD</DocketType>
            </Identifier>
            <DocketDetail>
                <WarehouseCode>ROC</WarehouseCode>
            </DocketDetail>
            <DocketLines>
                <DocketLine>
                    <Product>950064</Product>
                    <Description>1.25 PET X12 DIET COKE</Description>
                    <QuantityFromClientOrder>192</QuantityFromClientOrder>
                    <ProductUQ>CAS</ProductUQ>
                </DocketLine>
            </DocketLines>
        </WhsDocket>
        <WhsDocket>
            <Identifier>
                <Reference>2653108 - 9:00 AM - R/L</Reference>
                <DocketType>ORD</DocketType>
            </Identifier>
            <DocketDetail>
                <WarehouseCode>ROC</WarehouseCode>
            </DocketDetail>
            <DocketLines>
                <DocketLine>
                    <Product>950055</Product>
                    <Description>2.0 PET X8 COCA-COLA</Description>
                    <QuantityFromClientOrder>1056</QuantityFromClientOrder>
                    <ProductUQ>CAS</ProductUQ>
                </DocketLine>
            </DocketLines>
        </WhsDocket>
    </WhsDockets>

这是我创建的 XSLT。

<?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <XmlInterchange xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.edi.com.au/EnterpriseService/">
        <Payload>
            <WhsDockets>
                <xsl:for-each select="Orders/Line_Items">
                    <WhsDocket>
                        <Identifier>
                            <Reference>
                                <xsl:value-of select="SAP_Shipment"/>
                            </Reference>
                            <DocketType>ORD</DocketType>
                        </Identifier>
                        <DocketDetail>
                            <WarehouseCode>ROC</WarehouseCode>
                        </DocketDetail>
                        <DocketLines>
                            <DocketLine>
                                <Product>
                                    <xsl:value-of select="Material"/>
                                </Product>
                                <Description>
                                    <xsl:value-of select="Material_Description"/>
                                </Description>
                                <QuantityFromClientOrder>
                                    <xsl:value-of select="Order_Qty"/>
                                </QuantityFromClientOrder>
                                <ProductUQ>CAS</ProductUQ>
                            </DocketLine>
                        </DocketLines>
                    </WhsDocket>
                </xsl:for-each>
            </WhsDockets>
        </Payload>
    </XmlInterchange>
</xsl:template>
</xsl:stylesheet>

这是一个 "grouping" 问题,在 XSLT 1.0 中,通常使用的技术称为 Muenchian Grouping

首先你定义一个键来代表组。在您的情况下,您按 SAP_Shipment 元素对 Line_Items 元素进行分组,因此您可以像这样定义一个键:

<xsl:key name="items" match="Line_Items" use="SAP_Shipment" />

然后您 select 键中最先出现的 Line_Items 元素为其给定值 SAP_Shipment。这代表每组的开始

<xsl:for-each select="Line_Items[generate-id() = generate-id(key('items',SAP_Shipment)[1])]">

然后您可以使用键获取组中的所有项目(包括第一个项目):

<xsl:apply-templates select="key('items',SAP_Shipment)" />

初学者试试这个 XSLT

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

    <xsl:key name="items" match="Line_Items" use="SAP_Shipment" />

    <xsl:template match="Orders">
        <WhsDockets>
            <xsl:for-each select="Line_Items[generate-id() = generate-id(key('items',SAP_Shipment)[1])]">
                <WhsDocket>
                    <Identifier><xsl:value-of select="SAP_Shipment" /></Identifier>
                    <DocketLines>
                        <xsl:apply-templates select="key('items',SAP_Shipment)" />
                    </DocketLines>
                </WhsDocket>
            </xsl:for-each>
        </WhsDockets>
    </xsl:template>

    <xsl:template match="Line_Items">
        <DocketLine>
            <LineNumber><xsl:value-of select="position()" /></LineNumber>
            <Product><xsl:value-of select="Material" /></Product>        
        </DocketLine>
    </xsl:template>
</xsl:stylesheet>

注意:如果您能够使用 XSLT 2.0,那么您可以使用 xsl:for-each-group 结构。参见 http://www.xml.com/lpt/a/1314