2017-04-17 49 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

我只能回答,如果你实际显示不同的渲染,据我所见,这两个模板输出相同,所以请编辑问题,并告诉我们你需要一个不同的输出和你如何实现目前的方式。 –