[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Is this about grouping ?
Hi Benoit, > Of course, I should encapsulate <a> to <i> under <group>. > > But still I'm stuck with my XSLT. Leaving aside the indentation issue, and assuming that you use group elements to indicate how the a and b elements apply to particular f to i elements, you can do the following: (a) declare the key to access the group elements according to a particular combination of a and b. You can use a concatenation of a and b to give the key value for each group so that you are grouping by the combination of the two values rather than by just one: <xsl:key name="groups" match="group" use="concat(a, ':', b)" /> (b) apply templates to the first group with a particular a+b value. You want to find the group that is the first group returned by the key with that particular combination of a and b, and apply templates to it: <xsl:template match="topic"> <topic> <xsl:apply-templates select="group[generate-id() = generate-id(key('groups', concat(a, ':', b))[1])]" /> </topic> </xsl:template> (c) have a template that matches a group, outputs the values of a and b for that group and then copies the values of f to i of all the groups with that particular a+b combination, as retrieved from the key. You probably want to use a group element to distinguish the output from this group from any others: <xsl:template match="group"> <group> <xsl:copy-of select="a" /> <xsl:copy-of select="b" /> <xsl:variable name="groups" select="key('groups', concat(a, ':', b))" /> <xsl:copy-of select="$groups/*[self::f or self::g or self::h or self::i]" /> </group> </xsl:template> That's the Muenchian solution to the basic grouping problem. You have a couple of additional twists which alter it a little. First, you don't want to use a group element in the output to mark off the groups, but instead indent the elements to varying degrees. I think this is a dangerous way of indicating structure in an XML document because whitespace is often ignored (especially if you use MSXML), which means you lose precious information. If you really want to use indentation, then you need to use xsl:text elements to include the significant whitespace. In your sample XSLT, you've been using *empty* xsl:text elements to mark off whitespace - this is a technique that only works if you have some non-whitespace characters alongside the whitespace ones; if you want to include a number of spaces, you have to put that in the *content* of the xsl:text, e.g.: <xsl:for-each select="$elements"> <xsl:text>
 </xsl:text> <xsl:copy-of select="." /> </xsl:for-each> (The 
 gives a line break.) The second complication arises if you don't use group elements in your source XML. That means you have to use some other element to indicate the groups - the a element is a good bet - and use the following-sibling axis to access the relevant elements: <xsl:key name="groups" match="group" use="concat(., ':', following-sibling::b[1])" /> <xsl:template match="topic"> <topic> <xsl:apply-templates select="a[generate-id() = generate-id(key('groups', concat(a, ':', following-sibling::b[1]))[1])]" /> </topic> </xsl:template> <xsl:template match="a"> <group> <xsl:copy-of select="." /> <xsl:variable name="b" select="following-sibling::b[1]" /> <xsl:copy-of select="$b" /> <xsl:variable name="groups" select="key('groups', concat(., ':', $b))" /> <xsl:copy-of select="$groups/following-sibling::f[1] | $groups/following-sibling::g[1] | $groups/following-sibling::h[1] | $groups/following-sibling::i[1]" /> </group> </xsl:template> Or you might find that a different type of grouping method, such as one that steps through the elements one by one to create the groups, is easier to handle. Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|