Subject: Re: [xsl] A challenge.. Group Periods of Data (1..5, 2..8, 4..9) (10..12; 10..14) From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Wed, 4 May 2005 07:29:31 +1000 |
On 5/4/05, Karl Stubsjoen <kstubs@xxxxxxxxx> wrote: > A challenge, group the following XML into 2 periods. The periods are > arbitrary, but for this example they happen to be: > Period 1: 1 - 12 > Period 2: 14 - 30 > > Expected Result: > <result> > <period begins="1" ends="12"> > <B period_begin="1" period_end="5"/> > <B period_begin="2" period_end="7"/> > <B period_begin="3" period_end="10"/> > <B period_begin="4" period_end="12"/> > </period> > <period begins="14" ends="30"> > <B period_begin="14" period_end="16"/> > <B period_begin="16" period_end="20"/> > <B period_begin="16" period_end="30"/> > </period> > </result> > > Source XML / Result (sorted) > <A> > <B period_begin="1" period_end="5"/> > <B period_begin="2" period_end="7"/> > <B period_begin="3" period_end="10"/> > <B period_begin="4" period_end="12"/> > <B period_begin="14" period_end="16"/> > <B period_begin="16" period_end="20"/> > <B period_begin="16" period_end="30"/> > </A> > > Source XML / Result (un-sorted) > <A> > <B period_begin="14" period_end="16"/> > <B period_begin="2" period_end="7"/> > <B period_begin="16" period_end="20"/> > <B period_begin="1" period_end="5"/> > <B period_begin="4" period_end="12"/> > <B period_begin="16" period_end="30"/> > <B period_begin="3" period_end="10"/> > </A> Hi Karl, This has an elegant solution using the f:foldl() function of FXSL. Here, I'm giving a "first glance" XSLT 2.0 solution without using FXSL. This transformation: <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" > <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="A"> <xsl:variable name="vStarting" select= "*[not(@period_begin/xs:integer(.) <= preceding-sibling::*/@period_end/xs:integer(.) )]"> </xsl:variable> <xsl:for-each select="$vStarting"> <xsl:variable name="vPos" select="position()"/> <period start="{@period_begin}" end="{if ($vPos = last() ) then max( (. | following-sibling::*) /@period_end/xs:integer(.) ) else max( (. | following-sibling::*) [. << $vStarting[$vPos + 1]] /@period_end/xs:integer(.) ) }" /> </xsl:for-each> </xsl:template> </xsl:stylesheet> when applied on this source xml document (added one more group to yours): <A> <B period_begin="1" period_end="5"/> <B period_begin="2" period_end="7"/> <B period_begin="3" period_end="10"/> <B period_begin="4" period_end="12"/> <B period_begin="14" period_end="16"/> <B period_begin="16" period_end="20"/> <B period_begin="16" period_end="30"/> <B period_begin="32" period_end="33"/> <B period_begin="33" period_end="38"/> </A> produces the wanted result: <period start="1" end="12"/> <period start="14" end="30"/> <period start="32" end="38"/> Cheers, Dimitre Novatchev
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] A challenge.. Group Perio, Wendell Piez | Thread | Re: [xsl] A challenge.. Group Perio, Karl Stubsjoen |
Re: [xsl] XSL-FO / XSLT Transformat, craig webber | Date | Re: [xsl] XSL-FO / XSLT Transformat, JBryant |
Month |