Re: [xsl] Re: [xslt transform & grouping] Using the Muenchian Method?

Subject: Re: [xsl] Re: [xslt transform & grouping] Using the Muenchian Method?
From: "Michael PG" <xrow@xxxxxxx>
Date: Wed, 29 Sep 2004 07:59:04 +0000
Hello Anton,


Thanx for your help. That's exactly what I want!

What can I do regarding idenity transformation?
Today I work with two files, filter.xslt and base.xslt. I designed the filtering process from the begining so that Base.xslt does the identity transform, and Filter.xslt contains filtering rules.


Is it possible to make similar design with implementation of Muenchian method?

So the filtering work/grouping is done in the filter.xslt.

This is how I did it before:

base.xslt

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>


<!-- import filter rules -->


<xsl:include href="filter.xslt"/>


<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>


    <xsl:template match="node() | @*">
         <xsl:copy>
              <xsl:apply-templates select="node() | @*"/>
         </xsl:copy>
    </xsl:template>

</xsl:stylesheet>


filter.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" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="Article[not(@info='main')]"/>
</xsl:stylesheet>



Regards,


/M


From: Anton Triest <anton@xxxxxxxx>
Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] Re: [xslt transform & grouping] Using the Muenchian Method?
Date: Tue, 28 Sep 2004 10:56:06 +0200


Hi Michael,

The problem you have is, your XML structure is one level deeper than Jeni's example.

<xsl:template match="Records">
<xsl:for-each select="Doc[count(. | key('contacts-by-surname', surname)[1]) = 1]">


This will not work, because you're selecting Doc elements from within the Records elements,
while there's a Contact element inbetween them (the Doc elements are grandchildren, not
children of Records). So you need something like


<xsl:template match="Records">
<xsl:for-each select="Contact/Doc[count(. | key('contacts-by-surname', surname)[1]) = 1]">


It's the same thing for your input file - you just group by the info attribute (xsl:key use="@info"),
but from Documents, you need to select Document/Article[...]:


<?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" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:key name="by-info" match="Article" use="@info"/>
<xsl:template match="/Documents">
<Documents>
<xsl:for-each select="Document/Article[count(.|key('by-info', @info)[1])=1]">
<Document name="{@info}">
<xsl:copy-of select="key('by-info', @info)"/>
</Document>
</xsl:for-each>
</Documents>
</xsl:template>
</xsl:stylesheet>


Cheers,
Anton


Michael PG wrote:


Hi,

I have tried to implement the grouping by using the Muenchian Method according to http://www.jenitennison.com/xslt/grouping/muenchian.html, but I still receive errors when I transform.

I am trying to start with Jeni's example, but keep my XML structure. (below)

"Let's take our address book above. We want to group the contacts according to their surname, so we create a key that assigns each contact a key value that is the surname given in the record. The nodes that we want to group should be matched by the pattern in the 'match' attribute. The key value that we want to use is the one that's given by the 'use' attribute:"

xml-file structure

<?xml version="1.0" encoding="utf-8"?>

<Records>
    <Contact id="0001">
        <Doc title="Mr"/>
        <Doc forename="John"/>
        <Doc surname="Smith"/>
    </Contact>
    <Contact id="0002">
        <Doc title="Dr"/>
        <Doc forename="Amy"/>
        <Doc surname="Jones"/>
    </Contact>
</Records>



xslt-file

<?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" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="contacts-by-surname" match="Doc" use="surname" />

<xsl:template match="Records">
<xsl:for-each select="Doc[count(. | key('contacts-by-surname', surname)[1]) = 1]">
<xsl:sort select="surname" />
<xsl:value-of select="surname" />,<br />
<xsl:for-each select="key('contacts-by-surname', surname)">
<xsl:sort select="forename" />
<xsl:value-of select="forename" /> (<xsl:value-of select="title" />)<br />
</xsl:for-each>
</xsl:for-each>
</xsl:template>



</xsl:stylesheet>



What is the problem? Can anybody see it ?


Thanx,

/Michael


From: Anton Triest <anton@xxxxxxxx>
Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] XSLT, XML and Identity transform
Date: Mon, 27 Sep 2004 18:49:54 +0200

Hi Michael,

You want to group your Article elements by their info attribute:
see http://www.jenitennison.com/xslt/grouping/muenchian.html

HTH,
Anton


Michael PG wrote:


Hello,

I am trying to solve following problem:

Today I use identity transform. to filter elements from my original XML file and create XML output file.
I have created two XSLTs (base.xslt and filter.xslt), where base.xslt does the identity transformation and filter.xslt defines filtering rules and templates.


What I basically want is to filter elements of type "sub" and sort them under one parent node and make selections of type "main" and sort them under another parent node. One parent node for each category. (see in Filtered XML how output shoul look like).

My input XML looks like:

[Original XML]

<Documents>
   <Document chapter="1" title="title 1" href="file1.xml">
         <Article title="1.1" info="sub"/>
         <Article title="1.2" info="main"/>
    </Document>
   <Document chapter="2" title="title 2" href="file2.xml">
         <Article title="2.1" info="sub"/>
         <Article title="2.2" info="main"/>
    </Document>
</Documents>

[Filtered XML SHOULD LOOK LIKE]

<Documents>
   <Document name="main">
         <Article title="1.2" info="main"/>
         <Article title="2.2" info="main"/>
    </Document>
   <Document name="sub">
         <Article title="1.1" info="sub"/>
         <Article title="2.1" info="sub"/>
    </Document>
</Documents>

[snip]


_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today - it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/


_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today - it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/


Current Thread