xslt - Find maximum value of all child elements and only get the max row of that child using xsl transformation 1.0 -
for example source xml
<records> <record> <personid>111</personid> <location>australia</location> <year>1999</year> </record> <record> <personid>222</personid> <location>netherland</location> <year>1919</year> </record> <record> <personid>111</personid> <location>usa</location> <year>2000</year> </record> </records>
now after xsl should below takes latest year's (max on elemtnt year) , discards old records personid:
<records> <record> <personid>222</personid> <location>netherland</location> <year>1919</year> </record> <record> <personid>111</personid> <location>usa</location> <year>2000</year> </record> </records>
this stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:key name="krecordbypersonid" match="record" use="personid"/> <xsl:template match="node()|@*" name="identity"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="record"/> <xsl:template match="record[count(.|key('krecordbypersonid',personid)[1]) = 1]"> <xsl:for-each select="key('krecordbypersonid',personid)"> <xsl:sort select="year" data-type="number" order="descending"/> <xsl:if test="position()=1"> <xsl:call-template name="identity"/> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>
output:
<records> <record> <personid>111</personid> <location>usa</location> <year>2000</year> </record> <record> <personid>222</personid> <location>netherland</location> <year>1919</year> </record> </records>
just fun, preserving input source order performance:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:key name="krecordbypersonid" match="record" use="personid"/> <xsl:template match="node()|@*" name="identity"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="records"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:call-template name="group-max"> <xsl:with-param name="pgroup" select="record[count(.|key('krecordbypersonid',personid)[1]) = 1]"/> </xsl:call-template> </xsl:copy> </xsl:template> <xsl:template name="group-max"> <xsl:param name="pgroup" select="/.."/> <xsl:param name="pgroup-max" select="/.."/> <xsl:choose> <xsl:when test="$pgroup"> <xsl:for-each select="key('krecordbypersonid',$pgroup[1]/personid)"> <xsl:sort select="year" data-type="number" order="descending"/> <xsl:if test="position()=1"> <xsl:call-template name="group-max"> <xsl:with-param name="pgroup" select="$pgroup[position()!=1]"/> <xsl:with-param name="pgroup-max" select="$pgroup-max|."/> </xsl:call-template> </xsl:if> </xsl:for-each> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="$pgroup-max"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
output:
<records> <record> <personid>222</personid> <location>netherland</location> <year>1919</year> </record> <record> <personid>111</personid> <location>usa</location> <year>2000</year> </record> </records>
Comments
Post a Comment