My XML is structured like this (simplified)
<Record>
<Person>
<name>Jim</name>
<year>
<value>2022</value>
</year>
</Person>
</Record>
<Record>
<Person>
<name>Mary</name>
<year>
<value>2022</value>
<value>2023</value>
</year>
</Person>
</Record>
<Record>
<Person>
<name>Linda</name>
<year>
<value>2022</value>
<value>2021</value>
</year>
</Person>
</Record>
I need to create an HTML list grouped by year/value which can be shared across Person records.
2023
-Mary
2022
-Jim
-Linda
-Mary
2021
-Linda
I have tried standard Meunchian grouping, but all I get is the first year/value
2022
-Jim
-Linda
-Mary
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:exsl="http://exslt.org/common">
<xsl:key match="Person" name="person-year" use="year/value"/>
<xsl:template match="/">
<xsl:apply-templates select="Record">
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Record">
<xsl:for-each select="Person[generate-id(.)=generate-id(key('person-year', year/value))]">
<table class="table table-striped table-bordered" summary="list of {year/value} people">
<tr>
<th>
<xsl:value-of select="year/value"/>
</th>
</tr>
<xsl:for-each select="key('person-year', year/value)">
<xsl:sort order="ascending" select="name"/>
<tr>
<td>
<a href="{link}" target="_blank">
<xsl:value-of select="name"/>
</a>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</xsl:template>
You want to group every Person
by year/value
so you first need to know what all the year/value
values are. You can add another xsl:key
for this.
Then you process all of the years and use the current year to access your original key to get the people for that year.
Example...
XML (updated to be well-formed)
<doc>
<Record>
<Person>
<name>Jim</name>
<year>
<value>2022</value>
</year>
</Person>
</Record>
<Record>
<Person>
<name>Mary</name>
<year>
<value>2022</value>
<value>2023</value>
</year>
</Person>
</Record>
<Record>
<Person>
<name>Linda</name>
<year>
<value>2022</value>
<value>2021</value>
</year>
</Person>
</Record>
</doc>
XSLT 1.0
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:key name="years" match="Person/year/value" use="."/>
<xsl:key name="person-year" match="Person" use="year/value"/>
<xsl:template match="/">
<xsl:for-each select=".//Record/Person/year/value[generate-id()=generate-id(key('years',.)[1])]">
<xsl:sort select="." order="descending"/>
<table class="table table-striped table-bordered" summary="list of {.} people">
<tr>
<th>
<xsl:value-of select="."/>
</th>
</tr>
<xsl:for-each select="key('person-year', .)">
<xsl:sort order="ascending" select="name"/>
<tr>
<td>
<a href="{link}" target="_blank">
<xsl:value-of select="name"/>
</a>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Output (@href is empty because your source didn't have link
elements)
<?xml version="1.0" encoding="utf-8"?>
<table class="table table-striped table-bordered" summary="list of 2023 people">
<tr>
<th>2023</th>
</tr>
<tr>
<td>
<a href="" target="_blank">Mary</a>
</td>
</tr>
</table>
<table class="table table-striped table-bordered" summary="list of 2022 people">
<tr>
<th>2022</th>
</tr>
<tr>
<td>
<a href="" target="_blank">Jim</a>
</td>
</tr>
<tr>
<td>
<a href="" target="_blank">Linda</a>
</td>
</tr>
<tr>
<td>
<a href="" target="_blank">Mary</a>
</td>
</tr>
</table>
<table class="table table-striped table-bordered" summary="list of 2021 people">
<tr>
<th>2021</th>
</tr>
<tr>
<td>
<a href="" target="_blank">Linda</a>
</td>
</tr>
</table>