Subject: Re: XPath's role (Was: Re: [xsl] Re: . in for) From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Mon, 7 Jan 2002 16:40:56 +0000 |
Mike Kay wrote: > Attached, for information, is a position paper which was used during > the WG deliberations to justify the decision. It was drafted by me > under the direction of the XSL WG, and accepted by the group. [snip] > 3.3 Are range variables needed? [snip] > With sequences, it will be much more common to process several > collections (trees or sequences) at the same time and do joins > between them. It's easy to find use cases where the single "." is > obviously inadequate, for example you can't rewrite: > > for $i in 1 to 10 return $items[$i] > > without a range variable. > > In this case you could write > > $items[position() < 11] With a simple mapping operator, you could also do this with: (1 to 10) -> sublist($items, ., 1) > but what about > > for $i in (count($items) to count($items) - 5) return $items[$i] Again the sublist() function combined with the simple mapping operator comes in handy: (count($items) to count($items) - 5) -> sublist($items, ., 1) If I was doing this a lot I'd probably write myself a more general function of the form: <xsl:function name="my:sublist"> <xsl:param name="seq" type="item*" /> <xsl:param name="positions" type="integer*" /> <xsl:result select="if (empty($positions)) then () else ($seq[$positions[1]], my:sublist($seq, sublist($positions, 2)))" /> </xsl:function> and then do: my:sublist($items, (1 to 10)) my:sublist($items, (count($items) to count($items) - 5)) > Here we are not returning output in document order, so we can't fall > back on the boolean test against position(). > > There are plenty of other examples. A more obvious join example is > to find duplicates in two files, where duplication is tested under a > collation: > > for $i in document('doc1.xml')//item, > $j in document('doc2.xml')//item > return > if (compare($i/@code, $j/@code, 'case-folded-collation")) > then $i else () For this example, you need a recursive function: <xsl:function name="my:join"> <xsl:param name="is" type="node*" /> <xsl:param name="js" type="node*" /> <xsl:variable name="i" select="$is[1]" /> <xsl:result select="if (empty($is)) then () else (if (compare($i/@code, $j/@code, 'case-folded-collation') then $i else (), my:join(sublist($is, 2), $js))" /> </xsl:function> and a function call that looks like: my:join(document('doc1.xml')//item, document('doc2.xml')//item) Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: XPath's role (Was: Re: [xsl] Re, Michael Kay | Thread | Re: XPath's role (Was: Re: [xsl] Re, Brian Smith |
Re: [xsl] the problem with include , Matt G. | Date | RE: [xsl] need only one node to be , Michael Kay |
Month |