2017-04-17 94 views
0

我有一個給定的XML,我想在新的XML中轉換它,並希望基於狀態和orderId聚合節點。基於新家長條件下的聚合節點

<?xml version="1.0" encoding="utf-8"?> 
<OrderStatusUpdate> 
    <OrderStatusEvents> 
     <OrderStatusEvent> 
      <StoreCode>store1</StoreCode> 
      <OrderId>Order1</OrderId> 
      <ItemId>Item1</ItemId> 
      <OrderStatusDetails> 
      <OrderStatusDetail> 
       <OrderStatusEventTimeStamp>2017-03-19 03:37:05</OrderStatusEventTimeStamp> 
       <StatusName>Cancelled</StatusName> 
      </OrderStatusDetail> 
      </OrderStatusDetails> 
     </OrderStatusEvent> 
     <OrderStatusEvent> 
      <StoreCode>Store1</StoreCode> 
      <OrderId>Order1</OrderId> 
      <ItemId>Item2</ItemId> 
      <OrderStatusDetails> 
      <OrderStatusDetail> 
       <OrderStatusEventTimeStamp>2017-03-19 03:48:35</OrderStatusEventTimeStamp> 
       <StatusName>Cancelled</StatusName> 
      </OrderStatusDetail> 
      </OrderStatusDetails> 
     </OrderStatusEvent> 
     <OrderStatusEvent> 
      <StoreCode>Store1</StoreCode> 
      <OrderId>Order1</OrderId> 
      <ItemId>Item3</ItemId> 
      <OrderStatusDetails> 
      <OrderStatusDetail> 
       <OrderStatusEventTimeStamp>2017-03-19 03:48:35</OrderStatusEventTimeStamp> 
       <StatusName>Shipped</StatusName> 
      </OrderStatusDetail> 
      </OrderStatusDetails> 
     </OrderStatusEvent> 
     <OrderStatusEvent> 
     <StoreCode>Store1</StoreCode> 
     <OrderId>Order2</OrderId> 
     <ItemId>Item1</ItemId> 
     <OrderStatusDetails> 
     <OrderStatusDetail> 
      <OrderStatusEventTimeStamp>2017-03-19 03:48:35</OrderStatusEventTimeStamp> 
      <StatusName>Cancelled</StatusName> 
     </OrderStatusDetail> 
     </OrderStatusDetails> 
    </OrderStatusEvent> 
    </OrderStatusEvents> 
</OrderStatusUpdate> 

而我想要一個這樣的輸出。這裏我根據狀態和orderId對元素進行分組。

 <Orders> 
    <group name="CANCELLED"> 
     <STATUS ID="CANCELLED" DESCRIPTION="Goods Cancelled"> 
       <ORDER ID="Order1"> 
        <ORDER_ITEM item="item1" /> 
        <ORDER_ITEM item="item2" /> 
       </ORDER> 
     </STATUS> 
     <STATUS ID="CANCELLED" DESCRIPTION="Goods Cancelled"> 
       <ORDER ID="Order2"> 
        <ORDER_ITEM item="item1" /> 
       </ORDER> 
     </STATUS> 
    </group> 
    <group name="SHIPPED"> 
     <STATUS ID="SHIPPED" DESCRIPTION="Goods SHIPPED"> 
       <ORDER ID="Order1"> 
        <ORDER_ITEM item="item3" /> 
       </ORDER> 
     </STATUS> 
    <group> 
</Orders> 

我使用下面的xslt,它工作正常。有沒有什麼辦法可以改善這一點。

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes" /> 

    <xsl:template match="OrderStatusUpdate/OrderStatusEvents"> 
     <Orders> 
      <xsl:for-each-group select="OrderStatusEvent" group-by="OrderStatusDetails/OrderStatusDetail/StatusName"> 
       <xsl:variable name="group-name" select="current-grouping-key()" /> 
       <group name="{current-grouping-key()}"> 
        <xsl:for-each-group select="current-group()" group-by="OrderId"> 
         <xsl:variable name="order-id" select="current-grouping-key()" /> 
         <xsl:element name="STATUS"> 
          <xsl:attribute name="ID"><xsl:value-of select="$group-name" /></xsl:attribute> 
          <xsl:attribute name="DESCRIPTION">Goods <xsl:value-of select="$group-name" /></xsl:attribute> 
           <xsl:element name="ORDER"> 
            <xsl:attribute name="ID"><xsl:value-of select="$order-id" /></xsl:attribute> 
            <xsl:for-each select="current-group()"> 
             <xsl:if test="$group-name = 'Shipped'"> 
              <xsl:call-template name="Shipped"> 
               <xsl:with-param name="nodes"> 
                <xsl:copy-of select="." /> 
               </xsl:with-param> 
              </xsl:call-template> 
             </xsl:if> 
             <xsl:if test="$group-name = 'Cancelled'"> 
              <xsl:call-template name="Cancelled"> 
               <xsl:with-param name="nodes"> 
                <xsl:copy-of select="." /> 
               </xsl:with-param> 
              </xsl:call-template> 
             </xsl:if> 
            </xsl:for-each> 
           </xsl:element> 
         </xsl:element> 
        </xsl:for-each-group> 
       </group> 
      </xsl:for-each-group> 
     </Orders> 
    </xsl:template> 
    <xsl:template name="Shipped"> 
     <xsl:param name="nodes"> 
     </xsl:param> 
     <xsl:element name="ORDER_ITEM"> 
      <xsl:attribute name="ID"><xsl:value-of select="$nodes/OrderStatusEvent/ItemId" /></xsl:attribute> 
     </xsl:element> 
    </xsl:template> 
    <xsl:template name="Cancelled"> 
     <xsl:param name="nodes"></xsl:param> 
     <xsl:element name="ORDER_ITEM"> 
      <xsl:attribute name="ID"><xsl:value-of select="$nodes/OrderStatusEvent/ItemId" /></xsl:attribute> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 
+0

嘛,你知道的,你說「的基礎上的地位和訂單ID在這裏,我將這些元素分組」什麼做這樣簡單地使用'的xsl:for-每個-group'作爲例證https://www.w3.org/TR/xslt20/#grouping-examples。 –

+0

我可以分組但無法添加父元素。我試圖爲每個組的狀態,然後在此下我使用另一個for-each-group for orderId,但無法爲類似的orderId項目創建一個父元素 –

+0

請編輯您的問題,顯示當前的XSLT嵌套'xsl:for - 每個組 - 你有,與它創造的輸出,那麼我相信我們可以修復它。 –

回答

1

它更容易使用文字結果元素和屬性值模板,只要你不需要計算元素或屬性在運行時的名字,我不認爲你需要兩個模板和呼叫-template,只要使用

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    version="2.0"> 

    <xsl:output omit-xml-declaration="yes" indent="yes" /> 

    <xsl:template match="OrderStatusUpdate/OrderStatusEvents"> 
     <Orders> 
      <xsl:for-each-group select="OrderStatusEvent" group-by="OrderStatusDetails/OrderStatusDetail/StatusName"> 
       <xsl:variable name="group-name" select="current-grouping-key()" /> 
       <group name="{current-grouping-key()}"> 
        <xsl:for-each-group select="current-group()" group-by="OrderId"> 
         <xsl:variable name="order-id" select="current-grouping-key()" /> 
         <STATUS ID="{$group-name}" DESCRIPTION="Goods {$group-name}"> 
          <ORDER ID="{$order-id}"> 
           <xsl:apply-templates select="current-group()"/> 
          </ORDER> 
         </STATUS> 
        </xsl:for-each-group> 
       </group> 
      </xsl:for-each-group> 
     </Orders> 
    </xsl:template> 

    <xsl:template match="OrderStatusEvent"> 
     <ORDER_ITEM ID="{ItemId}"/> 
    </xsl:template> 

</xsl:stylesheet> 
+0

我需要基於組的不同渲染,這就是爲什麼我把條件和稱爲不同的模板。我可以以簡單/較短的方式完成嗎? –

+0

我只能回答,如果你實際顯示不同的渲染,據我所見,這兩個模板輸出相同,所以請編輯問題,並告訴我們你需要一個不同的輸出和你如何實現目前的方式。 –