Re: [xsl] Newbie question on XSL transformations: multiple sorts on element attributes

Subject: Re: [xsl] Newbie question on XSL transformations: multiple sorts on element attributes
From: Rob Newman <rlnewman@xxxxxxxx>
Date: Tue, 6 Feb 2007 15:48:19 -0800
Hi Abel and others,

Then what is missing is the document(@href) function in your original code in the apply templates.

I have this - I just left it out for simplicity - sorry about that.


This is quite different from your example input, where you showed one pfarr element with multiple pfstring children, each siblings to one another. I understand now, that instead of this:

   <pfarr name="dls">
       <pfarr name="abcde">
           <pfstring name="aa">0.010</pfstring>
           <pfstring name="br24">23266128.0</pfstring>
           <pfstring name="dlt">30</pfstring>

^^^^^^^^ CORRECT


it is more like this: <pfarr name="dls"> <pfarr name="abcde"> <pfstring name="aa">0.010</pfstring> </pfarr> <pfarr name="ef"> <pfstring name="br24">23266128.0</pfstring> </pfarr> <pfarr name="ghi"> <pfstring name="dlt">30</pfstring> ....

^^^^^^^^^^ INCORRECT

The former is correct (pointed at by carats above the CORRECT text). There is a parent pfarr element called 'dls'. It has many pfarr children called (using your example) 'abcde', 'ef', 'ghi' (there are about 400 of these). Each of these has many pfstring children (approx. 30). One of these children has the id 'dlt' and is present in every pfarr. I left all the other pstring's out in the example because I wanted to make it simple. Sorry for the confusion.

with one additional change: all names are now always equal to 'dlt', right?

I want this to be output thus:

<datalogger name="B">
    <param id="dlt">80</param>
</datalogger>

<datalogger name="C">
    <param id="dlt">50</param>
</datalogger>


which, to me, looks quite different from your original output, where you kept the original siblings of params together.

My original post was the correct one. I was again trying to simplify the problem by just showing the param id = 'dlt'.


To be verbose: I want to sort them so that the first datalogger element in the XML output is the one with the highest dlt. This is then followed by those with high dlt values. Once we get beyond the dlt values, the datalogger elements are ordered by their name. All dataloggers have a param element with an id of 'dlt' and an associated value.

Do you mean that siblings can occur, and that you want the pfarr that has highest available 'dlt' value to be output as first datalogger element?

Yes! All pfarr elements have a pfstring element with the id = 'dlt'. I want to sort on this value.


Or is there always only one dlt?

If you mean as a child of every pfarr, then yes. If you mean once only in the whole input XML, then no.


What do you mean with "beyond dlt values"? It helps if you show the input as it really is, because it seems contradictory to say "Each one has a pfstring element that has an id='dlt' " and "Once we get beyond the dlt values", because they are always there.

Here is a full pfarr that has many pfstring children:


input.xml:
<pfarr name="/tempname_a2hj43k3m4kmfmfe.tmp">
	<pfarr name="dls">
		<pfarr name="abcde">
			<pfstring name="aa">0.011</pfstring>
			<pfstring name="br24">1</pfstring>
			<pfstring name="bw24">1</pfstring>
			<pfstring name="cale">1</pfstring>
			<pfstring name="ce">1</pfstring>
			<pfstring name="cld">1</pfstring>
			<pfstring name="clq">1</pfstring>
			<pfstring name="clt">1</pfstring>
			<pfstring name="con">1</pfstring>
			<pfstring name="da">1</pfstring>
			<pfstring name="dbc">1</pfstring>
			<pfstring name="dbd">1</pfstring>
			<pfstring name="dbu">1</pfstring>
			<pfstring name="dg">1</pfstring>
			<pfstring name="dlt">50</pfstring>
			...... (lots more)
		</pfarr>
		<pfarr name="ghi">
			<pfstring name="aa">1</pfstring>
			<pfstring name="br24">1</pfstring>
			<pfstring name="bw24">1</pfstring>
			<pfstring name="cale">1</pfstring>
			<pfstring name="ce">1</pfstring>
			<pfstring name="cld">1</pfstring>
			<pfstring name="clq">1</pfstring>
			<pfstring name="clt">1</pfstring>
			<pfstring name="con">1</pfstring>
			<pfstring name="da">1</pfstring>
			<pfstring name="dbc">1</pfstring>
			<pfstring name="dbd">1</pfstring>
			<pfstring name="dbu">1</pfstring>
			<pfstring name="dg">1</pfstring>
			<pfstring name="dlt">100</pfstring>
			...... (lots more)
		</pfarr>
	</pfarr>
</pfarr>


And here is what I have working so far from my XSL transformation:


output.xml:
<dataloggerlist>
	<datalogger name="abcde">
		<param id="aa">1</param>
		<param id="br24">1</param>
		<param id="bw24">1</param>
		<param id="cale">1</param>
		<param id="ce">1</param>
		<param id="cld">1</param>
		<param id="clq">1</param>
		<param id="clt">1</param>
		<param id="con">1</param>
		<param id="da">1</param>
		<param id="dbc">1</param>
		<param id="dbd">1</param>
		<param id="dbu">1</param>
		<param id="dg">1</param>
		<param id="dlt">50</param>
		...... (lots more)
	</datalogger>
	<datalogger name="ghi">
		<param id="aa">1</param>
		<param id="br24">1</param>
		<param id="bw24">1</param>
		<param id="cale">1</param>
		<param id="ce">1</param>
		<param id="cld">1</param>
		<param id="clq">1</param>
		<param id="clt">1</param>
		<param id="con">1</param>
		<param id="da">1</param>
		<param id="dbc">1</param>
		<param id="dbd">1</param>
		<param id="dbu">1</param>
		<param id="dg">1</param>
		<param id="dlt">100</param>
		...... (lots more)
	</datalogger>
</dataloggerlist>

What I would like is for the same structure as output.xml, but with element datalogger name= 'ghi' above (coming before, preceding) datalogger 'abcde' because its param id='dlt' has a higher (larger) value. Thus, what I would like is (note that datalogger name='ghi' comes first):

ideal_output.xml
<dataloggerlist>
	<datalogger name="ghi">
		<param id="aa">1</param>
		<param id="br24">1</param>
		<param id="bw24">1</param>
		<param id="cale">1</param>
		<param id="ce">1</param>
		<param id="cld">1</param>
		<param id="clq">1</param>
		<param id="clt">1</param>
		<param id="con">1</param>
		<param id="da">1</param>
		<param id="dbc">1</param>
		<param id="dbd">1</param>
		<param id="dbu">1</param>
		<param id="dg">1</param>
		<param id="dlt">100</param>
		...... (lots more)
	</datalogger>
	<datalogger name="abcde">
		<param id="aa">1</param>
		<param id="br24">1</param>
		<param id="bw24">1</param>
		<param id="cale">1</param>
		<param id="ce">1</param>
		<param id="cld">1</param>
		<param id="clq">1</param>
		<param id="clt">1</param>
		<param id="con">1</param>
		<param id="da">1</param>
		<param id="dbc">1</param>
		<param id="dbd">1</param>
		<param id="dbu">1</param>
		<param id="dg">1</param>
		<param id="dlt">50</param>
		...... (lots more)
	</datalogger>
</dataloggerlist>


Please clarify the following:

1. The order of the datalogger elements, based on some (cumulative?) value of their children
Datalogger elements right now are not sorted. Whichever comes first in input.xml gets output first in output.xml. I have no control of the order in input.xml. Hence the need to sort them.

2. The order of the param elements inside each datalogger, if there are more than one (are there?)
Yes - see example above

3. Whether additional param elements influence the order of the datalogger, other then what you define by (1)
No.

4. The exact content of your data (but keep it brief) and an example of the exact output, based on that very content. Make sure it clarifies the other points above, and the structure.
See snippets above.

Sorry about this - hopefully this cleans the canvas and it is clear to all what I am trying to do. Thanks again.

Sincerely,
- Rob

Current Thread