Hi,
I've got two issues I need to deal with in sorting a product list. Here's
some sample XML:
<List>
<Product>
<ProductName>CFD 1-100</ProductName>
<ProductFamily>1" CFD</ProductFamily>
</Product>
<Product>
<ProductName>CFD 1-100 Pro</ProductName>
<ProductFamily>1" CFD</ProductFamily>
</Product>
<Product>
<ProductName>CFD 1.5-100</ProductName>
<ProductFamily>1.5" CFD</ProductFamily>
</Product>
<Product>
<ProductName>CFD 2-100</ProductName>
<ProductFamily>2" CFD</ProductFamily>
</Product>
<Product>
<ProductName>DSLA 1.5-100</ProductName>
<ProductFamily>1.5" DSLA</ProductFamily>
</Product>
<Product>
<ProductName>DSLA 1-100</ProductName>
<ProductFamily>1" DSLA</ProductFamily>
</Product>
</List>
I'm sorting first by ProductFamily, and then by ProductName. I was doing
this first on MSXML and getting the result:
Family: 1" CFD
CFD 1-100
CFD 1-100 Pro
Family: 1" DSLA
DSLA 1-100
Family: 1.5" CFD
CFD 1.5-100
Family: 1.5" DSLA
DSLA 1.5-100
Family: 2" CFD
CFD 2-100
My first challenge is that I want to change the ProductFamily sort so that
it groups first by the alpha characters, and then by the numerical ones. I
seems that I need to turn the value of ProductFamily into a string so I can
sort on substrings but that can't work.
My second challenge is similar -- this is migrating from ASP with MSXML to
PHP with Sablotron, and when I test it on Sablotron, the initial sort is
getting messed up by what appears to be a bug -- it doesn't seem to be
sorting the decimals, and instead gives me this:
Family: 1.5" CFD
CFD 1.5-100
Family: 1.5" DSLA
DSLA 1.5-100
Family: 1" CFD
CFD 1-100
CFD 1-100 Pro
Family: 1" DSLA
DSLA 1-100
Family: 2" CFD
CFD 2-100
Again, it seems like the workaround is sorting on the value of a string,
this time with the translate() function applied to strip out the decimal
points. But again, that can't be done. Or can it? Does anyone have a good
idea for this one?
Here's the relevant parts of the XSL as they stand now:
<xsl:key name="FamilySort" match="Product" use="ProductFamily" />
<xsl:for-each
select="document('../data/products.xml')/dataroot/Product[generate-id(.) =
generate-id(key('FamilySort', ProductFamily)[1])]">
<xsl:sort select="./ProductFamily"/>
<xsl:if test="not(. = preceding::ProductFamily)">
<xsl:text>Family: </xsl:text>
<xsl:value-of select="./ProductFamily"/>
</xsl:if>
<xsl:for-each select="key('FamilySort', ProductFamily)">
<xsl:sort select="./ProductName"/>
<xsl:variable name="ProductName" select="./ProductName"/>
</xsl:for-each>
</xsl:for-each>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list