Use variable to sort elements

B

bcochofel

Hi, I want to use a variable to sort elements. That var his passed with
query string (I'm using Perl CGI to generate XML).
Here's a sample of my output:
---------------------------------------------
<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xml" href="RR.xsl"?>
<!-- $Id: template.xml,v 1.5 2006/12/11 11:13:30 bcochofel Exp $ -->
<RR
xmlns:xsi="http://www.w3.org/2001/XMLSchema"
xsi:schemaLocation="http://cochofel.sytes.net
~bcochofel/iweb/files/RR.xsd">
<Request>
<url>/~bcochofel/iweb/cgi-bin/getmysites.cgi</url>
<session>
<user>[email protected]</user>
</session>
<query>
<!-- o campo parametro pode ter varias ocurrencias -->
<param name="sort" value="asc" />
<param name="field" value="" />
</query>
</Request>
<Response>
<sites>
<site url="http://www.google.com">
<tag name="pesquisa" weight="30" />
<tag name="procura" weight="30" />
</site>
<site url="http://www.google.com/webhp?complete=1">
<tag name="ajax" weight="25" />
<tag name="pesquisa" weight="30" />
<tag name="procura" weight="30" />
</site>
<site url="https://webmail.fe.up.pt">
<tag name="email" weight="20" />
<tag name="feup" weight="20" />
</site>
</sites>
</Response>
</RR>
---------------------------------------------

I want to use the param sort and is value to sort the element <site>.
In this example:
<param name="sort" value="asc" />
so sort=asc

How can I do this? I'm new to XML, XSL and XPath...
 
J

Joe Kesselman

bcochofel said:
I want to use the param sort and is value to sort the element <site>.
In this example:
<param name="sort" value="asc" />
so sort=asc

I can't give you specific advice since your question isn't well defined.
But here are some general pointers...

First, study the xsl:sort directive, so you understand how to do basic
sorting.

It isn't at all clear from your example what kinds of control you want,
since there's no mention of "asc" anywhere else in your example, so your
next step would be to come up with a better description of that. While
you're at it, you need to say more explicitly what you're trying to use
as your sort key -- the URL? the total weight? something else?

Then the problem becomes one of how to achieve the control you need. Not
everything in XSLT can be easily controlled via variables or parameters.
You may need to explicitly test the parameter's value and use that to
control a conditional. In extreme cases you may find yourself forced to
use extension functions. But until the first two points are addressed, I
really can't advise you on this one.
 
B

bcochofel

Well, I'm using xsl:sort to sort the url attribute of site. What I want
is to control the order (ascending or descending) from the value of the
sort param name.
 
J

Joseph Kesselman

bcochofel said:
Well, I'm using xsl:sort to sort the url attribute of site. What I want
is to control the order (ascending or descending) from the value of the
sort param name.

Thanks for the clarification.

Since xsl:sort's attibutes have to be literals, the only way I know to
do this is to use a conditional (probably xsl:choose) to examine the
variable's value and select between two blocks of code, one that sorts
ascending and another that sorts descending.
 
B

bcochofel

Thanks very much. Can you give an example of how can I examine the
variable's value? Sorry, I'm not really into XPath, I'm still getting
problems with matching elements...
 
B

bcochofel

Thanks very much. Can you give an example of how can I examine the
variable's value? Sorry, I'm not really into XPath, I'm still getting
problems with matching elements...
Can I use:
"/RR/Request/query/param[@name='sort']" and
"/RR/Request/query/param[@value]"?


Thanks very much. Can you give an example of how can I examine the
variable's value? Sorry, I'm not really into XPath, I'm still getting
problems with matching elements...

Since xsl:sort's attibutes have to be literals, the only way I know to
do this is to use a conditional (probably xsl:choose) to examine the
variable's value and select between two blocks of code, one that sorts
ascending and another that sorts descending.
 
M

Martin Honnen

Joseph said:
Since xsl:sort's attibutes have to be literals,


Some of those attribute values (i.e. order, lang, data-type, case-order)
allow attribute value templates to be used so you can do e.g.

<xsl:param name="sort-order" select="'ascending'"/>

and then somewhere

<xsl:apply-templates select="something">
<xsl:sort select="." order="{$sort-order}"/>
</xsl:apply-templates>
 
J

Joseph Kesselman

bcochofel said:
Thanks very much. Can you give an example of how can I examine the
variable's value?

Sketch of one solution follows. Fill in the elipses with real code, of
course, and wrap this in the appropriate template context.

<xsl:choose>
<xsl:when test="$sort = 'asc'">
<xsl:for-each ...>
<xsl:sort ... order="ascending" />
...
</xsl:for-each>
</xsl:when>
<xsl:eek:therwise>
<xsl:for-each ...>
<xsl:sort ... order="descending" />
...
</xsl:for-each>
</xsl:when>
</xsl:choose>


Sorry, I'm not really into XPath, I'm still getting
problems with matching elements...
Can I use:
"/RR/Request/query/param[@name='sort']" and
"/RR/Request/query/param[@value]"?


Thanks very much. Can you give an example of how can I examine the
variable's value? Sorry, I'm not really into XPath, I'm still getting
problems with matching elements...

bcochofel wrote:

Well, I'm using xsl:sort to sort the url attribute of site. What I want
is to control the order (ascending or descending) from the value of the
sort param name.Thanks for the clarification.
Since xsl:sort's attibutes have to be literals, the only way I know to
do this is to use a conditional (probably xsl:choose) to examine the
variable's value and select between two blocks of code, one that sorts
ascending and another that sorts descending.
 
J

Joseph Kesselman

Martin said:
Some of those attribute values (i.e. order, lang, data-type, case-order)
allow attribute value templates

Hm. Thought I checked for that in the spec, but I may have misread...?
 
B

bcochofel

I'm trying:

<xsl:template match="/RR/Request/query/param">
<xsl:choose>
<xsl:when test="(@name='sort' and @value='asc')">
<xsl:param name="sort-order" select="'ascending'"/>
</xsl:when>
<xsl:eek:therwise>
<xsl:param name="sort-order" select="'descending'"/>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>

But this doesn't seen to be valid... I'm getting an error with the
xsl:param

bcochofel said:
Thanks very much. Can you give an example of how can I examine the
variable's value?Sketch of one solution follows. Fill in the elipses with real code, of
course, and wrap this in the appropriate template context.

<xsl:choose>
<xsl:when test="$sort = 'asc'">
<xsl:for-each ...>
<xsl:sort ... order="ascending" />
...
</xsl:for-each>
</xsl:when>
<xsl:eek:therwise>
<xsl:for-each ...>
<xsl:sort ... order="descending" />
...
</xsl:for-each>
</xsl:when>
</xsl:choose>

Sorry, I'm not really into XPath, I'm still getting


problems with matching elements...
Can I use:
"/RR/Request/query/param[@name='sort']" and
"/RR/Request/query/param[@value]"?
Joe Kesselman / Beware the fury of a patient man. -- John Dryden
 
M

Martin Honnen

Joseph said:
Hm. Thought I checked for that in the spec, but I may have misread...?

Third paragraph in <http://www.w3.org/TR/xslt#element-sort> says
"The following optional attributes on xsl:sort control how the list
of sort keys are sorted; the values of all of these attributes are
interpreted as attribute value templates."
and then lists (and explains) the attributes I have listed above.
 
B

bcochofel

In my error of validation I'm not using xsl:sort (I'll use it on
another place). I'm just trying to check for the value of sort param.
 
J

Joseph Kesselman

bcochofel said:
But this doesn't seen to be valid... I'm getting an error with the
xsl:param

xsl:param can't be set at arbitrary locations; it has to be set at the
top of your template.

xsl:variable can be, but is scoped at the place where it's set, so your
code still wouldn't work.

The solution is to invert the problem, using the conditional to decide
what value to assign rather than trying to make the assignment itself
conditional. For example:

<xsl:variable name="sort-order">
<xsl:choose>
<xsl:when test="(@name='sort' and @value='asc')">
<xsl:text>ascending</xsl:text>
</xsl:when>
<xsl:eek:therwise>
<xsl:text>descending</xsl:text>
</xsl:eek:therwise>
</xsl:choose>
</xsl:variable>
 
B

bcochofel

This block of code sets param name="sort-oder" with the value that
xsl:text outputs?!
Ok, I have to read more on XSLT. Thanks
 
J

Joseph Kesselman

bcochofel said:
This block of code sets param name="sort-oder" with the value that
xsl:text outputs?!

Well, actually it sets the variable named sort-order, but the same idea
would work for setting the value of a param.
 
D

Dimitre Novatchev

Some of those attribute values (i.e. order, lang, data-type, case-order)
allow attribute value templates to be used so you can do e.g.

I think all attributes with the exception of the "select" one allow AVTs.


Cheers,
Dimitre Novatchev
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top