Introduction to XSLT
As a tool for humanities computing
8 Sorting and grouping
ALLC/ACH 2002, Tübingen
21-22 July 2002
C. M. Sperberg-McQueen
Wendell Piez
I. Monday afternoon 2: sorting and grouping
- Sunday a.m.: introductions
- Sunday a.m.: basics (simple transformations, if,
choose, selection by attribute values)
- Sunday p.m.: modes (e.g. tables of contents)
- Sunday p.m.: XPath
- Monday a.m.: functions, numbering
- Monday a.m.: near-identity transformations
- Monday p.m.: named templates, recursion
- Monday p.m.: sorting and grouping
- sorting (easy)
- grouping (takes some thought)
The xsl:sort element occurs as child of
apply-templates
<xsl:apply-templates select="//w" mode="conc">
<xsl:sort select="."/>
</xsl:apply-templates>
Attributes:
select
data-type (text, number)
order (ascending, descending)
- Sort the Gorbals data by surname.
- ... by occupation.
- ... by town and county of birth.
- ... by age and marital status.
A common idiom:
sortedWords = words.sort("lemma");
wordPrev = null;
write("<word-entry>");
for each w in sortedWords {
wordThis = w.getAttribute("lemma");
if (wordThis != wordPrev) {
write("</word-entry>\n<word-entry>");
}
...
wordPrev = wordThis;
}
write("</word-entry>\n");
Not a common idiom in functional languages!
- assignment statements
- we output a tree, not a stream
Three alternatives:
make list of unique items by checking for duplicates
[not(@lemma=preceding::w/@lemma)]
at cost of ca.
n × (n - 1) / 2
(ouch?)
Basically: sort, and then test for equality with preceding
value:
<xsl:template match="w" mode="conc">
<xsl:variable name="type" select="."/>
<xsl:if test="not(preceding::w[. = $type])">
<xsl:element name="h3">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
<!--* ... *-->
</xsl:template>
sort first, then check using
[not(@lemma=preceding-sibling::w[1]/@lemma)]
You probably want them sorted anyway.
Or: sort, test for equality with preceding, select:
<xsl:element name="li">
<xsl:value-of select="."/>
<xsl:call-template name="get-scraps-by-file">
<xsl:with-param name="fn">
<xsl:value-of select="."/>
</xsl:with-param>
</xsl:call-template>
</xsl:element>
Called for Steve Muench (Oracle)
Define a key:
<xsl:key name="lemma-key"
match="w"
use="@lemma"/>
Test on
generate-id(.) =
generate-id(key('lemma-key', @lemma)[1])
or on
1 = count(. | key('lemma-key',@lemma)[1])
Group exercise: reformatting census data | |
- Define key on household number.
- Define unique-households variable.
- For each household, select all individuals in it
and process them.
- Write sanity-checker to ensure we have not lost information.