xml - XSLT sort parent nodes based on maximum child node -
i've looked through existing articles xslt sorting, still can't figure out proper decision sorting case. need sort child nodes firstly (descending order) , sort parent nodes (descending order) based on first (maximum) child value.
so, need final order name3, name1, name2, have name1, name3, name2.
could please find solution. in advance!
input xml:
<collection> <products> <product> <productcode>001</productcode> <productname>name1</productname> <subproducts> <subproduct> <prices> <price> <totalprice>264.28</totalprice> </price> </prices> </subproduct> <subproduct> <prices> <price> <totalprice>264.28</totalprice> </price> </prices> </subproduct> </subproducts> </product> <product> <productcode>002</productcode> <productname>name2</productname> <subproducts> <subproduct> <prices> <price> <totalprice>231.99</totalprice> </price> <price> <totalprice>231.99</totalprice> </price> </prices> </subproduct> <subproduct> <prices> <price> <totalprice>231.99</totalprice> </price> <price> <totalprice>231.99</totalprice> </price> </prices> </subproduct> </subproducts> </product> <product> <productcode>003</productcode> <productname>name3</productname> <subproducts> <subproduct> <prices> <price> <totalprice>234.92</totalprice> </price> </prices> </subproduct> <subproduct> <prices> <price> <totalprice>734.12</totalprice> </price> </prices> </subproduct> </subproducts> </product> </products> </collection>
output xml: (expected)
<products> <product> <productname>name3</productname> <price>734.12</price> <price>234.92</price> </product> <product> <productname>name1</productname> <price>264.28</price> <price>264.28</price> </product> <product> <productname>name2</productname> <price>231.99</price> <price>231.99</price> <price>231.99</price> <price>231.99</price> </product> </products>
xslt transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:template match="/"> <xsl:copy> <xsl:apply-templates select="/collection/products/product"> <xsl:sort select="subproducts/subproduct[1]/prices/price[1]/totalprice" data-type="number" order="descending"/> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="/collection/products/product"> <xsl:copy> <productname> <xsl:value-of select="productname"/> </productname> <xsl:apply-templates select="subproducts/subproduct/prices/price"> <xsl:sort select="totalprice" order="descending" data-type="number"/> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="subproducts/subproduct/prices/price"> <xsl:copy> <xsl:value-of select="totalprice"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
wrong xml output:
<products> <product> <productname>name1</productname> <price>264.28</price> <price>264.28</price> </product> <product> <productname>name3</productname> <price>734.12</price> <price>234.92</price> </product> <product> <productname>name2</productname> <price>231.99</price> <price>231.99</price> <price>231.99</price> <price>231.99</price> </product> </products>
if you're using xalan processor, can take advantage of exslt math:max() extension function:
xslt 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:math="http://exslt.org/math" extension-element-prefixes="math"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/"> <products> <xsl:apply-templates select="collection/products/product"> <xsl:sort select="math:max(subproducts/subproduct/prices/price/totalprice)" data-type="number" order="descending"/> </xsl:apply-templates> </products> </xsl:template> <xsl:template match="product"> <xsl:copy> <xsl:copy-of select="productname"/> <xsl:apply-templates select="subproducts/subproduct/prices/price"> <xsl:sort select="totalprice" data-type="number" order="descending"/> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="price"> <xsl:copy> <xsl:value-of select="totalprice"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
Comments
Post a Comment