?
Solved

XSL Filtering

Posted on 2010-01-12
4
Medium Priority
?
193 Views
Last Modified: 2013-11-18
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
Comment
Question by:Techsavy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
4 Comments
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 26301055
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
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 26301058
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
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 2000 total points
ID: 26301621
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
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 26301639
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

10 Questions to Ask when Buying Backup Software

Choosing the right backup solution for your organization can be a daunting task. To make the selection process easier, ask solution providers these 10 key questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article covers the basics of the Sass, which is a CSS extension language. You will learn about variables, mixins, and nesting.
When using a search centre, I'm going to show you how to configure Sharepoint's search to only return results from the current site collection. Very useful when using Office 365 with multiple site collections.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…
Suggested Courses

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question