XSL grouping (Muenchian)

Discussion in 'XML' started by Tristan Miller, Jan 31, 2005.

  1. 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

    --
    _
    _V.-o Tristan Miller [en,(fr,de,ia)] >< Space is limited
    / |`-' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-= <> In a haiku, so it's hard
    (7_\\ http://www.nothingisreal.com/ >< To finish what you
     
    Tristan Miller, Jan 31, 2005
    #1
    1. Advertising

  2. Tristan Miller

    Joris Gillis Guest

    Tempore 12:42:20, die Monday 31 January 2005 AD, hinc in foro {comp.text.xml} scripsit Tristan Miller <>:

    > <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,
    --
    Joris Gillis (http://www.ticalc.org/cgi-bin/acct-view.cgi?userid=38041)
    Spread the wiki (http://www.wikipedia.org)
     
    Joris Gillis, Jan 31, 2005
    #2
    1. Advertising

  3. Tristan Miller wrote:
    > 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 |
    -----------------------
     
    Philippe Poulard, Jan 31, 2005
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Colin Mackenzie
    Replies:
    0
    Views:
    1,132
    Colin Mackenzie
    Jul 3, 2003
  2. reclusive monkey
    Replies:
    2
    Views:
    1,467
    reclusive monkey
    Aug 10, 2005
  3. Replies:
    1
    Views:
    651
    Joris Gillis
    Jun 6, 2006
  4. Jeffrey
    Replies:
    0
    Views:
    352
    Jeffrey
    Feb 28, 2009
  5. Jeffrey
    Replies:
    0
    Views:
    701
    Jeffrey
    Feb 28, 2009
Loading...

Share This Page