xsl-list
[Top] [All Lists]

Complicated grouping and column question

2005-06-29 13:56:27
Hi everyone,

I've got a problem trying to create two columns for an index of data. 
I can't for the life of me figure out how to break the data over two
columns.

This might be hard for me to explain, so please bear with me.

I've got a large XML file representing a course schedule for the
community college where I work.  Here's a small sample of the format:

<schedule>
    <division name="Business">
        <cluster name="Ethics">
            <course title="..." />
            <course title="..." />
            <course title="..." />
        </cluster>
        <cluster name="Accounting">
            <course title="..." />
        </cluster>
    </division>
    
    <division name="Arts">
        <cluster name="Painting">
            <course title="..." />
        </cluster>
        <cluster name="Drawing">
            <course title="..." />
        </cluster>
    </division>
</schedule>

(The actual format is a little bit more complicated than that, but
this is all of the structure that's involved in creating the index.)

I've got a stylesheet that creates a nice alphabetical index based on
the schedule XML file.  For the sample above, the index would look
like this:

A
        Arts
                Painting
                Drawing
B
        Business
                Accounting
                Ethics

So, in the index, the top level is a letter from A-Z, the second level
is a <division> name and the third level is a <cluster> name.

I'm using XSLT 2.0 and Saxon 8.4.  Here's the important part of the
current stylesheet (which is just outputting a simple HTML unordered
list, at the moment):

<xsl:template name="make-index">
        <ul>
        <xsl:for-each-group select="/schedule/division"
group-by="substring(@name,1,1)">
            <xsl:sort select="current-grouping-key()" />
            <xsl:variable name="current-letter"
select="current-grouping-key()" />
            
            <li>
                <h2><xsl:value-of select="$current-letter" /></h2>
                <ul>
                    <xsl:apply-templates
select="/schedule/division[substring(@name,1,1) = $current-letter]">
                        <xsl:sort select="@name" />
                    </xsl:apply-templates>
                </ul>
            </li>
        </xsl:for-each-group>
    </ul>
</xsl:template>

<xsl:template match="division">
    <li>
        <xsl:value-of select="@name" />
        <xsl:if test="cluster">
            <ul>
                <xsl:apply-templates select="cluster">
                    <xsl:sort select="@name" />
                </xsl:apply-templates>
            </ul>
        </xsl:if>
    </li>
</xsl:template>

<xsl:template match="cluster">
        <li><xsl:value-of select="@name" /></li>
</xsl:template>


Because I'm using for-each-group to break the divisions up into
sections by their first letters, I just can't figure out how to
calculate a good place to break the output into two columns.  The
columns need to break on a letter, so the "C" section couldn't break
at the bottom of one column and continue at the top of the other.  One
other problem is that the index is weighted heavily towards the front
of the alphabet, so the break will probably need to come around D or
E.

If this post made any sense and anyone has any suggestions, I'll be
grateful.  If I need to explain myself better, or provide a complete
input document, I'd be glad to do so.

Thanks in advance for your help,


Will.

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>