Subject: Re: 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 16:02:17 -0700
|
A solution... (sorry, I lean heavily on xxx:node-set)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:ms="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml"/>
<xsl:variable name="MIN_RANGE_VALUE">0</xsl:variable>
<xsl:variable name="MAX_RANGE_VALUE">99999</xsl:variable>
<xsl:variable name="CURRENT" select="/"/>
<xsl:template match="A">
<xsl:variable name="for_period_match">
<xsl:apply-templates select="B" mode="for_period_match" />
</xsl:variable>
<xsl:variable name="periods">
<xsl:element name="result">
<xsl:apply-templates select="ms:node-set($for_period_match)//B"
mode="periods"/>
</xsl:element>
</xsl:variable>
<xsl:variable name="periods_transformed">
<xsl:apply-templates select="ms:node-set($periods)//result"
mode="transform_periods"/>
</xsl:variable>
<xsl:element name="result">
<xsl:copy-of select="ms:node-set($periods_transformed)"/>
</xsl:element>
</xsl:template>
<xsl:template match="result" mode="transform_periods">
<xsl:apply-templates select="periods" mode="transform_periods"/>
</xsl:template>
<xsl:template match="periods" mode="transform_periods">
<xsl:element name="periods">
<xsl:attribute name="begin"><xsl:value-of
select="B[1]/@period_begin"/></xsl:attribute>
<xsl:attribute name="end"><xsl:value-of
select="B[last()]/@period_end"/></xsl:attribute>
<xsl:apply-templates select="B" mode="transform_periods"/>
</xsl:element>
</xsl:template>
<xsl:template match="B" mode="transform_periods">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="B[preceding-sibling::B/@period_begin <=
@period_begin and preceding-sibling::B/@period_end >=
@period_begin]" mode="for_period_match">
<xsl:apply-templates select="* | @*" mode="for_period_match"/>
</xsl:template>
<xsl:template match="* | @*" mode="for_period_match">
<xsl:copy>
<xsl:apply-templates select="* | @*" mode="for_period_match"/>
</xsl:copy>
</xsl:template>
<xsl:template match="B" mode="periods">
<xsl:variable name="min_range_value" select="@period_begin"/>
<xsl:variable name="max_range_value">
<xsl:choose>
<xsl:when test="following-sibling::B/@period_begin">
<xsl:value-of select="following-sibling::B/@period_begin"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$MAX_RANGE_VALUE"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="periods">
<xsl:apply-templates select="$CURRENT//B[@period_begin >=
$min_range_value and @period_end < $max_range_value]" />
</xsl:element>
</xsl:template>
<xsl:template match="* | @*">
<xsl:copy>
<xsl:apply-templates select="* | @*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
On 5/3/05, Michael Kay <mike@xxxxxxxxxxxx> wrote:
> >
> > >You mean you want the
> > > stylesheet to detect a time at which no sessions are alive,
> > and use that as
> > > a boundary between periods? What if there is no such time?
> >
> > First element of period: first element or first element where
> > period_begin does not fall within previous sibling period_begin and
> > period_end.
> >
> > Last element of period: last element match where period_begin falls
> > within previous sibling period_begin and period_end.
> >
> > > What if there are several?
> >
>
> This then sounds like a simple extension of Wendell's stylesheet, where
> instead of the list of periods being supplied as a parameter, it is
> constructed by a prescan of the data: the set of period boundaries is the
> set of session endtimes that do not overlap any session, i.e.
>
> //session/@endtime[every $s in //session satisfies ($s/@starttime <= . or
> $s/@endtime >= .)]
>
> (Sorry, I've forgotten what the actual element and attribute names were).
>
> Someone who enjoys coding with one hand tied behind their back can no doubt
> give you an XSLT 1.0 version of that...
>
> Michael Kay
> http://www.saxonica.com/
|