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) > 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) > 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) > 0]) mod 2"/>
<xsl:for-each select="ricerca/documento[sum(tag/match) > 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) > 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) > 0]) mod 2"/>
<xsl:for-each select="ricerca/documento[sum(tag/match) > 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) > 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>