[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: IF-ELSE.. Sorting
Hi Karlo, > * Hi, I am trying to do a conditional sort. I want to have a look at an > input parameter $arrangeby and if this is of Type DATE then I would like to > specify a sorting different from my usual > > <xsl:sort select="*[name()=$arrangeby]"/> > > as now I want to specify the data-type as "number" and then also > break it up into substring-before and substring-after, I will want > to specify a different <xsl:sort>, so I assumed I would use <xsl:if > test="$arrangeby = 'DATE'"> and put in my xsl code and finish it off > with </xsl:if>. If you need to specify an 'else' condition, then you need to use xsl:choose/xsl:when/xsl:otherwise rather than xsl:if. For example, you could store the data type that you wanted to use with: <xsl:variable name="dataType"> <xsl:choose> <xsl:when test="$arrangeby = 'DATE'">number</xsl:when> <xsl:otherwise>text</xsl:otherwise> </xsl:choose> </xsl:variable> The $dataType variable will have the value 'number' when the $arrangeby parameter is 'DATE' and the value 'text' otherwise. The data-type attribute on xsl:sort is an attribute value template. Anything that you put within {}s in the value will be evaluated as an XPath to give the value used for the attribute. This means that you can create this variable before the xsl:for-each, and then use it within the xsl:sort as follows: <xsl:for-each select="LIST/ASSIGN"> <xsl:sort select="*[name() = $arrangeby]" data-type="{$dataType}" /> ... </xsl:for-each> However, as you want to use substring-before() and substring-after() in this case, you also need to do something complicated within the select attribute to alter what expression is used according to the $arrangeby parameter. Unfortunately, this isn't possible in pure XSLT 1.0, and you can't wrap the xsl:sort within a xsl:if or xsl:choose. It's easiest to this with two separate xsl:for-eaches: <xsl:choose> <xsl:when test="$arrangeby = 'DATE'"> <xsl:for-each select="LIST/ASSIGN"> <xsl:sort select="substring-before(DATE, 'T')" data-type="number" /> ... </xsl:for-each> </xsl:when> <xsl:otherwise> <xsl:for-each select="LIST/ASSIGN"> <xsl:sort select="*[name() = $arrangeby]" /> ... </xsl:for-each> </xsl:otherwise> </xsl:choose> (You would probably be better off changing the xsl:for-eaches into xsl:apply-templates in this case - that way you could place the common processing in a common template rather than repeating it.) Or, if you're willing to use extensions and are using a processor like Saxon or Xalan that has an evaluate() function, then you could construct the expression that you want to use as a string within a variable, and then evaluate that expression within the select attribute. This also enables you to use an expression consisting of the value of the $arrangeby attribute (i.e. the name of the child element that you're using to sort by) rather than using *[name() = $arrangeby] to get at it: <xsl:variable name="selectExpression"> <xsl:choose> <xsl:when test="$arrangeby = 'DATE'"> <xsl:text>substring-before(DATE, 'T')</xsl:text> </xsl:when> <xsl:otherwise> <xsl:value-of select="$arrangeby" /> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="dataType"> ... </xsl:variable> <xsl:for-each select="LIST/ASSIGN"> <xsl:sort select="saxon:evaluate($selectExpression)" data-type="{$dataType}" /> ... </xsl:for-each> (Note that to use this extension function you need to declare the 'saxon' namespace and be using Saxon; as I say, Xalan has a similar extension function if you're using that.) Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|