File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes XML and Related Technologies and the fly likes xsl to merge duplicate tag Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » XML and Related Technologies
Bookmark "xsl to merge duplicate tag" Watch "xsl to merge duplicate tag" New topic
Author

xsl to merge duplicate tag

Artie Zero
Greenhorn

Joined: Oct 07, 2008
Posts: 5
hi.. i am new to xsl. i was wondering if someon may help out. i have the following xml

<groupsList>
<category name="AA">
<group description="AA - restricted" name="restricted_grp" dn="restRX"/>
</category>
<category name="BB">
<group description="BB - mkt" name="mkt_grp"/>
<group description="BB - info" name="info_grp"/>
</category>
<category name="AA">
<group description="A3 - resource" name="resource_grp"/>
<group description="A6 - future" name="future_grp"/>
</category>
</groupsList>


and the result should be the following

<groupsList>
<category name="AA">
<group description="AA - restricted" name="restricted_grp" dn="restRX"/>
<group description="A3 - resource" name="resource_grp"/>
<group description="A6 - future" name="future_grp"/>
</category>
<category name="BB">
<group description="BB - mkt" name="mkt_grp"/>
<group description="BB - info" name="info_grp"/>
</category>
</groupsList>


i need to come up with an xsl that would merge the xml file based on the category tag and the name attribute. so that for all categories that have the same name will have their children listed below them. that is no remove duplicate [merge duplicates in this case].

my xsl right now merges them together but don't know how to delete the duplicates. so i am going around in circles. may you someone please help
[ October 07, 2008: Message edited by: Artie Zero ]
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

You want a transformation which only copies a <category> element to the output if it isn't the same as any <category> element in the preceding-sibling axis. And underneath that you want to copy all <group> elements which are children of any <category> element which is the same as the one you are copying.

You implied you already had some not-quite-working code so I'm not going to write code for that. It might be better to start from the code you already have.
Artie Zero
Greenhorn

Joined: Oct 07, 2008
Posts: 5
Hi Paul - Thanks for the reply. Please find my xsl below. What it does it merges category elements but now I don't know how to delete. Thank you.


<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xslutput method="xml"/>
<xsl:template match="/groupsList">
<groupsList>
<xsl:call-template name="grpCategory"/>
</groupsList>
</xsl:template>
<xsl:template name="grpCategory">
<xsl:for-each select="/groupsList/category">
<xsl:call-template name="eachGroupCategory">
<xsl:with-param name="grpCat">
<xsl:value-of select="@name"/>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="eachGroupCategory">
<xsl:param name="grpCat" select="''"/>
<xsl:variable name="cnt" select="count(/groupsList/category[@name=$grpCat])"/>
<xsl:choose>
<xsl:when test="$cnt > 1">
<category>
<xsl:attribute name="name"><xsl:value-of select="$grpCat"/></xsl:attribute>
<xsl:copy-of select="/groupsList/category[@name=$grpCat]/node()"/>
</category>
</xsl:when>
<xsltherwise>
<xsl:copy-of select="/groupsList/category[@name=$grpCat]"/>
</xsltherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

[ October 08, 2008: Message edited by: Artie Zero ]
[ October 08, 2008: Message edited by: Artie Zero ]
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

You can't delete something once you have written it to the output. Your strategy should be to only write <category> elements you actually want in the output. I would repeat my suggestion about only writing <category> elements which aren't duplicates of other <category> elements in the preceding-sibling axis.
Artie Zero
Greenhorn

Joined: Oct 07, 2008
Posts: 5
I got some code online and tried to plug in and check. But I was unable to understand or get it to work. Bare in mind, I am new to XSL. I understand what you are saying (the theory) but my apologies I cannot code it. Would you be able to refer me to some samples?

I looked online for 2 days before I submitted this post. So I did try to find something I could work with. Please help.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8


Here you select each of your <category> elements. At this point you want to find out if there is another <category> element with the same "name" attribute in the previous-sibling axis. Let's start out with some code that finds out if there is any <category> element in the previous-sibling axis:
Now let's modify it to find out if there's any such <category> element with a particular "name" attribute:
Now let's modify that to make the "name" attribute the actual name attribute from the context node:
And finally you only want to generate output if that condition is not true... can I leave that up to you?

By the way, please post your code in the CODE tags so it's more readable. Indenting would help, for example.
Artie Zero
Greenhorn

Joined: Oct 07, 2008
Posts: 5
hi paul... i am getting 'invalid xpath expression' error... i tried it for a simple example below. the error is in the if statement below.


Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Yes, what I posted wasn't meant to be a finished product. So it's definitely possible that the XPath expression I came up with wasn't quite right. I think it would be a useful learning experience for you if you fixed it up.
Artie Zero
Greenhorn

Joined: Oct 07, 2008
Posts: 5
thank you paul. i was able to figure that one out. and thank you for making me think. cheers.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: xsl to merge duplicate tag