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

Unbounded element grouping/concatenation

Subject: Unbounded element grouping/concatenation
From: "Gupta, Raman K [CI]" <raman.k.gupta@xxxxxxxxxxxxx>
Date: Mon, 8 Dec 2003 21:53:26 -0500
element grouping
Hello,

I am trying to do something similar to the XSLT FAQ on Grouping,
question 17.  Concatenate two elements. Here is the original question
for your reference:

>   <record n="1" type="normal">
>     <foo> <x>... <y>...</y> ...</x> </foo>
>     <bar> <things> ... </things> </bar>
>   </record>
>   <record n="2" type="normal">
>     <foo> <x>... <y>...</y> ...</x> </foo>
>   </record>
>   <record n="3" type="continuation">
>     <bar> <things> ... </things> </bar>
>   </record>
>   <record n="4" type="normal">
>     <foo> <x>... <y>...</y> ...</x> </foo>
>     <bar> <things> ... </things> </bar>
>   </record>

In response to that post, Jeni Tennison gave a solution and wrote

> > Note that this method only works if there's only one continuation
> > for each normal record. If there might be more, then I'd use a 
> > key-based solution where you index each continuation record by its 
> > closest normal record and use that to identify which extra fields 
> > need to be added to the new record. If you need help with that, 
> > let us know.

Now, in my case I do have an unbounded number of continuation records for 
each normal record, and I need to concatenate all of them.

I followed Jeni's advice, and created a key as follows (this is my 
understanding of her directions, I could be wrong):

<xsl:key name="continuation-by-record"
  match="record[@type='continuation']"
  use="generate-id(preceding-sibling::record[@type='normal'][1])"/>
  
and then used that key to copy the appropriate continuation records for
each normal record:

<xsl:template match="records">
  <xsl:apply-templates select="record[@type = 'normal']" />
</xsl:template>

<xsl:template match="record">
  <record>
    <xsl:copy-of select="*" />
    <xsl:copy-of select="key('continuation-by-record', generate-id(.))/*"/>
  </record>
</xsl:template>

This works, except that it is *very* slow for anything more than a few
continuation records, presumably because the processer has to iterate,
for every continuation record, over all preceding sibling continuation 
records until it gets to a normal record (using xalan-j 2.4.0). For n
records,
this ends up being n factorial iterations.

I also tried a recursive template for the continuation record that only 
recurses if the following-sibling[1] is a continuation record also. 
This was *much* faster, but unfortunately for very large numbers 
of continuation records, the recursion causes a stack overflow.

Is there some other non-recursive efficient way of doing this? I am open
to multi-step transforms, etc.

Cheers,
Raman Gupta

 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.