This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]