2017-04-17 2 views
0

私は与えられたXMLを持っています。新しいXMLでそれを変換し、statusとorderIdに基づいてノードを集約したいと思います。新しい親のもとでconditonに基づく集約ノード

<?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> 

そして、このような出力が必要です。ここでは、statusと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を使用しますため、各-group'に例示されるようにhttps://www.w3.org/TR/xslt20/#grouping-examples –

+0

グループ化できますが、親要素を追加できません。私はfor-each-groupをstatusのためにしようとしています。これはorderIdに対して別のfor-each-groupを使用していますが、同様のorderId項目の親要素を作成できません。 –

+0

ネストされた 'xsl:forあなたが持っている出力と一緒に、私はそれを修正できると確信しています。 –

答えて

1

限り、あなたは実行時に要素や属性の名前を計算する必要はありませんし、私はあなたが2つのテンプレートとのコールを必要としないと思うようリテラル結果要素や属性値テンプレートを使用する方が簡単です-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

2つのテンプレートが同じものを出力するのを見る限り、実際に別のレンダリングを表示する場合にのみ回答できますので、質問を編集して、どのような出力が必要か、現在どのように実現しているかを教えてください。 –

関連する問題