I'm getting back to learning XSLT after a while and find myself struggling with the push approach.
From the following (simplified) document:
<Index>
<Person id="Je1" age="30" nationality="Fra">Jean</Person>
<Person id="Ma1" age="30" nationality="Eng">Mary</Person>
<Person id="Je2" age="40" nationality="Fra">Jean</Person>
<Person id="Lu1" age="20" nationality="Ita">Luigi</Person>
<Person id="He1" age="50" nationality="Gre">Hector</Person>
<Person id="Pe1" age="45" nationality="Gre">Penelope</Person>
</Index>
I would like: 1. to use the distinct values of the attribute "nationality" to create sorted elements, 2. to pass the items to the corresponding elements 3. to order them according to another original attribute, e.g. "age"
<OrderedIndex>
<Country key="Eng">
<Person id="Ma1" age="30" nationality="E">Mary</Person>
</Country>
<Country key="Fra">
<Person id="Je1" age="30" nationality="F">Jean</Person>
<Person id="Je2" age="40" nationality="F">Jean</Person>
</Country>
<Country key="Gre">
<Person id="Pe1" age="45" nationality="Gre">Penelope</Person>
<Person id="He1" age="50" nationality="Gre">Hector</Person>
</Country>
<Country key="Ita">
<Person id="Lu1" age="20" nationality="Ita">Luigi</Person>
</Country>
</OrderedIndex>
I am managing the first step thus:
<xsl:variable name="cou" select="distinct-values(//@nationality)"/>
<xsl:template match="*">
<xsl:text>
</xsl:text>
<List>
<xsl:for-each select="$cou">
<xsl:sort/>
<xsl:text>
</xsl:text>
<xsl:element name="country">
<xsl:attribute name="country">
<xsl:copy-of select="."/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
<xsl:text>
</xsl:text>
</List>
</xsl:template>
— but am not managing to use <apply-templates>
or <for-each>
after that. There is obviously something I don't understand in the selection process.
Thanks for your help!
Your
distinct-values
is selecting@n
attributes, but I think you mean to select@nationality
attributesHowever,
distinct-values
may not be the best choice to use here, because it returns a sequence of atomic values, so you will no longer be in the context of the original XML document.xsl:for-each-group
may be a better match hereNotes:
There is really no need to try and output line breaks when outputting XML (unless you do have some special requirement). Just use the
indent
option onxsl:output
The identity template is used to copy the
Person
elementsNote the use of Attribute Value Templates when creating the
key
attribute on thecountry
element.Also note, if you did want to use
distinct-values
you could do it like this...