mnvbrtn
mnvbrtn

Reputation: 568

Group nodes and remove duplicates

Input:

<?xml version="1.0" encoding="UTF-8"?>
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:object name="items">
    <itemConfig>
        <itemId>8955444</itemId>
        <json:number name="Price">17.99</json:number>
        <json:string name="itemId">8955444</json:string>
        <json:number name="upcNum">54654654546</json:number>
        <json:number name="freeShipFlag">1</json:number>
        <json:number name="Cartavailable">0</json:number>
        <json:number name="OnlineOnly">0</json:number>
        <json:number name="salePrice">9.39</json:number>
        <json:string name="onlinePurchDate">20150624</json:string>
        <json:string name="itemName">Conditioner</json:string>
    </itemConfig>
</json:object>
<json:object name="items">
    <itemConfig>
        <itemId>5646554</itemId>
        <json:number name="itemstock">179</json:number>
        <json:string name="wt">0.49 LBS</json:string>
        <json:number name="Price">3.39</json:number>
        <json:string name="itemId">5646554</json:string>
        <json:number name="upcNum">5646554892521</json:number>
        <json:string name="onlinePurchDate">20150624</json:string>
        <json:string name="itemName">oil</json:string>
    </itemConfig>
</json:object>
<json:object name="items">
    <itemConfig>
        <itemId>8955444</itemId>
        <json:number name="itemstock">419</json:number>
        <json:string name="wt">0.79 LBS</json:string>
        <json:string name="unitSalePrice">NA</json:string>
        <json:number name="onlineqty">0</json:number>
        <json:string name="size">6oz</json:string>
        <json:string name="category">beauty</json:string>
        <json:string name="itemId">8955444</json:string>
        <json:number name="onlineStock">1</json:number>
        <json:number name="shipsaveFlag">1</json:number>
        <json:number name="onsale">0</json:number>
        <json:number name="upcNum">54654654546</json:number>
    </itemConfig>
</json:object>
<json:object name="items">
    <itemConfig>
        <itemId>905678911</itemId>
        <json:number name="itemstock">157</json:number>
        <json:string name="wt">0.23 LBS</json:string>
        <json:string name="unitSalePrice">NA</json:string>
        <json:number name="onlineqty">0</json:number>
        <json:string name="title">Cleanser</json:string>
        <json:number name="Price">6.49</json:number>
        <json:string name="itemId">908911</json:string>
        <json:number name="upcNum">88941105671610</json:number>
        <json:number name="freeShipFlag">1</json:number>
    </itemConfig>
</json:object>
<json:object name="items">
    <itemConfig>
        <itemId>8955444</itemId>
        <json:string name="itemId">8955444</json:string>
        <json:string name="storePurchDate">20150115</json:string>
        <json:number name="storePurchqty">1</json:number>
    </itemConfig>
</json:object>
<json:object name="items">
    <itemConfig>
        <itemId>1410743567</itemId>
        <json:string name="itemId">1410743567</json:string>
        <json:string name="storePurchDate">20141226</json:string>
        <json:number name="storePurchqty">8</json:number>
    </itemConfig>
</json:object>
</json:object>

I have this xml and i need to group it to output based on itemId. Once we group the two nodes there might be duplicates, which we need to remove. how to write this in muenchian method.

Tried the following but it is not changing anything

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" extension-element-prefixes="xsi" exclude-result-prefixes="xsi json">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="items-by-id" match="itemConfig" use="itemId"/>
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="json:object[@name = 'items']">
    <xsl:copy>
        <xsl:apply-templates select="itemConfig[generate-id() = generate-id(key('items-by-id', itemId)[1])]" mode="group"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="itemConfig" mode="group">
    <xsl:copy>
        <xsl:copy-of select="itemId"/>
        <xsl:apply-templates select="key('items-by-id', itemId)"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="*[not(descendant::text())]"/>
</xsl:stylesheet>

Output:

<?xml version="1.0" encoding="UTF-8"?>
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:object name="items">
    <itemConfig>
        <itemId>8955444</itemId>
        <json:number name="Price">17.99</json:number>
        <json:string name="itemId">8955444</json:string>
        <json:number name="upcNum">54654654546</json:number>
        <json:number name="freeShipFlag">1</json:number>
        <json:number name="Cartavailable">0</json:number>
        <json:number name="OnlineOnly">0</json:number>
        <json:number name="salePrice">9.39</json:number>
        <json:string name="onlinePurchDate">20150624</json:string>
        <json:string name="itemName">Conditioner</json:string>
        <json:number name="itemstock">419</json:number>
        <json:string name="wt">0.79 LBS</json:string>
        <json:string name="unitSalePrice">NA</json:string>
        <json:number name="onlineqty">0</json:number>
        <json:string name="size">6oz</json:string>
        <json:string name="category">beauty</json:string>
        <json:number name="onlineStock">1</json:number>
        <json:number name="shipsaveFlag">1</json:number>
        <json:number name="onsale">0</json:number>
        <json:string name="storePurchDate">20150115</json:string>
        <json:number name="storePurchqty">1</json:number>             
    </itemConfig>
</json:object>
<json:object name="items">
    <itemConfig>
        <itemId>5646554</itemId>
        <json:number name="itemstock">179</json:number>
        <json:string name="wt">0.49 LBS</json:string>
        <json:number name="Price">3.39</json:number>
        <json:string name="itemId">5646554</json:string>
        <json:number name="upcNum">5646554892521</json:number>
        <json:string name="onlinePurchDate">20150624</json:string>
        <json:string name="itemName">oil</json:string>
        <json:string name="storePurchDate">20141226</json:string>
        <json:number name="storePurchqty">8</json:number>        
    </itemConfig>
</json:object>
<json:object name="items">
    <itemConfig>
        <itemId>905678911</itemId>
        <json:number name="itemstock">157</json:number>
        <json:string name="wt">0.23 LBS</json:string>
        <json:string name="unitSalePrice">NA</json:string>
        <json:number name="onlineqty">0</json:number>
        <json:string name="title">Cleanser</json:string>
        <json:number name="Price">6.49</json:number>
        <json:string name="itemId">908911</json:string>
        <json:number name="upcNum">88941105671610</json:number>
        <json:number name="freeShipFlag">1</json:number>
    </itemConfig>
</json:object>
<json:object name="items">
    <itemConfig>
        <itemId>1410743567</itemId>
        <json:string name="itemId">1410743567</json:string>
        <json:string name="storePurchDate">20141226</json:string>
        <json:number name="storePurchqty">8</json:number>
    </itemConfig>
</json:object>    
</json:object>

How to achieve this?

Upvotes: 0

Views: 149

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117165

Once we group the two nodes there might be duplicates, which we need to remove.

In order to group the items nodes and remove duplicates within each group, you must apply Muenchian grouping twice:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" >
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>  

<xsl:key name="items-by-id" match="itemConfig" use="itemId"/>
<xsl:key name="item-by-name" match="itemConfig/*" use="concat(../itemId, '|', @name)"/>

<xsl:template match="/json:object">
    <xsl:copy>
        <!-- for each group --> 
        <xsl:for-each select="json:object/itemConfig[count(. | key('items-by-id', itemId)[1]) = 1]">
            <json:object name="items">
                <itemConfig>
                    <!-- get distinct items in this group -->   
                    <xsl:copy-of select="key('items-by-id', itemId)/*[count(. | key('item-by-name', concat(../itemId, '|', @name))[1]) = 1]"/>
                </itemConfig>
            </json:object>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Test Input

 <json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
    <json:object name="items">
        <itemConfig>
            <itemId>123</itemId>
            <json:number name="Price">17.99</json:number>
            <json:string name="itemId">123</json:string>
            <json:number name="upcNum">54654654546</json:number>
            <json:number name="salePrice">9.39</json:number>
        </itemConfig>
    </json:object>
    <json:object name="items">
        <itemConfig>
            <itemId>456</itemId>
            <json:number name="Price">3.39</json:number>
            <json:number name="upcNum">456892521</json:number>
            <json:string name="itemName">oil</json:string>
        </itemConfig>
    </json:object>
    <json:object name="items">
        <itemConfig>
            <itemId>123</itemId>
            <json:string name="itemId">123</json:string>
            <json:number name="onlineStock">1</json:number>
            <json:number name="upcNum">54654654546</json:number>
        </itemConfig>
    </json:object>
    <json:object name="items">
        <itemConfig>
            <itemId>456</itemId>
            <json:number name="upcNum">456892521</json:number>
            <json:string name="category">beauty</json:string>
        </itemConfig>
    </json:object>
    <json:object name="items">
        <itemConfig>
            <itemId>123</itemId>
            <json:string name="itemId">123</json:string>
            <json:string name="storePurchDate">20150115</json:string>
        </itemConfig>
    </json:object>
</json:object>

Result

<?xml version="1.0" encoding="utf-8"?>
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
   <json:object name="items">
      <itemConfig>
         <itemId>123</itemId>
         <json:number name="Price">17.99</json:number>
         <json:string name="itemId">123</json:string>
         <json:number name="upcNum">54654654546</json:number>
         <json:number name="salePrice">9.39</json:number>
         <json:number name="onlineStock">1</json:number>
         <json:string name="storePurchDate">20150115</json:string>
      </itemConfig>
   </json:object>
   <json:object name="items">
      <itemConfig>
         <itemId>456</itemId>
         <json:number name="Price">3.39</json:number>
         <json:number name="upcNum">456892521</json:number>
         <json:string name="itemName">oil</json:string>
         <json:string name="category">beauty</json:string>
      </itemConfig>
   </json:object>
</json:object>

Note that this assumes that <itemId> is the only one in its group without a name attribute.

Upvotes: 1

Related Questions