XSLT sorting question

M

Michiel Kamermans

Hi,

I need to generate a list based on a sorted nodeset, except duplicates
need to be discarded. I initially though of doing a sort on a nodeset and
then passing it to a template that iterates over the set and compares the
current element it's processing to the previous one, continueing to the
next element immediately if it was the same as the previous one.

However, quite annoyingly the xsl:sort command cannot "just" be called, I
need to call it in a for-each, which seems to destroy the ability to
determine what the previous element processed was.

My idea was to do the following (in prologlike code)

buildlist() :-
node('//entry',List),
sort(List,SortedList)
writelist(Sortedlist,'',1).

writelist(List, Lastseen, Count) :-
Newcounter is Count + 1,
Element = List[Count],
( Lastseen != Element,
writeelement(Element)
;
# do nothing )
writelist(List,Element,Newcount).

writeelement(E) :- # do whatever writing is required here

I am not entirely sure why sort() never became a select function in
addition (or frankly, replacement) to being an element that can only be
used inside iteration, but it would seem that the fact that one cannot do
something like:

<xsl:variable name="sortedvarname" select="sort(variable,condition-
string)"/>

was a bad idea - but this is a problem I have with XSLT's design, so that
won't get me any closer to an answer =)

Does anyone know how to either obtain the count for which element from a
set is used in a foreach, or how to sort a nodeset before sending it on
for further processing in another template?

Mike Kamermans
 
M

Martin Honnen

Michiel Kamermans wrote:

However, quite annoyingly the xsl:sort command cannot "just" be called, I
need to call it in a for-each,

xsl:sort can be used inside of <xsl:apply-templates>, not only
xsl:for-each. It might help to write two stylesheets, one that sorts as
needed, the second that takes the result of the first as the input and
then does what you additionally want to do. You simply chain those two
stylesheets then to get the complete result.
Or if your processor supports an extension function to convert a result
tree fragment into a node set then you can sort and store in a variable
(which then contains a result tree fragment), then use the extension
function to convert the result tree fragment to a node set and do what
you need to do with the node set.

On the other hand when I think about the initial requirement
I need to generate a list based on a sorted nodeset, except duplicates
need to be discarded

then I think it should be possible in one step, simply use grouping to
eliminate duplicates in the node set you sort and process further e.g.
<xsl:apply-templates select="item[conditionHereToFilterDuplicates]">
<xsl:sort ... />
</xsl:apply-templates>
 
M

Michiel Kamermans

Sadly this solution would require an "apply-template", while I need the
functionality in a "call-template" instead. Is there any creative way that
you (or anyone else) knows of to get a sorted, duplicates removed nodeset
to pass on to a custom function?

Mike Kamermans
 
M

Martin Honnen

Michiel said:
Sadly this solution would require an "apply-template", while I need the
functionality in a "call-template" instead. Is there any creative way that
you (or anyone else) knows of to get a sorted, duplicates removed nodeset
to pass on to a custom function?

As said, you can write two stylesheets and chain them (have the second
process the result of the first) or you can use an extension function to
convert a result tree fragment to a node set. Many XSLT processors have
such a function and EXSLT has attempted to standardize the name and
namespace that function lives in:
<http://www.exslt.org/exsl/functions/node-set/index.html>
 
M

Michiel Kamermans

I'll check up on that... but my word is that the worst name ever; "extended
extendible [...]"?

*shakes head*

Mike
 

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
474,001
Messages
2,570,251
Members
46,851
Latest member
CristineKo

Latest Threads

Top