Click to See Complete Forum and Search --> : Xml sorting with XSL


Fabricio
11-29-2007, 07:02 PM
Hi everybody

Hope someone can help me.



I have to sort the output for this xml file

<?xml version='1.0' encoding='ISO-8859-1' standalone='no' ?>

<ricerca>

<documento dnome='doc1'>

<tag tname='t1'>

<match>1</match>

</tag>

<tag tname='t2'>

<match>1</match>

</tag>

<tag tname='t3'>

<match>1</match>

</tag>

</documento>

<documento dnome='doc2'>

<tag tname='t1'>

<match>0</match>

</tag>

<tag tname='t2'>

<match>1</match>

</tag>

<tag tname='t3'>

<match>0</match>

</tag>

</documento>

<documento dnome='doc3'>

<tag tname='t1'>

<match>1</match>

</tag>

<tag tname='t2'>

<match>0</match>

</tag>

<tag tname='t3'>

<match>1</match>

</tag>

</documento>

<documento dnome='doc4'>

<tag tname='t1'>

<match>0</match>

</tag>

<tag tname='t2'>

<match>0</match>

</tag>

<tag tname='t3'>

<match>0</match>

</tag>

</documento>

<documento dnome='doc5'>

<tag tname='t1'>

<match>1</match>

</tag>

<tag tname='t2'>

<match>1</match>

</tag>

<tag tname='t3'>

<match>0</match>

</tag>

</documento>

<documento dnome='doc6'>

<tag tname='t1'>

<match>0</match>

</tag>

<tag tname='t2'>

<match>0</match>

</tag>

<tag tname='t3'>

<match>1</match>

</tag>

</documento>

<documento dnome='doc7'>

<tag tname='t1'>

<match>1</match>

</tag>

<tag tname='t2'>

<match>1</match>

</tag>

<tag tname='t3'>

<match>1</match>

</tag>

</documento>

</ricerca>

this xml is built run-time, so the numbers of the documents and the tags can be different.

TO BE CONTINUE

Fabricio
11-29-2007, 07:03 PM
I made a simple xsl:

<?xml version="1.0" encoding="ISO-8859-1"?>



<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html"/>

<xsl:template match="/">

<html>

<body>

<xsl:apply-templates select="ricerca/documento"/>

</body>

</html>

</xsl:template>

<xsl:template match="documento">

<h1>

<xsl:value-of select="."/>

<xsl:value-of select="@dnome"/>

</h1>

</xsl:template>

</xsl:stylesheet>



which make this output.

1 1 1 doc1

0 1 0 doc2

1 0 1 doc3

0 0 0 doc4

1 1 0 doc5

0 0 1 doc6

1 1 1 doc7





but I want my output is:



0 1 0 doc2

1 1 0 doc5

1 1 1 doc1

1 1 1 doc7

1 0 1 doc3

0 0 1 doc6



- documents with more occurences tag=1 printed in the middle of the page

-documents with more occurences tag=0 printed in the top and in the bottom of the page

-documente with all tag=0 not printed



someone can help me??

Thanks

jkmyoung
12-03-2007, 09:56 AM
3rd requirement, using a conditional [sum(tag/match) &gt; 0]

I don't quite understand the 2nd and 1st requirements.
?Could you do something like:

<xsl:apply-templates select="ricerca/documento[sum(tag/match) &gt; 0]">
<xsl:sort select="sum(tag/match)"/>
</xsl:apply-templates>

Fabricio
12-03-2007, 10:28 AM
HI
the xml file is the same

an exemple of the output for the 2nd and 1st requirements.


0 1 0 doc2 because the occurrences number is smaller than doc 5
1 1 0 doc5 because the occurrences number is smaller than doc 1
1 1 1 doc1 in the middle of the pagebecause is the document with highest number of occurrences of '1'
1 1 1 doc7 in the middle of the pagebecause is the document with highest number of occurrences of '1'
1 0 1 doc3 because the occurrences number is smaller than doc 7
0 0 1 doc6 because the occurrences number is smaller than doc 3


at the center of the page i'd like to put the document with highest number of occurrences of '1'.
then the i'd like to put document with a number of 'match' (occurrences of '1') smaller than the center document one above it, and one under it
and so on

another example

0 1 0 1 doc2 doc2 < doc5
1 1 0 1 doc5 doc2 < doc5 < doc 1
1 1 1 1 doc1 in the middle because 1111 is the biggest
1 1 1 0 doc7 doc3 < doc7 < doc 1 && >doc5
1 0 1 1 doc3 doc7 < doc3 < doc 6
0 0 1 0 doc6 doc6 < doc3 < doc 1



the tag number is run-time generated, so while i'm coding i can't know the number and the names of the tags (but inside every document tag names and number are the same )

thanks

jkmyoung
12-03-2007, 03:01 PM
<xsl:variable name="parity" select="count(ricerca/documento[sum(tag/match) &gt; 0]) mod 2"/>
<xsl:for-each select="ricerca/documento[sum(tag/match) &gt; 0]">
<xsl:sort select="sum(tag/match)" order="ascending"/>
<xsl:if test="position() mod 2 = $parity">
<xsl:apply-templates select="."/>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="ricerca/documento[sum(tag/match) &gt; 0]">
<xsl:sort select="sum(tag/match)" order="descending"/>
<xsl:if test="position() mod 2 = 0">
<xsl:apply-templates select="."/>
</xsl:if>
</xsl:for-each>


I think this should be it, in place of your original apply-templates.

Fabricio
12-04-2007, 07:43 PM
thaks a lot jkm!!
only 2 things:

1)
now my xsl is this

?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html"/>

<xsl:template match="/">

<html>
<head>
<title>Sono nel xls</title>
</head>
<body>
<h1> <center>Risultati Ricerca </center> </h1>
<xsl:variable name="parity" select="count(ricerca/documento[sum(tag/match) &gt; 0]) mod 2"/>
<xsl:for-each select="ricerca/documento[sum(tag/match) &gt; 0]">
<xsl:sort select="sum(tag/match)" order="ascending"/>
<xsl:if test="position() mod 2 = $parity">
<xsl:apply-templates select="."/>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="ricerca/documento[sum(tag/match) &gt; 0]">
<xsl:sort select="sum(tag/match)" order="descending"/>
<xsl:if test="position() mod 2 = 0">
<xsl:apply-templates select="."/>
</xsl:if>
</xsl:for-each>
<center><a href="./index.html">altra ricerca</a></center>
</body>

</html>

</xsl:template>

<xsl:template match="documento">

<h3>

<xsl:value-of select="."/>

<a href="./motoreRic/{@dnome}"><xsl:value-of select="@dnome"/></a>

</h3>

</xsl:template>

</xsl:stylesheet>

there is a little problem:
if my xml is this
<documento dnome='colombo.html'>
<tag tname='colombo'>
<match> 1 </match>
</tag>
<tag tname='genova'>
<match> 1 </match>
</tag>

<documento dnome='genova.html'>
<tag tname='colombo'>
<match> 0 </match>
</tag>
<tag tname='genova'>
<match> 1 </match>
</tag>
</documento>
<documento dnome='univ.html'>
<tag tname='colombo'>
<match> 0 </match>
</tag>
<tag tname='genova'>
<match> 1 </match>
</tag>
</documento>


0 1 genova.html
1 1 colombo.html
0 1 genova.html

but it should be

0 1 genova.html
1 1 colombo.html
0 1 univ.html
why, in your opinion?

second) it's possible to write the values that we 've put on the middle of the page, in a font size bigger than the top and the botton one ?

like this:
1 0 0 pippo.html font size = 5
1 0 1 genova.html font size = 10
1 1 1 colombo.html font size = 15
0 1 1 univ.html font size = 10
0 1 0 paperino.html font size = 5


thanks

Fabrizio

jkmyoung
12-05-2007, 01:22 PM
Ok, I realized that the 2 sorts are not reverse of each other.
Add a subsort to each
<xsl:sort select="position()" order="ascending"/>
AND
<xsl:sort select="position()" order="descending"/>

Add to the first for-each, and xsl:choose
<xsl:choose>
<xsl:when test="position()=last()">
Output values in bigger text, eg add surrounding <font> tags.
</xsl:when>
<xsl:otherwise>
Output values normally
</xsl:otherwise>
</xsl:choose>