基于新父节点下的条件聚合节点

时间:2017-04-17 10:09:06

标签: xslt-2.0

我有一个给定的XML,我想在新的xml中转换它,并希望根据status和orderId聚合节点。

 cartServices.deleteCart(carts.getCartId());

我想要这样的输出。在这里,我根据status和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>

我正在使用以下xslt,它运行正常。有没有办法改善这一点。

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

1 个答案:

答案 0 :(得分: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>