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

Re: Wrap changing element sequence into container: wit

Subject: Re: Wrap changing element sequence into container: with 'for-each-group'?
From: Yves Forkl <Y.Forkl@xxxxxx>
Date: Tue, 30 Jan 2007 18:13:30 +0100
Re:  Wrap changing element sequence into container: wit
What I am having trouble to do is adding a container around a specific
(fixed-order) sequence of those 'p' elements, say, 'p[style="a"]' and 'p[style="b"]', where the first of these may not always occur.

Michael Kay wrote:


If you can identify a comparison between two adjacent siblings which, if
true, means that they go in different containers, then you can use
group-starting-with. For example, in this case the condition might be that
the element is not immediately preceded by an element with a value for
@style that is alphabetically less than the current element's @style:

group-starting-with="p[not(preceding-sibling::p[1][@style lt
current()/@style])]"

Thank you for your useful explanations. Actually, I am faced with grouping in a situation which is a bit more complex. I would like to expose it on behalf of elements with distinct GIs, dropping the above example of "p" elements with "style" attributes to make it easier.


Among the child elements of my "root" element, some adjacent children need to go into some container, and this occurs repeatedly. I can make out two issues when trying to use xsl:for-each-group in this case:

1) The names of those children that should get together are very dissimilar, so functions that analyze the name like in the example above won't help much. Let's say I have "abc" and "xyz" that I want to group: how can I select the first instance of either of them, in order to add the container only once?

2) I fail to see how I can repeatedly group some children, when in between are some children that are not to be grouped. Do I need to apply recursion when working my way through the children?


Abel proposed using modes, along these lines (modified by me, so errors are mine):


>  <xsl:template match="*[starts-with(name(), 'b')][1]">
>     <container>
>       <xsl:apply-templates
>         select="self::* | following-sibling::*"
>         mode="within_container"/>
>     </container>
>   </xsl:template>
>
>   <xsl:template match="*[starts-with(name(), 'b')]"
>     mode="within_container">
>       <xsl:copy>
>           <xsl:apply-templates select="node() | @*"
>             mode="#current"/>
>       </xsl:copy>
>   </xsl:template>
>
>   <xsl:template match="*[not(starts-with(name(), 'b'))]">
>       <xsl:copy>
>           <xsl:apply-templates select="node() | @*" />
>       </xsl:copy>
>   </xsl:template>

This looks even more promising: I suspect taking out several groups of children is easier to do this way than with xsl:for-each-group. Is this true?

But using modes I face the same problem concerning the identification of the nodes to group (which in the above example all had names starting with "b", which isn't real) and of selecting the very first instance of them.

So how could I proceed?

Yves

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.