|
Subject: RE: [xsl] variable as element name; issues with for-each-group From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Wed, 11 Jul 2007 17:34:53 +0100 |
>How do I
> filter out extra elements when any predicates added to * seem
> to break it?
<xsl:for-each-group select="* except author">
or
<xsl:for-each-group select="*[not(self::author)]">
>Is
> there a mechanism to ignore anything before the first "genus"
> when doing the grouping?
<xsl:for-each-group select="* except genus[1]/preceding-sibling::*)"
>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.
You did group-starting-with="family", so it seems likely that
current-group()[1] is a <family> element, which has a complex internal
structure. I suspect you don't want the string-value of the <family>
element, you want the value of its name attribute, that is <family
name="{current-group()[1]/@name}">
> 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).
Almost certainly a context problem. If you're within for-each-group then it
seems unlikely that the context node has a child called superfamily. And
using position() on the rhs of "/" almost certainly means something
different from what you would like it to mean.
Michael Kay
http://www.saxonica.com/
> -----Original Message-----
> From: Thomas Kielczewski [mailto:thomaskiel@xxxxxxxxx]
> Sent: 11 July 2007 16:53
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] variable as element name; issues with for-each-group
>
> 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 -> |
|---|---|---|
| Re: [xsl] variable as element name;, David Carlisle | Thread | [xsl] RE: xsl-list Digest 12 Jul 20, shi wudao |
| Re: [xsl] variable as element name;, David Carlisle | Date | Re: [xsl] Tricky transformation tas, David Carlisle |
| Month |