[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Sorting data after transformation is done

Subject: Sorting data after transformation is done
From: "Jean-Yves Avenard" <jyavenard@xxxxxxxxx>
Date: Tue, 29 Apr 2008 23:12:26 +1000
 Sorting data after transformation is done
Hello

I am facing a problem that unfortunately, I've been unable to resolve.
For a preamble, I'm very new at XSLT, only started yesterday, so
please forgive my ignorance !

I am working on some xmltv files. An xmltv file (as described in
www.xmltv.org) is a XML file containing TV programme information.
The programme listings look like this:
 <tv>
<programme channel="tpg.aljazeera" start="20080430040000 +0100"
stop="20080430043000 +0100">
   <title>
     Witness
   </title>
   <sub-title>
     Memories of Utopia
   </sub-title>
   <desc>
     Inspirational and provocative stories providing a fresh and
informative insight into the world's key events and their impact on
the lives of ordinary people.
   </desc>
 </programme>
</tv>

As you can see, the programme contains one attribute: start which is a
date in the format YYYYMMDDHHMMSS [+-]XXXX
where XXXX is the timezone.

I have written an XSLT template (I've attached the code below) that
converts that date to UTC as the xmltv file will contain various
programme, all in different timezone depending on the source.

What I'm trying to achieve, is sort the XML file based on the start
attribute, but *after* it has been converted to UTC

Currently, to sort the XML by the start attribute , I would do
something like this:
<xsl:template match="tv">
	<xsl:for-each select="programme">
	<xsl:sort select="@start" order="ascending"/>
		<xsl:value-of select="@start" />
	.	...
	</xsl:for-each>
</xsl:template>

The way I would convert my date, with my template/function is:
	<xsl:variable name="utcstart">
		<xsl:call-template name="UTCDate">
			<xsl:with-param name="DateTime" select="@start"/>
		</xsl:call-template>
	</xsl:variable>

Is this something that would be possible with XSLT?
if not, could you suggest a work around ?

Thank you very much in advance.
Kind regards and all the best

-- My UTC convert template: Unfortunately, I want this to run in my
web browser, and I haven't found one compatible with XSLT 2.0, so I
had to do everything by hand.


	<xsl:template name="DayMonth">
	<xsl:param name="mo" />
	<xsl:param name="year" />
		<xsl:choose>
			<xsl:when test="$mo = 0">31</xsl:when>
			<xsl:when test="$mo = 1">31</xsl:when>
			<xsl:when test="($mo = 2) and (($year mod 4) = 0)">29</xsl:when>
			<xsl:when test="$mo = 2">28</xsl:when>
			<xsl:when test="$mo = 3">31</xsl:when>
			<xsl:when test="$mo = 4">30</xsl:when>
			<xsl:when test="$mo = 5">31</xsl:when>
			<xsl:when test="$mo = 6">30</xsl:when>
			<xsl:when test="$mo = 7">31</xsl:when>
			<xsl:when test="$mo = 8">31</xsl:when>
			<xsl:when test="$mo = 9">30</xsl:when>
			<xsl:when test="$mo = 10">31</xsl:when>
			<xsl:when test="$mo = 11">30</xsl:when>
			<xsl:when test="$mo = 12">31</xsl:when>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template name="UTCDate">
	<xsl:param name="DateTime" />
	<xsl:variable name="year">
		<xsl:value-of select="number(substring($DateTime,1,4))" />
	</xsl:variable>
	<xsl:variable name="month">
		<xsl:value-of select="number(substring($DateTime,5,2))" />
	</xsl:variable>
	<xsl:variable name="day">
		<xsl:value-of select="number(substring($DateTime,7,2))" />
	</xsl:variable>
	<xsl:variable name="hh">
		<xsl:value-of select="number(substring($DateTime,9,2))" />
	</xsl:variable>
	<xsl:variable name="mm">
		<xsl:value-of select="number(substring($DateTime,11,2))" />
	</xsl:variable>
	<xsl:variable name="ss">
		<xsl:value-of select="substring($DateTime,13,2)" />
	</xsl:variable>
	<xsl:variable name="sign">
		<xsl:value-of select="substring($DateTime,16,1)" />
	</xsl:variable>
	<xsl:variable name="tzh">
		<xsl:value-of select="number(substring($DateTime,17,2))" />
	</xsl:variable>
	<xsl:variable name="tzm">
		<xsl:value-of select="number(substring($DateTime,19,2))" />
	</xsl:variable>
	<xsl:variable name="stzh">
		<xsl:choose>
			<xsl:when test="$sign = '-'">
				<xsl:value-of select="-($tzh)"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$tzh"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>
	<xsl:variable name="stzm">
		<xsl:choose>
			<xsl:when test="$sign = '-'">
				<xsl:value-of select="-($tzm)"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$tzm"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>

	 <!--Calculate last day of current month -->
	<xsl:variable name="maxday">
		<xsl:call-template name="DayMonth">
			<xsl:with-param name="mo" select="$month"/>
			<xsl:with-param name="year" select="$year"/>
		</xsl:call-template>
	</xsl:variable>

	 <!--Calculate previous day -->
	<xsl:variable name="dayminus">
		<xsl:choose>
			<!--Set to last day of previous month-->
			<xsl:when test="$day &lt;= 1">
				<xsl:call-template name="DayMonth">
					<xsl:with-param name="mo" select="($month)-1"/>
					<xsl:with-param name="year" select="$year"/>
				</xsl:call-template>
			</xsl:when>
			<!--Decrement day-->
			<xsl:otherwise>
				<xsl:value-of select="($day)-1"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>
	
	 <!--Calculate next day -->
	<xsl:variable name="dayplus">
		<xsl:choose>
			<!--If last day of current month-->
			<xsl:when test="$day = $maxday">
				<xsl:value-of select="1"/>
			</xsl:when>
			<!--Increment day-->
			<xsl:otherwise>
				<xsl:value-of select="($day)+1"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>

	<xsl:variable name="dayadj">
		<xsl:choose>
			<!--TimeZone was positive-->
			<xsl:when test="$hh &lt; $stzh">
				<xsl:value-of select="$dayminus"/>
				<!--Remove one day-->
			</xsl:when>
			<xsl:when test="($hh &lt;= $stzh) and ($mm &lt; $stzm)">
				<xsl:value-of select="$dayminus"/>
				<!--Remove one day-->
			</xsl:when>
			<!--TimeZone was negative-->
			<xsl:when test="((($hh)-($stzh)) &gt;= 23) and ((($mm)-($stzm)) &gt;= 60)">
				<xsl:value-of select="$dayplus"/>
				<!--Add one day-->
			</xsl:when>
			<xsl:when test="(($hh)-($stzh)) &gt;= 24">
				<xsl:value-of select="$dayplus"/>
				<!--Add one day-->
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$day"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>

	<xsl:variable name="monthadj">
		<xsl:choose>
			<!--Handle +XX timezone-->
			<xsl:when test="($hh &lt; $stzh) and ($day = 1) and ($month = 1)">
				<xsl:value-of select="12"/>
			</xsl:when>
			<xsl:when test="($hh &lt;= $stzh) and ($mm &lt; $stzm) and ($day =
1) and ($month = 1)">
				<xsl:value-of select="12"/>
			</xsl:when>
			<xsl:when test="($hh &lt; $stzh) and ($day = 1) and ($month &gt; 1)">
				<xsl:value-of select="($month)-1"/>
			</xsl:when>
			<xsl:when test="($hh &lt;= $stzh) and ($mm &lt; $stzm) and ($day =
1) and ($month &gt; 1)">
				<xsl:value-of select="($month)-1"/>
			</xsl:when>
			<!--Handle -XX timezone-->
			<xsl:when test="((($hh)-($stzh)) &gt;= 24) and ($day = $maxday) and
($month = 12)">
				<xsl:value-of select="1"/>
			</xsl:when>
			<xsl:when test="((($hh)-($stzh)) &gt;= 24) and ($day = $maxday) and
($month &lt; 12)">
				<xsl:value-of select="($month)+1"/>
			</xsl:when>
			<xsl:when test="((($hh)-($stzh)) &gt;= 23) and ((($mm)-($stzm))
&gt;= 60) and ($day = $maxday) and ($month = 12)">
				<xsl:value-of select="1"/>
			</xsl:when>
			<xsl:when test="((($hh)-($stzh)) &gt;= 23) and ((($mm)-($stzm))
&gt;= 60) and ($day = $maxday) and ($month &lt; 12)">
				<xsl:value-of select="($month)+1"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$month"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>

	<xsl:variable name="yearadj">
		<xsl:choose>
			<!--Handle +XX timezone-->
			<xsl:when test="($hh &lt; $stzh) and ($day = 1) and ($month = 1)">
				<xsl:value-of select="($year)-1"/>
			</xsl:when>
			<xsl:when test="($hh &lt;= $stzh) and ($mm &lt; $stzm) and ($day =
1) and ($month = 1)">
				<xsl:value-of select="($year)-1"/>
			</xsl:when>
			<!--Handle -XX timezone-->
			<xsl:when test="((($hh)-($stzh)) &gt;= 24) and ($day = $maxday) and
($month = 12)">
				<xsl:value-of select="($year)+1"/>
			</xsl:when>
			<xsl:when test="((($hh)-($stzh)) &gt;= 23) and ((($mm)-($stzm))
&gt;= 60) and ($day = $maxday) and ($month = 12)">
				<xsl:value-of select="($year)+1"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$year"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>

	<!--Calculate time in UTC -->
	<xsl:variable name="mmutc">
		<xsl:choose>
			<xsl:when test="$mm &lt; $stzm">
				<xsl:value-of select="(60+$mm)-($stzm)"/>
			</xsl:when>
			<xsl:when test="(($mm)-($stzm)) &gt;= 60">
				<xsl:value-of select="(($mm)-($stzm))-60"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="($mm)-($stzm)"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>
	<xsl:variable name="hhutc">
		<xsl:choose>
			<!--Handle +XX timezone-->
			<xsl:when test="($hh &lt;= $stzh) and ($mm &lt; $stzm)">
				<xsl:value-of select="(23+$hh)-($stzh)"/>
			</xsl:when>
			<xsl:when test="($hh &lt; $stzh) and ($mm &gt;= $stzm)">
				<xsl:value-of select="(24+$hh)-($stzh)"/>
			</xsl:when>
			<xsl:when test="($hh &gt; $stzh) and ($mm &lt; $stzm)">
				<xsl:value-of select="($hh)-($stzh)-1"/>
			</xsl:when>
			<!--Handle -XX timezone-->
			<xsl:when test="((($hh)-($stzh)) &gt;= 23) and ((($mm)-($stzm)) &gt;= 60)">
				<xsl:value-of select="(($hh)-($stzh)+1) mod 24"/>
			</xsl:when>
			<xsl:when test="((($hh)-($stzh)) &gt; 23) and ((($mm)-($stzm)) &lt; 60)">
				<xsl:value-of select="(($hh)-($stzh)) mod 24"/>
			</xsl:when>
			<xsl:when test="((($hh)-($stzh)) &lt; 23) and ((($mm)-($stzm)) &gt;= 60)">
				<xsl:value-of select="(($hh)-($stzh))+1"/>
			</xsl:when>
			<!--We haven't changed day, month, year-->
			<xsl:otherwise>
				<xsl:value-of select="($hh)-($stzh)"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>

	<xsl:value-of select="$yearadj"/>
	<xsl:if test="($monthadj) &lt; 10"><xsl:value-of select="'0'"/></xsl:if>
	<xsl:value-of select="$monthadj"/>
	<xsl:if test="($dayadj) &lt; 10"><xsl:value-of select="'0'"/></xsl:if>
	<xsl:value-of select="$dayadj"/>
	<xsl:if test="($hhutc) &lt; 10"><xsl:value-of select="'0'"/></xsl:if>
	<xsl:value-of select="$hhutc"/>
	<xsl:if test="($mmutc) &lt; 10"><xsl:value-of select="'0'"/></xsl:if>
	<xsl:value-of select="$mmutc"/>
	<xsl:value-of select="$ss"/>
	<xsl:value-of select="' +0000'"/>
	</xsl:template>

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Cast Your Vote

We need your help – Vote for DataDirect XML Products!

  • Best SOA or XML site

Winners and finalists announced at SOA World Conference in November.

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2007 All Rights Reserved.