• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

xsl to merge duplicate tag

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Sheriff
Posts: 28321
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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">
<xsl:output 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>
<xsl:otherwise>
<xsl:copy-of select="/groupsList/category[@name=$grpCat]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

[ October 08, 2008: Message edited by: Artie Zero ]
[ October 08, 2008: Message edited by: Artie Zero ]
 
Paul Clapham
Sheriff
Posts: 28321
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 28321
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 28321
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thank you paul. i was able to figure that one out. and thank you for making me think. cheers.
 
catch it before it slithers away! Oh wait, it's a tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic