xsl-list
[Top] [All Lists]

[xsl] creating a head-letter for directory

2010-01-17 23:07:30
HI, I would like to understand, given a flat sort of data extraction, of the type
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <data>
        <name>Aname</name>
<!-- other elements such as <location> follow, all related to the <name> -->
    </data>
    <data>
        <name>Hname</name><!-- other elements such as <location> follow -->
    </data>
    <data>
        <name>Dname</name><!-- other elements such as <location> follow -->
    </data>
    <data>
        <name>Wname</name><!-- other elements such as <location> follow -->
    </data>
    <data>
<name>Anothername</name><!-- other elements such as <location> follow -->
    </data>
    <data>
<name>Whatevername</name><!-- other elements such as <location> follow -->
    </data>
</root>

what are the groupings and keys needed to accomplish this (even flatter) output?

<output>
        <letter>A</etter>
        <name>Aname</name><!-- other elements such as <location> follow -->
<name>Anothername</name><!-- other elements such as <location> follow -->
        <letter>D</etter>
        <name>Dname</name><!-- other elements such as <location> follow -->
        <letter>H</etter>
        <name>Hname</name><!-- other elements such as <location> follow -->
        <letter>W</etter>
        <name>Wname</name><!-- other elements such as <location> follow -->
<name>Whatevername</name><!-- other elements such as <location> follow -->
<output>

I know that I first need to identify which first letters exist in the set of <data> elements, and then generate a <letter> element containing that first letter, followed by all the data elements children <name> that have a matching first letter. But I'm getting a <letter> element every time, rather than once for each unique occurrence, followed by the <name> elements which have a matching first letter. How do I generate the <letter> once, but follow it with all of the <name> (and related) elements? I think I need to move the <leter> element builder up out of the for-each loop that it is in, but I don't know how I then would get each letter only once for the set of all <data> elements.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="2.0">
    <xsl:template match="/">
        <xsl:variable name="blocks" select="root/data"/>
        <xsl:element name="output">
            <xsl:for-each-group select="$blocks" group-by="name">
                <xsl:sort select="current-grouping-key()"/>
<xsl:variable name="currentGroup" select="current-grouping-key()"/> <xsl:variable name="headletter" select="substring($currentGroup,1,1)"/>
                <xsl:for-each select="."><!-- context here should be data -->
                    <xsl:element name="letter">
                        <xsl:value-of select="$headletter"/>
                    </xsl:element>
<xsl:apply-templates select="name[substring(.,1,1)=$headletter]"></xsl:apply-templates>
                </xsl:for-each>
            </xsl:for-each-group>
        </xsl:element>
    </xsl:template>

    <xsl:template match="name">
        <!-- is there a way that I should use the $headletter here? -->
        <xsl:element name="name"><xsl:value-of select="."/></xsl:element>
    </xsl:template>
</xsl:stylesheet>

output with duplicate <letter> values:
<?xml version="1.0" encoding="UTF-8"?>
<output>
        <letter>A</letter>
        <name>Aname</name>
        <letter>A</letter>
        <name>Anothername</name>
        <letter>D</letter>
        <name>Dname</name>
        <letter>H</letter>
        <name>Hname</name>
        <letter>W</letter>
        <name>Whatevername</name>
        <letter>W</letter>
        <name>Wname</name>
</output>

Regards, Dorothy

--~------------------------------------------------------------------
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>