Subject: [xsl] variable as element name; issues with for-each-group From: Thomas Kielczewski <thomaskiel@xxxxxxxxx> Date: Wed, 11 Jul 2007 08:53:07 -0700 (PDT) |
Hi, Please bear with me as this is a triple-shot of newbie questions. I have the following simplified XML: <section name="Species Accounts"> <author>someone</author> <chapter>1</chapter> <superfamily>True Butterflies</superfamily> <description> <p>The true butterflies have antennae with rounded clubs</p> </description> <family> <name>Swallowtails</name> <description> <p>The swallowtails are worldwide in distribution.</p> </description> </family> <species> <name>Cattle Heart Swallowtail</name> </species> <genus> <name>Pipevine Swallowtails</name> <description>This is a primarily tropical genus.</description> </genus> <species> <name>Pipevine Swallowtail</name> </species> <species> <name>Polydamas Swallowtail</name> </species> <chapter>2</chapter> ... </section> I am giving it this structure: <section> <chapter id="1"> <superfamily name="..."> <description/> <family name="..."> <description/> <species>...</species> ... <genus> <species>...</species> ... </genus> ... </family> <superfamily> </chapter> <chapter> ... </chapter> </section> This is going well, but with a few sticky issues: 1) This is my outer for-each-group: <xsl:for-each-group group-starting-with="chapter" select="*"> <chapter> ... </chapter> </xsl:for-each-group> The problem is that this seems to pick up orphan elements I'd rather leave alone, like "author" in the XML above, and recasting them as "chapter" (complete with "id"). How do I filter out extra elements when any predicates added to * seem to break it? Same idea when I group "species" under "genus", because some species are not in a genus but directly under "family." Is there a mechanism to ignore anything before the first "genus" when doing the grouping? (This is where the higher-order species will always be located.) Or is this done with some crafty predicates? 2) I'm having trouble with current-group() and position() in for-each-group. Basically, nothing works. <family name="{current-group()[1]}"> gives me the whole sequence when it's clear it should only return the first element. Then, rather than explicitly stating the cutoff point in <xsl:for-each-group group-starting-with="superfamily" select="subsequence(current-group(),2)"> I'd like to replace subsequence(current-group(),2) with something like subsequence(current-group(),./superfamily[1]/position()) but again it doesn't seem to work (seems to come up with no matches). This is the entire XSLT: <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes" method="xml" /> <xsl:strip-space elements="*" /> <xsl:template match="section"> <xsl:result-document href="a.xml"> <section title="{@name}"> <xsl:for-each-group group-starting-with="chapter" select="*"> <chapter id="{current-group()[1]}"> <xsl:for-each-group group-starting-with="superfamily" select="subsequence(current-group(),2)"> <superfamily name="{current-group()[1]}"> <xsl:for-each-group group-starting-with="family" select="subsequence(current-group(),2)"> <family name="{current-group()[1]}"> <xsl:copy-of select="following::description[1]" /> <xsl:for-each-group group-starting-with="genus" select="subsequence(current-group(),2)"> <genus name="{current-group()[1]}"> <xsl:for-each-group group-starting-with="species" select="subsequence(current-group(),2)"> <species name="{current-group()[1]}"> <xsl:copy-of select="."/> </species> </xsl:for-each-group> </genus> </xsl:for-each-group> </family> </xsl:for-each-group> </superfamily> </xsl:for-each-group> </chapter> </xsl:for-each-group> </section> </xsl:result-document> </xsl:template> </xsl:stylesheet> 3) Eventually, I'd like to clean up the repeating elements of my template and make each level a template call using parameters. But I can't even make a call to a variable work. I declare my variable as a top-level element, shouldn't it be visible to all? What crucial ingredient am I missing? I tried this with braces and without: <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> ... <xsl:variable name="level2" select="'superfamily'" /> <xsl:template match="section"> ... <xsl:for-each-group group-starting-with="{$level2}" select="subsequence(current-group(),2)"> <xsl:element name="{$level2}"> <xsl:attribute name="name" select="current-group()[1]"/> ... </xsl:element> </xsl:for-each-group> </xsl:template> This newbie has been XSLT'ing for a little over a month now. He's using Saxon 8B on <oXygen/> 8.2. Thanks, and congratulations for the great discussions that occasionally pop up on this forum. Thomas Kielczewski Modality, LLC Durham, NC ____________________________________________________________________________________Ready for the edge of your seat? Check out tonight's top picks on Yahoo! TV. http://tv.yahoo.com/
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Deepak Jain wants to chat, Deepak Jain | Thread | Re: [xsl] variable as element name;, David Carlisle |
Re: [xsl] the document() in IE, David Carlisle | Date | Re: [xsl] variable as element name;, David Carlisle |
Month |