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(_at_)yahoo(_dot_)com]
Sent: 11 July 2007 16:53
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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="{(_at_)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/
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--