Subject: RE: [xsl] grouping sequence question From: TSchutzerWeissmann@xxxxxxxxxxxxxxxx Date: Fri, 29 Nov 2002 14:02:12 -0000 |
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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] grouping sequence questio, TSchutzerWeissmann | Thread | RE: [xsl] grouping sequence questio, Paul |
RE: [xsl] grouping sequence questio, TSchutzerWeissmann | Date | Re: [xsl] Looking for the rigth sel, Sorin Marti |
Month |