I want to use for-each group in XSLT 1.0 which is quite comfortable in XSLT 2.0. However my application expects XSLT 1.0. Also some additional input text in the XML
Input XML of XSLT
<?xml version="1.0" ?>
<message:GenericData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:generic="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic"
xmlns:message="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message"
xmlns:common="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common">
<message:Header>
<message:ID>BBSDI</message:ID>
<message:Test>false</message:Test>
<message:Prepared>2023-06-30T10:18:43.607+02:00</message:Prepared>
<message:Sender id="BBK">
<common:Name xml:lang="de">Deutsche Bundesbank</common:Name>
<message:Contact>
<message:Email>[email protected]</message:Email>
</message:Contact>
</message:Sender>
<message:Structure structureID="BBK_SEDI" dimensionAtObservation="TIME_PERIOD">
<common:Structure>
<URN>urn:sdmx:org.sdmx.infomodel.datastructure.DataStructure=BBK:BBK_SEDI(1.0)</URN>
</common:Structure>
</message:Structure>
</message:Header>
<message:DataSet structureRef="BBK_SEDI" >
<generic:Series>
<generic:SeriesKey>
<generic:Value id="BBK_SEDI_CALCULATION" value="ABZINS7"></generic:Value>
</generic:SeriesKey>
<generic:Attributes>
<generic:Value id="BBK_ID" value="BBSDI.M.ABZINS7.R01"></generic:Value>
</generic:Attributes>
<generic:Obs>
<generic:ObsDimension value="2015-01"></generic:ObsDimension>
<generic:ObsValue value="3.07"></generic:ObsValue>
</generic:Obs>
<generic:Obs>
<generic:ObsDimension value="2016-01"></generic:ObsDimension>
<generic:ObsValue value="3.05"></generic:ObsValue>
</generic:Obs>
</generic:Series>
<generic:Series>
<generic:SeriesKey>
<generic:Value id="BBK_SEDI_CALCULATION" value="ABZINS7"></generic:Value>
</generic:SeriesKey>
<generic:Attributes>
<generic:Value id="BBK_ID" value="BBSDI.M.ABZINS7.R02"></generic:Value>
</generic:Attributes>
<generic:Obs>
<generic:ObsDimension value="2015-01"></generic:ObsDimension>
<generic:ObsValue value="1.07"></generic:ObsValue>
</generic:Obs>
<generic:Obs>
<generic:ObsDimension value="2016-01"></generic:ObsDimension>
<generic:ObsValue value="1.05"></generic:ObsValue>
</generic:Obs>
</generic:Series>
</message:DataSet>
</message:GenericData>
Using XSLT 2.0 which is running quite well, it seems my application is not supporting XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic">
<xsl:output indent="yes"/>
<xsl:template match="/">
<ns1:DiscountInterestRatePercent xmlns:xslt-version="MonthlyDiscounts_XSLT_26/06/2022">
<xsl:for-each-group select="//Series[SeriesKey/Value/@value='ABZINS7']/Obs" group-by="ObsDimension/@value">
<Data>
<Year>
<xsl:value-of select="substring-before(current-grouping-key(), '-')"/>
</Year>
<Month>
<xsl:value-of select="substring-after(current-grouping-key(), '-')"/>
</Month>
<RatePercentList>
<xsl:for-each select="current-group()">
<RatePercent>
<xsl:value-of select="ObsValue/@value"/>
</RatePercent>
</xsl:for-each>
</RatePercentList>
</Data>
</xsl:for-each-group>
</ns1:DiscountInterestRatePercent>
</xsl:template>
</xsl:stylesheet>
I want to use this logic in XSLT 1.0.
For XSLT 1.0 you need to use Muenchian Grouping.
You'll notice it's fairly similar, you're just using xsl:key and key() instead of xsl:for-each-group...
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:g="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic"
xmlns:m="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message"
exclude-result-prefixes="g m">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="obs" match="g:Obs" use="g:ObsDimension/@value"/>
<xsl:template match="/*/m:DataSet">
<DiscountInterestRatePercent xmlns:xslt-version="MonthlyDiscounts_XSLT_26/06/2022">
<xsl:for-each select="g:Series/g:Obs[count(.|key('obs',g:ObsDimension/@value)[1])=1]">
<xsl:variable name="obsdim" select="g:ObsDimension/@value"/>
<Data>
<Year>
<xsl:value-of select="substring-before($obsdim,'-')"/>
</Year>
<Month>
<xsl:value-of select="substring-after($obsdim,'-')"/>
</Month>
<RatePercentList>
<xsl:for-each select="key('obs',$obsdim)">
<RatePercent>
<xsl:value-of select="g:ObsValue/@value"/>
</RatePercent>
</xsl:for-each>
</RatePercentList>
</Data>
</xsl:for-each>
</DiscountInterestRatePercent>
</xsl:template>
</xsl:stylesheet>
Fiddle: http://xsltfiddle.liberty-development.net/3Nzb5jQ
Note: I didn't do any filtering based on ABZINS7
and I didn't bother with namespaces in the output. Those are left up to the reader.