[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Grouping repeating elements

Subject: Re: Grouping repeating elements
From: tcn@xxxxxxxxxxxxx (Trevor Nash)
Date: Thu, 12 Jul 2001 11:57:00 GMT
pattern of repeating elements
On Wed, 11 Jul 2001 11:57:07 +0100, Wendell  wrote:

>Hi Till,
>
>At 10:12 AM 7/11/01, Trevor wrote:
>[snip]
>>Have a template matching "name".
>>In the body of this template create the target <person> element,
>>copying the matched <name> element, e.g. using copy-of.
>>To handle elements which always appear, use copy-of with
>>following-sibling to get the *first* element after the name of the
>>given type.  Get this working first, and see that 'phil' ends up with
>>age 28.  Make sure everyone gets just one age!
>>When you have that XPath right, you now have to add a condition that
>>the node you find matches the current <name> node and not a later one.
>>So, add a further condition that the <name> node before the one you
>>have found is the same node as the one matched in your template: use
>>preceding-sibling and generate-id().
>>
>>Have a try at this yourself, if you get stuck ask again.
>
>And after you've got it working, ask again and we'll tell you about the 
>Advanced Technique using keys (the Topic of the Week) to simplify such 
>"levitation" problems (by which I mean making implicit structures explicit)....
>
>Cheers,
>Wendell
>
I think what Wendell is referring to is that instead of writing this
(tested with Saxon 6.0.2) (a) :

<xsl:template match="name">
   <person>
       <xsl:variable name="id" select="generate-id()" />
       <xsl:copy-of select="."/>
       <xsl:copy-of select="following-sibling::firstname[1]"/>
       <xsl:copy-of select="following-sibling::age[1]
            [generate-id(preceding-sibling::name[1])=$id]" />
   </person>
</xsl:template>
<xsl:template match="firstname|age" />

You can write (b):

<xsl:key
    name="following-name"
    match="firstname|age"
    use="generate-id(preceding-sibling::name[1])"
/>
<xsl:template match="name">
   <person>
       <xsl:copy-of select=".|key('following-name', generate-id())" />
   </person>
</xsl:template>
</xsl:stylesheet>
<xsl:template match="firstname|age" />

This is not exactly equivalent:
 - if your input contained <name/><age/><age/><name/>... then the key
method copies both <age/> elements, while (a) copies only the first.
This may or may not be what is needed.
 - the key method copies elements in the order they appear in the
input document, rather than in an order you specify (this can be
changed, but then you lose some of the brevity which is a main
attraction of using keys)
 - if you are dealing with large documents, the performance
characteristic of the first method is better, as long as you have a
processor which takes the obvious short cut when it sees expressions
like following-sibling::x[1].  If it doesn't, the key method is
better, but you are likely in trouble with either approach.

BTW you can get from (a) to (b) with some simple algebra.  The core of
method (a) is the expression:

  following-sibling::age[1]
            [generate-id(preceding-sibling::name[1])=$id]

If there is at most one <age/> element between each <name/> then this
is equivalent to:

   //age[generate-id(preceding-sibling::name[1])=$id]

which is an example of a general form 

    //pattern[f(.)=string-value]

where f is a function returning a string.  Whenever you see this you
can rewrite it as:

   <xsl:key name="k" match="pattern" use="f(.)" />
and then
   key ('k', string-value)

I hope somebody else enjoyed that too ;-)

Regards,
Trevor Nash
--
Traditional training & distance learning,
Consultancy by email

Melvaig Software Engineering Limited
voice:     +44 (0) 1445 771 271 
email:     tcn@xxxxxxxxxxxxx

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.