>4) The copy of within the element period within the otherwise then the
>apply templates rule, it obviously creates the new <period/> element,
>but I don't see how your recursive template call inserts the
>"members", I don't get how you are preserving the member element of
>period.
The <xsl:when test="..."> checks whether thare are any <B> elements which
overlap our current begin/end. If so we add the current <B> to an
"accumulator" ($g), and recursively call ourselves with the *next* <B>.
Note that the input <B>s are sorted by their begin/end--<B> elements that
overlap our current <B> must be in the immediately-following vicinity.
(Remember that the respondent posted another "tree-walking" strategy a few
days ago, related to the issue of finding processing-instructions.)
A more detailed explanation follows:
>From: David Carlisle <davidc@xxxxxxxxx>
>Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>Subject: Re: [xsl] A challenge.. Group Periods of Data (1..5, 2..8, 4..9)
>(10..12; 10..14)
>Date: Wed, 4 May 2005 13:03:20 +0100
>
>
><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> version="1.0">
>
>
><xsl:output indent="yes"/>
>
><xsl:template match="A">
><result>
><xsl:apply-templates select="B[1]"/>
></result>
></xsl:template>
This kicks off the process with the first <B>
><xsl:template match="B">
> <xsl:param name="b" select="@period_begin"/>
> <xsl:param name="e" select="@period_end"/>
> <xsl:param name="g" select="/.."/>
><xsl:variable name="e2" select="@period_end[. > $e]|$e[. >=
>current()/@period_end]"/>
The first time around no params are passed in. So $b defaults to
@period_begin, $e to @period_end, and $g to an empty set. $e2, the "new
end" is calculated as either @period_end (if greater-than the passed-in $e)
or simply $e (if it's already equal-or-greater than the current <B>'s
@period_end). Of course, the first time around, for the forst <B> as it
were, it is simply $e.
So now we're armed with a begin and an end, and if we don't find any more
<B>s whose periods intersect or overlap this one, we've just found a period.
Testing for overlaps is what the next section does.
><xsl:choose>
><xsl:when test="../B[@period_begin <=$e2 and @period_end > $e2]">
> <xsl:apply-templates select="following-sibling::B[1]">
> <xsl:with-param name="b" select="$b"/>
> <xsl:with-param name="e" select="$e2"/>
> <xsl:with-param name="g" select="$g|."/>
> </xsl:apply-templates>
></xsl:when>
What the test asks is this: are there any <B>s whose @period_begin is less
than $e2, and whose @period_end id greater than $e2. Pretty
straightforward. The existence of such <B>s implies that those <B>s
intersect our current begin/end.
See the diagram below:
b=======$e2 (the current <B>)
........2b======2e
................................3b=======3e
b--e2 is our current period. The 2b--2e pair intersects our period, so we
need to extend our currently-known end, $e2, to 2e. We do this by
recursively processing the intersecting node, passing in our currently-known
limits for $b, and the "end" $e2. We also pass in the current <B> via the
param nodeset $g, since our it falls in, and will be subsumed by, the
period.
> <xsl:otherwise>
> <period begins="{$b}" ends="{$e2}">
> <xsl:copy-of select="$g|."/>
> </period>
Otherwise, i.e. we have no intersecting <B>s, we have just found a period,
so print it out. Remember that $g is the "accumulation" of all <B>s we've
seen thus far that fall in this period.
> <xsl:apply-templates select="following-sibling::B[1]"/>
Restart the process with the next <B>
></xsl:otherwise>
></xsl:choose>
></xsl:template>
>
></xsl:stylesheet>
>
>
>
><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>
>
>
>
>
>
>$ saxon period.xml period.xsl
><?xml version="1.0" encoding="utf-8"?>
><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>
> <period begins="32" ends="38">
> <B period_begin="32" period_end="33"/>
> <B period_begin="33" period_end="38"/>
> </period>
></result>
>
_________________________________________________________________
Is your PC infected? Get a FREE online computer virus scan from McAfee.
Security. http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963