How do I apply a parameter to a select
and order
attribute in a xsl:sort
element? I'ld like to do this dynamic with PHP with something like this:
$xsl = new XSLTProcessor();
$xslDoc = new DOMDocument();
$xslDoc->load( $this->_xslFilePath );
$xsl->importStyleSheet( $xslDoc );
$xsl->setParameter( '', 'sortBy', 'viewCount' );
$xsl->setParameter( '', 'order', 'descending' );
But I'ld first have to now how to get this to work. I tried the following, but it gives me a 'compilation error' : 'invalid value $order for order'. $sortBy
doesn't seem to do anything either:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="sortBy" select="viewCount"/>
<xsl:param name="order" select="descending"/>
<xsl:template match="/">
<media>
<xsl:for-each select="media/medium">
<xsl:sort select="$sortBy" order="$order"/>
// <someoutput>
</xsl:for-each>
</media>
</xsl:template>
</xsl:stylesheet>
You are close to the correct solution, but there are a few issues:
<xsl:param name="sortBy" select="viewCount"/>
This defines the$sortBy
parameter as the value of theviewCount
child of the current node (the document node). Because the top element is not namedviewCount
, the$sortBy
parameter so defined has no value at all.<xsl:param name="order" select="descending"/>
Ditto.<xsl:sort select="$sortBy" order="$order"/>
Even if issues 1. and 2. above are fixed, this xslt instruction is still problematic. It specifies the value of theorder
attribute as the literal string'$order'
-- not as the value of the parameter$order
. The way to do this in XSLT is by using AVT (Attribute Value Template). Whenever we want a to specify that within an attribute value we want a particular string to be evaluated as an XPath expression, then this string must be surrounded by curly braces.So, the
order
attribute should be specified as:order = '{$order}'
.Unfortunately, AVTs cannot be used for the
select
attribute (another rule from the XSLT spec).The way to specify the value of the
select
attribute is a little-bit more tricky:select='*[name()=$sortBy]'
This says: sort by the child element, whose name is the same as the value of the variable$sortBy
.To put all this together, here is the corrected transformation:
When this transformation is applied on the following XML document:
The correct result is produced: