xsl-list
[Top] [All Lists]

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

2005-05-04 09:58:47


David, WOW!  ... i'm still trying to figure out how it works ...
So, can you explain?  This is like magic..

Have you considered the possibility that it really is magic?
Asking how it works might spoil the fun.
It's just like sawing ladies in half...

Things I don't get:
Oh if you insist...


1)  Variable e2 select.
select="@period_end[. > $e]|$e[. >= current()/@period_end]"


That expression is just me being tricksy, It just sets e2 to being the
maximum of e and the current period_end attribute, ie as you walk along
the list one at a time it keeps a note of the current period end.

I could have written

<xsl:variable name="e2">
 <xsl:choose>
  <xsl:when test="@period_end &gt; $e"><xsl:value-of 
select="@period_end"/></xsl:when>
  <xsl:otherwise><xsl:value-of select="$e"/></xsl:otherwise>
 </xsl:choose>
</xsl:variable>

but that would just make people yearn for XSLT2's

<xsl:variable name="e2" select="max(@period_end,$e)"/>

Whereas the version I used makes XSLT1 look exotic and enticing:-)

How does the pipe work here and is this only evaluating the current B
element, or evaluating all @period_end(s)?

The thing about understanding Xpath expressions is to remember that
things mean what they mean, even if they get used in unexpected places,
so if I'd have gone
select="a|b"
you would probably not have asked what | means: it means select all a's
and all b's and take the union of those two selections.
similarly if I'd have gone
selct="@foo"
you probably wouldn't have asked which element this is the foo atribute
of, it's (just) the curent element.
so putting it all together
@period_end[. &gt; $e]
selects those period_end attributes of the current element for which the
value of the attribute is greater than $e. Since there is only one
period_end  attribute this either selects that attribute (if it is
greater than $e) or selects the empty set otherwise.

the other side of the |
is
$e[. &gt;= current()/@period_end]
the [] predicate is the negation of the last one, so this node set is $e
if the other node set is empty and empty if the other node set is @period_end 

so the | is the union of two node sets, one of which has one attribute
node, the other is empty so $e2 ends up being a node set of exactly one
attribute node, with value the maximum of the two attributes compared.


2)  Right off the bat (first iteration), I don't understand how you
determine the period attribute "ends" value.

You walk along the nodes one at a time, carrying the current best guess
of the end of the period in the parameter $e, as discussed above.
You can tell when to stop because there is no B note that "overlaps"
this current guessed end, ie there is a B that starts before $e2 and
ends after it:

<xsl:when test="../B[(_at_)period_begin &lt;=$e2 and @period_end &gt; $e2]">

If this condition is not satisfied you just process the next node and try
again. You never output any elements until you get to the end of a
range, you just pass the beginning of the range, the current best guess
of the end, and all the B nodes so far collected in the three parameters
b e and g.

Once it is satisfied you can make your wrapper element with the
determined range and then just copy-of $g and the current element
to form the content, then agsin process the next B, this time not
setting any parameters so you initialise a new range.

3)  Variable g select, what does this get you, the ancestor record?
select="/.."

The value on a param setting is only used if a parameter is not
explictly supplied. /.. is the parent of the root node, which doesn't
exist so this is the empty set. If instead I had gone
 <xsl:param name="g" />
the default value would have been an empty string
but then when you try to add teh current node to teh collection when
moving on to the next node:
  <xsl:with-param name="g" select="$g|."/>
The | would generate an error that it can't be used with an empty
string if $g was ""/ If $g is the empty set then $g|. is the union of
the emopty set and the current node, which is the current node.


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

No. The copy-of copies $g (all the B elements picked up earlier in this
range, and . which is the current B element)
the period element isn't copied from anywhere, it's gneretaed as a
literal result element on the line above:
  <period begins="{$b}" ends="{$e2}">


Having just looked over this, I think my XSLT is easier to understand
than my English description of it, so maybe I should just give up and
see if the list auto-documentation-daemon is triggered and documentation
arrives from elsewhere....

David

________________________________________________________________________
This e-mail has been scanned for all viruses by Star. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>