Nikhil Preeth
Nikhil Preeth

Reputation: 37

How to group by a value in xslt

I am having an xml with item values

<value1>
        <OrderLine OrderedQty="1.00" Type="cancel" >
            <Item ItemID="1234">                
            </Item>
        </OrderLine>
        <OrderLine OrderedQty="1.00" Type="cancel" >
            <Item ItemID="1234">
            </Item>
        </OrderLine>
        <OrderLine OrderedQty="1.00" Type="blabla" >
            <Item ItemID="1234">
            </Item>
        </OrderLine>
        <OrderLine OrderedQty="1.00" Type="asdsd" >
            <Item ItemID="4567">
            </Item>
        </OrderLine>
</value1>

I want to get the item id's which are not canceled but some of them are canceled.The item 4567 nothing is done to it so we wont update it.

<item>
<id>1234</id>
<quantity>1</quantity>
</item>

XSLT:

    <xsl:stylesheet version="2.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20">
    <tns:Root-Element>    
      <xsl:for-each-group select="/value1/OrderLine" group-by="Item/@ItemID">

      </xsl:for-each-group>
</tns:Root-Element>

I dont have much xsl code.I need to update the orders which are not canceled.If you take itemid 4567 there is no change so we dont want anything form it.

Upvotes: 1

Views: 3652

Answers (1)

Daniel Haley
Daniel Haley

Reputation: 52848

This should get you started...

XML Input (additional OrderLine added for testing)

<value1>
    <OrderLine OrderedQty="1.00" Type="cancel" >
        <Item ItemID="1234">                
        </Item>
    </OrderLine>
    <OrderLine OrderedQty="1.00" Type="cancel" >
        <Item ItemID="1234">
        </Item>
    </OrderLine>
    <OrderLine OrderedQty="1.00" Type="blabla" >
        <Item ItemID="1234">
        </Item>
    </OrderLine>
    <OrderLine OrderedQty="1.00" Type="asdsd" >
        <Item ItemID="4567">
        </Item>
    </OrderLine>
    <OrderLine OrderedQty="2.00" Type="qwerty" >
        <!--ADDED ITEM FOR TESTING-->
        <Item ItemID="1234"/>
    </OrderLine>
</value1>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/*">
    <root>
      <xsl:for-each-group select="OrderLine[not(@Type='cancel')]/Item" group-by="@ItemID">
        <xsl:if test="count(current-group()) > 1">
          <item>
            <id><xsl:value-of select="current-grouping-key()"/></id>
            <quantity>
              <xsl:value-of select="sum(current-group()/../@OrderedQty)"/>
            </quantity>
          </item>          
        </xsl:if>
      </xsl:for-each-group>
    </root>
  </xsl:template>

</xsl:stylesheet>

XML Output

<root>
   <item>
      <id>1234</id>
      <quantity>3</quantity>
   </item>
</root>

Notes:

  • You didn't have the prefix tns bound to a namespace, so I just used a generic element (root) for the root element.
  • I assumed when you said The item 4567 nothing is done to it so we wont update it. you meant that since it wasn't added to another item, we drop the element (since it's not in your output example).
  • OrderLine/@Type is ignored other than checking for the value of "cancel".

Upvotes: 1

Related Questions