Search code examples
xmlxslt

Count number of unique field in the input xml


I want to get no of unique "id" fields of below xml.

<jsonObject>
    <headers>
        <Resources>
            <field1>test-profile order 11</field1>
            <id>abca7923-eaea-4e9c-a952-b4aadc39a295</id>
            <description1>This is a test profile</description1>
        ...
        </Resources>
        <Resources>
            <field1>test-profile order 11</field1>
            <id>abca7923-eaea-4e9c-a952-b4aadc39a295</id>
            <description1>This is a test profile</description1>
            ...
        </Resources>
        <Resources>
            <field1>test-profile order 11</field1>
            <id>abca7923-eaea-4e9c-a952-b4aadc39a296</id>
            <description1>This is a test profile</description1>
            ...
        </Resources>
        <Resources>
            <field1>test-profile order 11</field1>
            <id>abca7923-eaea-4e9c-a952-b4aadc39a296</id>
            <description1>This is a test profile</description1>
            ...
        </Resources>
</headers>
</jsonObject>

I tried to get the unique "id" using the below xslt.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:key name="profileGroup" match="Resources" use="profileId" />

<xsl:template match="/jsonObject/headers">
    <jsonObject>
        <total>

            <xsl:for-each select="//id[not(.=preceding::id)]">
                <xsl:value-of select="count(//id[.=current()])" />
            </xsl:for-each>
        </total>


    </jsonObject>
</xsl:template>
</xsl:stylesheet>

But this is not working. I got this response. <total>22</total>

But I'm expecting this response <total>2</total>

What is the issue in my xslt?


Solution

  • If your processor supports XSLT 2.0 or higher, you can do simply:

    <xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="/jsonObject">
        <jsonObject>
            <total>
                <xsl:value-of select="count(distinct-values(headers/Resources/id))" />
            </total>
        </jsonObject>
    </xsl:template>
    
    </xsl:stylesheet>