XSL grouping (Muenchian)

T

Tristan Miller

Greetings.

I have a question involving sorting and grouping output using XSLT. I am
trying to produce a publication list from a BibTeX-like XML file:

<bibxml:file xmlns:bibxml="http://bibtexml.sf.net/">

<bibxml:entry id="foo01">
<bibxml:article>
<bibxml:title>Foo</bibxml:title>
<bibxml:year>2001</bibxml:year>
</bibxml:article>
</bibxml:entry>

<bibxml:entry id="foo02">
<bibxml:book>
<bibxml:title>Baz</bibxml:title>
<bibxml:year>1999</bibxml:year>
</bibxml:book>
</bibxml:entry>

<bibxml:entry id="foo03">
<bibxml:inproceedings>
<bibxml:title>Bar</bibxml:title>
<bibxml:year>2001</bibxml:year>
</bibxml:inproceedings>
</bibxml:entry>

</bibxml:file>

I want the output to be as follows:

YEAR 1999:
Baz

YEAR 2001:
Bar
Foo

A naive adaptation of the example at
<http://www.jenitennison.com/xslt/grouping/muenchian.html> results in the
following:

<xsl:key name="entries-by-year" match="bibxml:entry" use="bibxml:year" />
<xsl:template match="bibxml:file">
<xsl:for-each select="contact[count(. | key('entries-by-year',
bibxml:year)[1]) = 1]">
<xsl:sort select="bibxml:year" />
YEAR <xsl:value-of select="bibxml:year" />:
<xsl:for-each select="key('entries-by-year', bibxml:year)">
<xsl:sort select="bibxml:title" />
<xsl:value-of select="bibxml:title" />
</xsl:for-each>
</xsl:for-each>
</xsl:template>

The problem is that in my case the bibxml:year element is not a direct
child of bibxml:entry, but rather inside some other element (which could
be bibxml:article, bibxml:book, or any of a number of others). Could
someone suggest to this XSLT newbie what I need to change in the above
XSLT code to account for this?

Regards,
Tristan
 
J

Joris Gillis

Tempore 12:42:20 said:
<bibxml:file xmlns:bibxml="http://bibtexml.sf.net/">

<bibxml:entry id="foo01">
<bibxml:article>
<bibxml:title>Foo</bibxml:title>
<bibxml:year>2001</bibxml:year>
</bibxml:article>
</bibxml:entry>

<bibxml:entry id="foo02">
<bibxml:book>
<bibxml:title>Baz</bibxml:title>
<bibxml:year>1999</bibxml:year>
</bibxml:book>
</bibxml:entry>

<bibxml:entry id="foo03">
<bibxml:inproceedings>
<bibxml:title>Bar</bibxml:title>
<bibxml:year>2001</bibxml:year>
</bibxml:inproceedings>
</bibxml:entry>

</bibxml:file>

I want the output to be as follows:

YEAR 1999:
Baz

YEAR 2001:
Bar
Foo
The problem is that in my case the bibxml:year element is not a direct
child of bibxml:entry, but rather inside some other element (which could
be bibxml:article, bibxml:book, or any of a number of others). Could
someone suggest to this XSLT newbie what I need to change in the above
XSLT code to account for this?

Regards,
Tristan
Hi,


Try something like this:

<xsl:key name="entries-by-year" match="bibxml:entry" use="*/bibxml:year" />

<xsl:template match="bibxml:file">
<xsl:for-each select="bibxml:entry[count(. | key('entries-by-year',*/bibxml:year)[1]) = 1]">
<xsl:sort select="*/bibxml:year" />
YEAR <xsl:value-of select="*/bibxml:year" />:
<xsl:for-each select="key('entries-by-year',*/bibxml:year)">
<xsl:sort select="*/bibxml:title" />
<xsl:value-of select="*/bibxml:title" />
</xsl:for-each>
</xsl:for-each>
</xsl:template>


regards,
 
P

Philippe Poulard

Tristan said:
Greetings.

I have a question involving sorting and grouping output using XSLT. I am
trying to produce a publication list from a BibTeX-like XML file:

<bibxml:file xmlns:bibxml="http://bibtexml.sf.net/">

<bibxml:entry id="foo01">
<bibxml:article>
<bibxml:title>Foo</bibxml:title>
<bibxml:year>2001</bibxml:year>
</bibxml:article>
</bibxml:entry>

<bibxml:entry id="foo02">
<bibxml:book>
<bibxml:title>Baz</bibxml:title>
<bibxml:year>1999</bibxml:year>
</bibxml:book>
</bibxml:entry>

<bibxml:entry id="foo03">
<bibxml:inproceedings>
<bibxml:title>Bar</bibxml:title>
<bibxml:year>2001</bibxml:year>
</bibxml:inproceedings>
</bibxml:entry>

</bibxml:file>

I want the output to be as follows:

YEAR 1999:
Baz

YEAR 2001:
Bar
Foo

A naive adaptation of the example at
<http://www.jenitennison.com/xslt/grouping/muenchian.html> results in the
following:

<xsl:key name="entries-by-year" match="bibxml:entry" use="bibxml:year" />
<xsl:template match="bibxml:file">
<xsl:for-each select="contact[count(. | key('entries-by-year',
bibxml:year)[1]) = 1]">
<xsl:sort select="bibxml:year" />
YEAR <xsl:value-of select="bibxml:year" />:
<xsl:for-each select="key('entries-by-year', bibxml:year)">
<xsl:sort select="bibxml:title" />
<xsl:value-of select="bibxml:title" />
</xsl:for-each>
</xsl:for-each>
</xsl:template>

The problem is that in my case the bibxml:year element is not a direct
child of bibxml:entry, but rather inside some other element (which could
be bibxml:article, bibxml:book, or any of a number of others). Could
someone suggest to this XSLT newbie what I need to change in the above
XSLT code to account for this?

Regards,
Tristan

hi,

try this:
<xsl:key name="entries-by-year" match="bibxml:entry"
use="bibxml:*/bibxml:year" />

if the parent of bibxml:year may be bound to another namespace, simply use:
*/bibxml:year

--
Cordialement,

///
(. .)
-----ooO--(_)--Ooo-----
| Philippe Poulard |
-----------------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top