2017-04-17 4 views
0

주어진 XML이 있고 새 XML로 변환하고 상태 및 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> 

그리고 이렇게 출력하고 싶습니다. 여기서는 상태 및 주문 ID를 기반으로 요소를 그룹화합니다.

 <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

음을 사용하기에 충분 https://www.w3.org/TR/xslt20/#grouping-examples. –

+0

그룹을 만들 수 있지만 상위 요소를 추가 할 수 없습니다. 나는 for-each-group for status를 시도하고있다. orderId에 대해 다른 for-each-group을 사용하고 있지만 유사한 orderId 항목에 대한 부모 요소를 만들 수 없다. –

+0

중첩 된'xsl : for -each-group'을 사용하면 생성 한 결과와 함께 해결할 수 있다고 확신합니다. –

답변

1

당신이 요소를 계산 또는 런타임에 속성 이름을 할 필요가 없습니다만큼 리터럴 결과 요소와 속성 값 템플릿을 사용하는 것이 더 쉽습니다 그리고 당신이 두 개의 템플릿과 전화를 필요가 있다고 생각하지 않습니다 에 예시를위한 각-그룹 ': -template, 그렇게 단순히`XSL을 사용하여, 당신은 당신이 "상태 및 OrderID를 기반으로 여기에 내가 그룹화하고 요소"를 말하는 것처럼 무슨 일을 알고를

<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

두 개의 템플릿 출력이 동일한 것을 볼 수있는 한 실제로 다른 렌더링을 표시하는 경우에만 대답 할 수 있습니다. 질문을 편집하여 다른 출력이 필요한 방식과 현재 달성 방법을 알려주십시오. –