0

Please can someone assist with the creation of keys in order to correctly group an xml file using xsl? Using the received xml I need to be able to bring the data into my ERP system whereby a new purchase order is created for each new supplier as well as each destination warehouse. In other words from the below I need a purchase order created for LIY0001 and going to A4 (this must include all lines relevant to both the supplier and warehouse). Similarly a new purchase order needs to be created for WOR0001 going to A4 and another for WOR0001 going to A5 (again with all lines relevant to both keys going to the necessary purchase order grouping as such). For the sample below than there should be 3 separate purchase orders created.

Here is a sample of the xml:

<rows>
<row>
<SUPPLIER>LIY0001</SUPPLIER>
<DESTWHS>A4</DESTWHS>
<RELEASE_DATE>2013-02-14</RELEASE_DATE>
<DUE_DATE>2013-05-13</DUE_DATE>
<ITEM>5021616</ITEM>
<QTY>528</QTY>
<LINE_ITEM_NO>1</LINE_ITEM_NO>
<CUST_PO_NO>LIY0001-2013-02-14</CUST_PO_NO>
<PURCHASEPRICE>5.25</PURCHASEPRICE>
</row>
<row>
<SUPPLIER>LIY0001</SUPPLIER>
<DESTWHS>A4</DESTWHS>
<RELEASE_DATE>2013-02-14</RELEASE_DATE>
<DUE_DATE>2013-05-13</DUE_DATE>
<ITEM>5021816</ITEM>
<QTY>222</QTY>
<LINE_ITEM_NO>2</LINE_ITEM_NO>
<CUST_PO_NO>LIY0001-2013-02-14</CUST_PO_NO>
<PURCHASEPRICE>5.90</PURCHASEPRICE>
</row>
<row>
<SUPPLIER>WOR0001</SUPPLIER>
<DESTWHS>A4</DESTWHS>
<RELEASE_DATE>2013-02-14</RELEASE_DATE>
<DUE_DATE>2013-05-13</DUE_DATE>
<ITEM>650616</ITEM>
<QTY>129</QTY>
<LINE_ITEM_NO>9</LINE_ITEM_NO>
<CUST_PO_NO>WOR0001-2013-02-14</CUST_PO_NO>
<PURCHASEPRICE>4.46</PURCHASEPRICE>
</row>
<row>
<row>
<SUPPLIER>WOR0001</SUPPLIER>
<DESTWHS>A5</DESTWHS>
<RELEASE_DATE>2013-02-14</RELEASE_DATE>
<DUE_DATE>2013-05-13</DUE_DATE>
<ITEM>650610</ITEM>
<QTY>129</QTY>
<LINE_ITEM_NO>1</LINE_ITEM_NO>
<CUST_PO_NO>WOR0001-2013-02-14</CUST_PO_NO>
<PURCHASEPRICE>3.5</PURCHASEPRICE>
</row>
<row>
</rows>

Here is the translation file I have created:

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="Windows-1252" omit-xml-declaration="yes" />
<xsl:template match="/">
<PostPurchaseOrders>
    <Orders>
      <OrderHeader> 
      <xsl:for-each select = "rows/row">
      <CustomerPoNumber><xsl:value-of select="CUST_PO_NO"/></CustomerPoNumber> 
      <Supplier><xsl:value-of select="SUPPLIER"/></Supplier>
          <OrderDate><xsl:value-of select="RELEASE_DATE"/></OrderDate>
          <DueDate><xsl:value-of select="DUE_DATE"/></DueDate>
         <Warehouse><xsl:value-of select="DESTWHS"/></Warehouse>
     </xsl:for-each>
     </OrderHeader> 
      <OrderDetails>
     <xsl:for-each select = "rows/row">
       <StockLine>
         <PurchaseOrderLine><xsl:value-of select="LINE_ITEM_NO"/></PurchaseOrderLine>
            <StockCode><xsl:value-of select="ITEM"/></StockCode>
            <Warehouse><xsl:value-of select="DESTWHS"/></Warehouse>
           <OrderQty><xsl:value-of select="QTY"/></OrderQty>
           <Price><xsl:value-of select="PURCHASEPRICE"/></Price>
          </StockLine>
         </xsl:for-each>
       </OrderDetails>       
       </Orders>
<PostPurchaseOrders>
</xsl:template>
</xsl:stylesheet>   

Here is what I need the xml transformed into for our ERP system:

<PostPurchaseOrder>
<Orders>
    <OrderHeader>
        <Supplier>LIY0001</Supplier>
        <CustomerPoNumber>example po</CustomerPoNumber>
        <OrderDate>2013-02-03</OrderDate>
        <Warehouse>A1</Warehouse>
    </OrderHeader>
    <OrderDetails>
        <StockLine>
            <PurchaseOrderLine>1</PurchaseOrderLine>
            <StockCode>12022</StockCode>
            <OrderQty>10</OrderQty>
        </StockLine>
        <StockLine>
            <PurchaseOrderLine>2</PurchaseOrderLine>
            <StockCode>15014</StockCode>
            <OrderQty>15</OrderQty>
        </StockLine>
    </OrderDetails>
</Orders>
</PostPurchaseOrders>

Any help as to how I can change my translation file to group for the 2 keys so that many lines are brought into one purchase order for each supplier as well as per destination warehouse would be greatly appreciated.

Thanks

4

2 に答える 2

1

XSLTとサンプル出力の間にいくつかの矛盾があるため、サンプル出力をエミュレートします。これにより、探しているグループ化が実現します。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:key name="kOrder" match="row" use="concat(SUPPLIER, '+', DESTWHS)"/>

  <xsl:template match="/*">
    <PostPurchaseOrder>
      <xsl:apply-templates
        select="row[generate-id() = 
                    generate-id(key('kOrder', concat(SUPPLIER, '+', DESTWHS))[1])]"
        mode="group"/>
    </PostPurchaseOrder>
  </xsl:template>

  <xsl:template match="row" mode="group">
    <OrderHeader>
      <Supplier>
        <xsl:value-of select="SUPPLIER" />
      </Supplier>
      <CustomerPoNumber>
        <xsl:value-of select="CUST_PO_NO" />
      </CustomerPoNumber>
      <OrderDate>
        <xsl:value-of select="RELEASE_DATE" />
      </OrderDate>
      <Warehouse>
        <xsl:value-of select="DESTWHS" />
      </Warehouse>
    </OrderHeader>
    <OrderDetails>
      <xsl:apply-templates select="key('kOrder', concat(SUPPLIER, '+', DESTWHS))" />
    </OrderDetails>
  </xsl:template>

  <xsl:template match="row">
    <StockLine>
      <PurchaseOrderLine>
        <xsl:value-of select="LINE_ITEM_NO" />
      </PurchaseOrderLine>
      <StockCode>
        <xsl:value-of select="ITEM" />
      </StockCode>
      <OrderQty>
        <xsl:value-of select="QTY" />
      </OrderQty>
    </StockLine>
  </xsl:template>

</xsl:stylesheet>

サンプル入力で実行すると、次のようになります。

<PostPurchaseOrder>
  <OrderHeader>
    <Supplier>LIY0001</Supplier>
    <CustomerPoNumber>LIY0001-2013-02-14</CustomerPoNumber>
    <OrderDate>2013-02-14</OrderDate>
    <Warehouse>A4</Warehouse>
  </OrderHeader>
  <OrderDetails>
    <StockLine>
      <PurchaseOrderLine>1</PurchaseOrderLine>
      <StockCode>5021616</StockCode>
      <OrderQty>528</OrderQty>
    </StockLine>
    <StockLine>
      <PurchaseOrderLine>2</PurchaseOrderLine>
      <StockCode>5021816</StockCode>
      <OrderQty>222</OrderQty>
    </StockLine>
  </OrderDetails>
  <OrderHeader>
    <Supplier>WOR0001</Supplier>
    <CustomerPoNumber>WOR0001-2013-02-14</CustomerPoNumber>
    <OrderDate>2013-02-14</OrderDate>
    <Warehouse>A4</Warehouse>
  </OrderHeader>
  <OrderDetails>
    <StockLine>
      <PurchaseOrderLine>9</PurchaseOrderLine>
      <StockCode>650616</StockCode>
      <OrderQty>129</OrderQty>
    </StockLine>
  </OrderDetails>
  <OrderHeader>
    <Supplier>WOR0001</Supplier>
    <CustomerPoNumber>WOR0001-2013-02-14</CustomerPoNumber>
    <OrderDate>2013-02-14</OrderDate>
    <Warehouse>A5</Warehouse>
  </OrderHeader>
  <OrderDetails>
    <StockLine>
      <PurchaseOrderLine>1</PurchaseOrderLine>
      <StockCode>650610</StockCode>
      <OrderQty>129</OrderQty>
    </StockLine>
  </OrderDetails>
</PostPurchaseOrder>
于 2013-02-19T21:30:11.593 に答える
0

これは、XSLT2.0で次のように実現できます。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="xs fn">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="rows">
        <PostPurchaseOrder>
            <!-- Generate Orders with OrderHeader -->
            <xsl:for-each-group select="row" group-by="SUPPLIER">
                <Orders>
                    <OrderHeader>
                        <Supplier><xsl:value-of select="SUPPLIER" /></Supplier>
                        <CustomerPoNumber><xsl:value-of select="CUST_PO_NO" /></CustomerPoNumber>
                        <OrderDate><xsl:value-of select="RELEASE_DATE" /></OrderDate>
                        <Warehouse><xsl:value-of select="DESTWHS" /></Warehouse>
                    </OrderHeader>
                    <!-- Generate OrderDetails -->
                    <OrderDetails>
                        <!-- Generate StockLine -->
                        <xsl:for-each select="current-group()">
                            <StockLine>
                                <PurchaseOrderLine><xsl:value-of select="LINE_ITEM_NO" /></PurchaseOrderLine>
                                <StockCode><xsl:value-of select="ITEM" /></StockCode>
                                <OrderQty><xsl:value-of select="QTY" /></OrderQty>
                            </StockLine>
                        </xsl:for-each>
                    </OrderDetails>
                </Orders>
            </xsl:for-each-group>
        </PostPurchaseOrder>
    </xsl:template>
</xsl:stylesheet>
于 2013-02-19T21:42:06.453 に答える