Subject: [xsl] Re: last(): selecting the last one? From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Mon, 22 Apr 2002 06:50:35 -0700 (PDT) |
> when xml-file contains several elements (information)and they have > element which tells the date of input and then there is element that > tells the clock time of input and another element called subject. > > How can I find out which one is the last one and > then select it's subject elements content? The FXSL functional programming library is ideally suited for solving such problems. Simply use (call) the maximum() function (template), passing to it your own comparison function, like this: testMaximumDate.xsl: ------------------- <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:vendor="urn:schemas-microsoft-com:xslt" xmlns:MycompareDates="MycompareDates" exclude-result-prefixes="xsl MycompareDates vendor" > <xsl:import href="maximum.xsl"/> <xsl:output omit-xml-declaration="yes"/> <!-- This transformation must be applied to: date-time.xml.xml --> <MycompareDates:MycompareDates/> <xsl:template match="/"> <xsl:variable name="vCMPFun" select="document('')/*/MycompareDates:*[1]"/> <xsl:variable name="vrtfResult"> <xsl:call-template name="maximum"> <xsl:with-param name="pList" select="/*/*"/> <xsl:with-param name="pCMPFun" select="$vCMPFun"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="vendor:node-set($vrtfResult)/*/subject"/> </xsl:template> <xsl:template name="MycompareDates" match="MycompareDates:*"> <xsl:param name="arg1"/> <xsl:param name="arg2"/> <xsl:variable name="vDate1" select="translate($arg1/date, '/', '')"/> <xsl:variable name="vDate2" select="translate($arg2/date, '/', '')"/> <xsl:choose> <xsl:when test="$vDate1 > $vDate2">1</xsl:when> <xsl:when test="$vDate1 = $vDate2"> <xsl:variable name="vTime1" select="translate($arg1/time, ':APM', '') + 120000 * (substring($arg1/time, 9,2)='PM')"/> <xsl:variable name="vTime2" select="translate($arg1/time, ':APM', '') + 120000 * (substring($arg1/time, 9,2)='PM')"/> <xsl:if test="$vTime1 > $vTime2">1</xsl:if> </xsl:when> </xsl:choose> </xsl:template> </xsl:stylesheet> When applied on the following source xml document: date-time.xml: ------------- <contents> <entry> <date>2002/02/13</date> <time>10:24:11AM</time> <subject>Subject1</subject> </entry> <entry> <date>2002/02/11</date> <time>10:24:11AM</time> <subject>Subject2</subject> </entry> <entry> <date>2002/02/13</date> <time>10:24:11PM</time> <subject>Subject3</subject> </entry> <entry> <date>2002/02/10</date> <time>10:24:11AM</time> <subject>Subject4</subject> </entry> <entry> <date>2002/02/15</date> <time>10:24:11AM</time> <subject>Subject5</subject> </entry> <entry> <date>2002/02/15</date> <time>10:24:11PM</time> <subject>Subject6</subject> </entry> <entry> <date>2002/02/13</date> <time>10:24:11AM</time> <subject>Subject7</subject> </entry> </contents> The result of the transformation is: Subject6 Another way to find a maximum is to use xsl:sort, but the above solution has at least two advantages over sorting: 1. Sometimes it is very difficult (if possible at all) to express the sorting criterion as a single XPath expression. In all such cases it would be literally impossible to perform the sorting using xsl:sort 2. Finding a maximum through sorting has a time complexity O(N*log2(N)), which is greater than the linear complexity of the above algorithm. In case the maximum is sought over a long list of elements, then the linear algorithm should be preferred. Cheers, Dimitre Novatchev. __________________________________________________ Do You Yahoo!? Yahoo! Games - play chess, backgammon, pool and more http://games.yahoo.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] last(): selecting the las, Jarno . Elovirta | Thread | [xsl] leaving and thanks, Ralph Holz |
RE: [xsl] last(): selecting the las, Jarno . Elovirta | Date | RE: [xsl] making html output for ap, Hunsberger, Peter |
Month |