• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 194
  • Last Modified:

XSL Filtering

Hi

I am trying to get a list of unique categories for Product1 and Product 2 in the entire XML. i.e I want :


for Product1 : I should get research, marketing,industry, cinema, Literature, theory.

for Product 2: I should get Science, Economics, Commerce, Pottery, Fengshui, Ikebena


<item>
<Product1>
<category>research</category>
<category>marketing</category>
<category>industry</category>
</Product1>

<Product2>
<category>Science</category>
<category>Economics</category>
<category>Commerce</category>
<category>Ikebena</category>
</Product2>

</item>

<item>

<Product1>
<category>Cinema</category>
<category>Literature</category>
<category>Theory</category>
<category>research</category>

</Product1>

<Product2>
<category>Pottery</category>
<category>FengShui</category>
<category>Ikebena</category>
</Product2>
</item>


How do I do this using XSLT 1.0?


Thanks in advance,
0
Techsavy
Asked:
Techsavy
  • 4
1 Solution
 
Geert BormansCommented:
here you go
            <Product1>
                <xsl:for-each select="//item/Product1/category[generate-id() = generate-id(key('prod1', text())[1])]">
                    <category><xsl:value-of select="."/></category>
                </xsl:for-each>
            </Product1>
        </Products>

Open in new window

0
 
Geert BormansCommented:
that was only part of it
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:key name="prod1" match="Product1/category" use="text()"/>
    <xsl:key name="prod2" match="Product2/category" use="text()"/>
    <xsl:output indent='yes'/>
    <xsl:template match="/">
        <Products>
            <Product1>
                <xsl:for-each select="//item/Product1/category[generate-id() = generate-id(key('prod1', text())[1])]">
                    <category><xsl:value-of select="."/></category>
                </xsl:for-each>
            </Product1>
        <Product2>
            <xsl:for-each select="//item/Product2/category[generate-id() = generate-id(key('prod2', text())[1])]">
                <category><xsl:value-of select="."/></category>
            </xsl:for-each>
        </Product2>
        </Products>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
Geert BormansCommented:
I started giving you an XML result, so you could see how the mechanics work.
I used a variant on the Muenchian Grouping
read about that here:
http://www.jenitennison.com/xslt/grouping/muenchian.xml
Here is a solution, doing essentialy the same, but giving you a text output instead of XML
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:key name="prod1" match="Product1/category" use="text()"/>
    <xsl:key name="prod2" match="Product2/category" use="text()"/>
    <xsl:output method="text"/>
    <xsl:template match="/">
        <xsl:text>Product1: </xsl:text>
                <xsl:for-each select="//item/Product1/category[generate-id() = generate-id(key('prod1', text())[1])]">
                    <xsl:if test="position() != 1">, </xsl:if>
                    <xsl:value-of select="."/>
                </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
        <xsl:text>Product2: </xsl:text>
        <xsl:for-each select="//item/Product2/category[generate-id() = generate-id(key('prod2', text())[1])]">
            <xsl:if test="position() != 1">, </xsl:if>
            <xsl:value-of select="."/>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
Geert BormansCommented:
and as a last step...
I have made the string compare, case insensitive
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:param name="lc"><xsl:text>azertyuiopqsdfghjklmwxcvbn</xsl:text></xsl:param>
    <xsl:param name="uc"><xsl:text>AZERTYUIOPQSDFGHJKLMWXCVBN</xsl:text></xsl:param>
    <xsl:key name="prod1" match="Product1/category" use="translate(text(), 'AZERTYUIOPQSDFGHJKLMWXCVBN', 'azertyuiopqsdfghjklmwxcvbn')"/>
    <xsl:key name="prod2" match="Product2/category" use="translate(text(), 'AZERTYUIOPQSDFGHJKLMWXCVBN', 'azertyuiopqsdfghjklmwxcvbn')"/>
    <xsl:output method="text"/>
    <xsl:template match="/">
        <xsl:text>Product1: </xsl:text>
                <xsl:for-each select="//item/Product1/category[generate-id() = generate-id(key('prod1', translate(., $uc, $lc))[1])]">
                    <xsl:if test="position() != 1">, </xsl:if>
                    <xsl:value-of select="translate(., $uc, $lc)"/>
                </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
        <xsl:text>Product2: </xsl:text>
        <xsl:for-each select="//item/Product2/category[generate-id() = generate-id(key('prod2', translate(., $uc, $lc))[1])]">
            <xsl:if test="position() != 1">, </xsl:if>
            <xsl:value-of select="translate(., $uc, $lc)"/>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now