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: How to define a xsl:sort's order attribute using a variable


Mike McGraw wrote:

> I want to sort a list of <person> elements, and define the "select" and
> "order" attributes of the xsl:sort element using variables, rather than
> hardcoded values.
> 
> xml source:
> 
> <personlist sortBy="name" sortOrder="descending">
>  <person>
>   <name>Bob</name>
>   <age>40</age>
>  </person>
>  <person>
>   <name>Mary</name>
>   <age>53</age>
>  </person>
>  <person>
>   <name>Arthur</name>
>   <age>22</age>
>  </person>
> </personlist>
> 
> 
> Here's an example of what I want to do. Iterate through the list of <person>
> elements, and sort by the element whose names matches personlist/@sortBy, in
> the order defined by personlist/@sortOrder:
> 
> <xsl:template match="personlist">
> 
>  <xsl:variable name="sortBy">
>   <xsl:attribute name="value">
>    <xsl:value-of select="@sortBy">
>   </xsl:attribute>
>  </xsl:variable>
> 
>  <xsl:variable name="sortOrder">
>   <xsl:attribute name="value">
>    <xsl:value-of select="@sortOrder">
>   </xsl:attribute>
>  </xsl:variable>
> 
>  <xsl:for-each select="person/*[name()=$sortBy]">
>  <xsl:sort select="." order="$sortOrder"/>
> 
>   <p>
>   <xsl:value-of select="../name"/>&#160;
>   <xsl:value-of select="../age"/>
>   </p>
> 
>  </xsl:for-each>
> 
> </xsl:template>


Hi Mike,

Have you used an xsl:variable before?

This is incorrect:

>  <xsl:variable name="sortBy">
>   <xsl:attribute name="value">
>    <xsl:value-of select="@sortBy">
>   </xsl:attribute>
>  </xsl:variable>
> 
>  <xsl:variable name="sortOrder">
>   <xsl:attribute name="value">
>    <xsl:value-of select="@sortOrder">
>   </xsl:attribute>
>  </xsl:variable>

An xsl:variable doesn't have a "value" attribute. An xsl:variable can be assigned
(initial) value either specified by its "select" attribute, or as an RTF (if the
contents/body of the xsl:variable is used.

In your case these are correct:

    <xsl:variable name="sortBy" select="@sortBy"/>
    <xsl:variable name="sortOrder" select="@sortOrder"/>

Also, all attributes of xsl:sort will accept an AVT.

Therefore, a correct stylesheet that will process your xml source in the desired way
is:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
 <xsl:output indent="yes" omit-xml-declaration="yes"/>
 <xsl:template match="text()"/>
 <xsl:template match="personlist">

    <xsl:variable name="sortBy" select="@sortBy"/>
    <xsl:variable name="sortOrder" select="@sortOrder"/>

    <xsl:for-each select="person/*[name()=$sortBy]">
    <xsl:sort select="." order="{$sortOrder}"/>

     <p>
       <xsl:value-of select="../name"/>
       <xsl:text>&#160;</xsl:text>
       <xsl:value-of select="../age"/>
     </p>

  </xsl:for-each>

</xsl:template>
</xsl:stylesheet>

And the result is:
<p>Mary 53</p>
<p>Bob 40</p>
<p>Arthur 22</p>

Hope this helped.

Cheers,
Dimitre Novatchev.

__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail
http://personal.mail.yahoo.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]