根据密钥对来自不同节点的节点进行分组

时间:2019-08-26 14:30:15

标签: xml xslt

**将装箱清单按发票编号作为ASN节点的键**     -------------------------------------------------- -------- 我的输入

<?xml version="1.0" encoding="UTF-8"?>
<SupplierInvoiceProcessing>
<Invoice>
<Header>
<InvoiceNumber>1</InvoiceNumber>
<ETA>1</ETA>
</Header>
<Details>
<InvoiceNumber>1</InvoiceNumber>
<OrderNumber>a1</OrderNumber>
</Details>
<Details> 
<InvoiceNumber>1</InvoiceNumber>
<OrderNumber>a2</OrderNumber>
</Details>
</Invoice>
<Invoice>
<Header>
<InvoiceNumber>2</InvoiceNumber>
<ETA>2</ETA>
</Header>
<Details>
<InvoiceNumber>2</InvoiceNumber>
<OrderNumber>b1</OrderNumber>
</Details>
<Details>
<InvoiceNumber>2</InvoiceNumber>
<OrderNumber>b2</OrderNumber>
</Details>
<PackingList>
<IN>3</IN>
<FOBTotalNoOfCartons>c3</FOBTotalNoOfCartons>
</PackingList>
<PackingList>
<IN>1</IN>
<FOBTotalNoOfCartons>a1</FOBTotalNoOfCartons>
</PackingList>
</Invoice>
<Invoice>
<Header>
<InvoiceNumber>3</InvoiceNumber>
<ETA>1</ETA>
</Header>
<Details>
<InvoiceNumber>3</InvoiceNumber>
<OrderNumber>c1</OrderNumber>
</Details>
<Details>
<InvoiceNumber>3</InvoiceNumber>
<OrderNumber>c2</OrderNumber>
</Details>
</Invoice>
<Invoice>
<Header>
<InvoiceNumber>4</InvoiceNumber>
<ETA>2</ETA>
</Header>
<Details>
<InvoiceNumber>4</InvoiceNumber>
<OrderNumber>d1</OrderNumber>
</Details>
<Details>
<InvoiceNumber>4</InvoiceNumber>
<OrderNumber>d2</OrderNumber>
</Details>
<PackingList>
<IN>4</IN>
<FOBTotalNoOfCartons>d4</FOBTotalNoOfCartons>
</PackingList>
<PackingList>
<IN>2</IN>
<FOBTotalNoOfCartons>b2</FOBTotalNoOfCartons>
</PackingList>
</Invoice>
</SupplierInvoiceProcessing>

XSLT 2.0代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:ns0="urn:Shiseido.com:interface:SHISEIDOJAPAN" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<ns0:SupplierAdvanceShipmentNotification_XSL>
<xsl:for-each-group select="ns0:SupplierInvoiceProcessing/Invoice" group-by="(Header/InvoiceNumber,IN)">
<AdvanceShipmentNotifications>
<ASN>
<Header>
<xsl:value-of select="Invoice/Header"/>
<InvoiceNumber><xsl:value-of select="Header/InvoiceNumber"/></InvoiceNumber>
<ETA><xsl:value-of select="Header/ETA"/></ETA>
<xsl:for-each-group select="//PackingList" group-by="concat(InvoiceNumber,IN)">
<PackingList>
<InvoiceNumber><xsl:value-of select="InvoiceNumber"/></InvoiceNumber>
<Cart><xsl:value-of select="current-group()/FOBTotalNoOfCartons"/></Cart>
</PackingList></xsl:for-each-group>
</Header>                   
<xsl:for-each select="current-group()/Details">
<Details>
<xsl:value-of select="Details"/>
<InvoiceNumber><xsl:value-of select="InvoiceNumber"/></InvoiceNumber>
<OrderNumber><xsl:value-of select="OrderNumber"/></OrderNumber>
</Details>
</xsl:for-each>                                                                 
</ASN>
</AdvanceShipmentNotifications>
</xsl:for-each-group>
</ns0:SupplierAdvanceShipmentNotification_XSL>
</xsl:template>
</xsl:stylesheet>

预期产量

<?xml version="1.0" encoding="UTF-8"?>
<SupplierAdvanceShipmentNotification_XSL>
<AdvanceShipmentNotifications>
<ASN>
<Header>
<InvoiceNumber>1</InvoiceNumber>
<ETA>1</ETA>
</Header>
<Details>
<InvoiceNumber>1</InvoiceNumber>
<OrderNumber>a1</OrderNumber>
</Details>
<Details>
<InvoiceNumber>1</InvoiceNumber>
<OrderNumber>a2</OrderNumber>
</Details>
<PackingList>
<InvoiceNumber>1</InvoiceNumber>
<FOBTotalNoOfCartons>a1</FOBTotalNoOfCartons>
</PackingList>
</ASN>
<ASN>
<Header>
<InvoiceNumber>2</InvoiceNumber>
<ETA>2</ETA>
</Header>
<Details>
<InvoiceNumber>2</InvoiceNumber>
<OrderNumber>b1</OrderNumber>
</Details>
<Details>
<InvoiceNumber>2</InvoiceNumber>
<OrderNumber>b2</OrderNumber>
</Details>
<PackingList>
<InvoiceNumber>2</InvoiceNumber>
<FOBTotalNoOfCartons>b2</FOBTotalNoOfCartons>
</PackingList>
</ASN>
<ASN>
<Header>
<InvoiceNumber>3</InvoiceNumber>
<ETA>1</ETA>
</Header>
<Details>
<InvoiceNumber>3</InvoiceNumber>
<OrderNumber>c1</OrderNumber>
</Details>
<Details>
<InvoiceNumber>3</InvoiceNumber>
<OrderNumber>c2</OrderNumber>
</Details>
<PackingList>
<InvoiceNumber>3</InvoiceNumber>
<FOBTotalNoOfCartons>c3</FOBTotalNoOfCartons>
</PackingList>
</ASN>
<ASN>
<Header>
<InvoiceNumber>4</InvoiceNumber>
<ETA>2</ETA>
</Header>
<Details>
<InvoiceNumber>4</InvoiceNumber>
<OrderNumber>d1</OrderNumber>
</Details>
<Details>
<InvoiceNumber>4</InvoiceNumber>
<OrderNumber>d2</OrderNumber>
</Details>
<PackingList>
<InvoiceNumber>4</InvoiceNumber>
<FOBTotalNoOfCartons>d4</FOBTotalNoOfCartons>
</PackingList>
</ASN>
</AdvanceShipmentNotifications>
</SupplierAdvanceShipmentNotification_XSL>

1 个答案:

答案 0 :(得分:0)

我认为您基本上想使用Invoice的子元素:

<xsl:template match="/*">
    <xsl:for-each-group select="Invoice/(Header, Details, PackingList)" group-by="InvoiceNumber, IN">
        <ASN>
            <xsl:copy-of select="current-group()"/>
        </ASN>
    </xsl:for-each-group>
</xsl:template>

https://xsltfiddle.liberty-development.net/ejivdGC处给出

<ASN>
   <Header>
         <InvoiceNumber>1</InvoiceNumber>
         <ETA>1</ETA>
      </Header>
   <Details>
         <InvoiceNumber>1</InvoiceNumber>
         <OrderNumber>a1</OrderNumber>
      </Details>
   <Details>
         <InvoiceNumber>1</InvoiceNumber>
         <OrderNumber>a2</OrderNumber>
      </Details>
   <PackingList>
         <IN>1</IN>
         <FOBTotalNoOfCartons>a1</FOBTotalNoOfCartons>
      </PackingList>
</ASN>
<ASN>
   <Header>
         <InvoiceNumber>2</InvoiceNumber>
         <ETA>2</ETA>
      </Header>
   <Details>
         <InvoiceNumber>2</InvoiceNumber>
         <OrderNumber>b1</OrderNumber>
      </Details>
   <Details>
         <InvoiceNumber>2</InvoiceNumber>
         <OrderNumber>b2</OrderNumber>
      </Details>
   <PackingList>
         <IN>2</IN>
         <FOBTotalNoOfCartons>b2</FOBTotalNoOfCartons>
      </PackingList>
</ASN>
<ASN>
   <PackingList>
         <IN>3</IN>
         <FOBTotalNoOfCartons>c3</FOBTotalNoOfCartons>
      </PackingList>
   <Header>
         <InvoiceNumber>3</InvoiceNumber>
         <ETA>1</ETA>
      </Header>
   <Details>
         <InvoiceNumber>3</InvoiceNumber>
         <OrderNumber>c1</OrderNumber>
      </Details>
   <Details>
         <InvoiceNumber>3</InvoiceNumber>
         <OrderNumber>c2</OrderNumber>
      </Details>
</ASN>
<ASN>
   <Header>
         <InvoiceNumber>4</InvoiceNumber>
         <ETA>2</ETA>
      </Header>
   <Details>
         <InvoiceNumber>4</InvoiceNumber>
         <OrderNumber>d1</OrderNumber>
      </Details>
   <Details>
         <InvoiceNumber>4</InvoiceNumber>
         <OrderNumber>d2</OrderNumber>
      </Details>
   <PackingList>
         <IN>4</IN>
         <FOBTotalNoOfCartons>d4</FOBTotalNoOfCartons>
      </PackingList>
</ASN>

因此,如果您添加一些包装器元素

<xsl:template match="/*">
    <SupplierAdvanceShipmentNotification_XSL>
        <AdvanceShipmentNotifications>
            <xsl:for-each-group select="Invoice/(Header, Details, PackingList)" group-by="InvoiceNumber, IN">
                <ASN>
                    <xsl:copy-of select="current-group()"/>
                </ASN>
            </xsl:for-each-group>                
        </AdvanceShipmentNotifications>
    </SupplierAdvanceShipmentNotification_XSL>
</xsl:template>

就像在https://xsltfiddle.liberty-development.net/ejivdGC/1中所做的那样,那么您就可以在对元素进行分组方面获得理想的结果,我想您可以添加

  <xsl:template match="/*">
        <SupplierAdvanceShipmentNotification_XSL>
            <AdvanceShipmentNotifications>
                <xsl:for-each-group select="Invoice/(Header, Details, PackingList)" group-by="InvoiceNumber, IN">
                    <ASN>
                        <xsl:copy-of select="current-group()[self::Header], current-group()[self::Details], current-group()[self::PackingList]"/>
                    </ASN>
                </xsl:for-each-group>                
            </AdvanceShipmentNotifications>
        </SupplierAdvanceShipmentNotification_XSL>
    </xsl:template>

以获取正确的输出顺序:https://xsltfiddle.liberty-development.net/ejivdGC/2