Re: [xsl] A challenge.. Group Periods of Data (1..5, 2..8, 4..9) (10..12; 10..14)

Subject: Re: [xsl] A challenge.. Group Periods of Data (1..5, 2..8, 4..9) (10..12; 10..14)
From: Karl Stubsjoen <kstubs@xxxxxxxxx>
Date: Tue, 3 May 2005 14:42:16 -0700
Dimitre:

*weeping* I am not able to transform with XSLT2 : (
Do you have an "elegant" XSLT1 solution?

Karl

On 5/3/05, Dimitre Novatchev <dnovatchev@xxxxxxxxx> wrote:
> 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(.)
>         &lt;=
>           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::*)
>                               [. &lt;&lt; $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