RE: [xsl] grouping sequence question

Subject: RE: [xsl] grouping sequence question
From: Paul <reganmian@xxxxxxxxx>
Date: Fri, 29 Nov 2002 08:59:27 -0800 (PST)
Hey Tom

Thanks you for yr interesting solution !! 

Paul

--- TSchutzerWeissmann@xxxxxxxxxxxxxxxx wrote:
> Sorry - sent the last one prematurely...
> 
> [...]
> > what if I can't evaluate by string->
> > not(start-with(@ref, 'GRP')), but need to judge
> from
> > whether the element can apply another templates.
> > because there are lots different groups, and
> naming by
> > different people, etc.
> > such as , I add a GRP xs:element in the schema
> which
> > is tailor for this 'GRP2'
> > <xs:element name="GRP2">
> > 	<xs:complexType>
> > 		<xs:sequence>
> > 			<xs:element ref="GRP-for-mail"
> > maxOccurs="unbounded"/>
> > 		</xs:sequence>
> > 	</xs:complexType>
> > </xs:element>
> 
> Nested groups are a bit more complicated, so I'm
> going to stick with
> defining group elements as having a ref attribute
> that begins with "GRP". 
> 
> Let's say you want to output this:
> Group starts
> ---> apply templates to any child group (ie,
> recurse)
> Group ends
> Group members.
> 
> Since a "child group" isn't going to be a direct
> child node, you can either
> set up an XPath that can cope with the hierarchy of
> xs:complexType,
> xs:sequence, whatever, or you could use a key -
> 
> <xsl:key name="childGRPs"
> match="xs:element[starts-with(@ref, 'GRP')]"
>  
>
use="generate-id(ancestor::xs:element[starts-with(@ref,
> 'GRP')][1])"/>
> 
> The [1] makes sure that you only recurse one level
> at a time, giving you
> child groups but no grandchild groups.
> 
> The real complication though, is the first key. This
> is because you don't
> want to associate elements with a preceding group
> that's nested deeper than
> they are, so you need to alter the preceding axis
> and only consider
> preceding-siblings or ancestors of
> preceding-siblings...
> 
> <xsl:key name="byGRP" 
> match="xs:element[not(starts-with(@ref, 'GRP'))]"
>  
>
use="generate-id(ancestor-or-self::*/preceding-sibling::xs:element
>        [starts-with(@ref, 'GRP')][1])"/>
>  
> Then you just need to set the recursive template
> going by sending the first
> level of groups to it:
> (email resumes...)
> 
> <xsl:template match="/xs:schema/xs:element">
>   <xsl:apply-templates
> select="//xs:element[starts-with(@ref, 'GRP')]
>                 
> [not(ancestor::xs:element[starts-with(@ref,
> 'GRP')])]"
>     mode="recurse"/>
> </xsl:template>
> 
> The whole thing looks like this:
> 
> <xsl:key name="childGRPs"
> match="xs:element[starts-with(@ref, 'GRP')]"
>  
>
use="generate-id(ancestor::xs:element[starts-with(@ref,
> 'GRP')][1])"/>
> 
> <xsl:key name="byGRP" 
> match="xs:element[not(starts-with(@ref, 'GRP'))]"
>   use="generate-id(
>       
> ancestor-or-self::*/preceding-sibling::xs:element
>        [starts-with(@ref, 'GRP')][1])"/>
> 
> <xsl:template match="/xs:schema/xs:element">
>   <xsl:apply-templates
> select="//xs:element[starts-with(@ref, 'GRP')]
>                 
> [not(ancestor::xs:element[starts-with(@ref,
> 'GRP')])]"
>     mode="recurse"/>
> </xsl:template>
> 
> <xsl:template match="xs:element" mode="recurse">
>   <!-- for each group -->
>     <xsl:variable name="me" select="generate-id()"/>
> 
>     Group <xsl:value-of select="@ref"/> Starts     
>     
>     <xsl:apply-templates
> select="key('childGRPs',$me)" mode="recurse"/>
>    
>     Group <xsl:value-of select="@ref"/> Ends.
>                                         
>     <xsl:for-each select="key('byGRP',$me)">
>       <xsl:value-of select="@ref"/> Starts
>     </xsl:for-each>
>     
>     <xsl:for-each select="key('byGRP',$me)">
>       <xsl:value-of select="@ref"/> Ends
>     </xsl:for-each>
> 
> </xsl:template>
> 
> 
>  XSL-List info and archive: 
> http://www.mulberrytech.com/xsl/xsl-list
> 


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

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


Current Thread