Home > Software design >  Please help in grouping by Title within for each catalog using Muenchian grouping XSLT 1.0
Please help in grouping by Title within for each catalog using Muenchian grouping XSLT 1.0

Time:11-05

Please help with a code to group based on TITLE within its each separate CATALOG tag. I am using XSLT 1.0 version.

<?xml version="1.0" encoding="UTF-8"?>
<hello>
<catalog>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
<cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>2000</year>
  </cd>
  <cd>
    <title>Unchain my heart</title>
    <artist>Joe Cocker</artist>
    <country>USA</country>
    <company>EMI</company>
    <price>8.20</price>
    <year>1987</year>
  </cd>
  
</catalog>
<catalog>
 <cd>
    <title>Ring My Bells</title>
    <artist>Enrique</artist>
    <country>USA</country>
    <company>EMI</company>
    <price>8.20</price>
    <year>1987</year>
  </cd>
  <cd>
     <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
</catalog>
</hello>

Excepted Output

<Song>
    <Desc>From First Catalog</Desc>
    <nameofAlbum>Empire Burlesque</nameofAlbum>
    <nameofAlbum>Unchain my heart</nameofAlbum>
</Song>
<Song>
    <Desc>From Second Catalog</Desc>
    <nameofAlbum>Ring My Bells</nameofAlbum>
    <nameofAlbum>Empire Burlesque</nameofAlbum>
</Song>

Please help as the requirement is to group based on title of each CatLog only.

I have tried using the Muenchian grouping but it was grouping with all the catalogs tags where as I require as induvial grouping between catalogs

CodePudding user response:

Since you want to dedup within the catalog, I would use generate-id() and create a composite key with the generated ID for the catalog element and the cd/title.

Use that composite key for the xsl:key matching on cd, then you can iterate over each /hello/catalog and then for each cd under that catalog you can use the key for Muenchian grouping:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    
    <xsl:variable name="labels">
        <label>First</label>
        <label>Second</label>
    </xsl:variable>
    
    <xsl:key name="cd-by-catalog-and-title" match="cd" use="concat(generate-id(..), title)"/>
    
    <xsl:template match="/">
        <xsl:for-each select="/hello/catalog">
            <xsl:variable name="pos" select="position()"/>
            <Song>
                <Desc>From <xsl:value-of select="document('')/xsl:stylesheet/xsl:variable[@name='labels']/label[$pos]"/> Catalog</Desc>
                <xsl:for-each select="cd[count(. | key('cd-by-catalog-and-title', concat(generate-id(..), title))[1]) = 1]">
                    <nameofAlbum><xsl:value-of select="title"/></nameofAlbum>
                </xsl:for-each>
            </Song>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
  • Related