Sean
My problem with "ancestor::*/@style" is that it selects the outermost
ancestor's attribute.
Try this
<page>
<xsl:attribute name="style">
<xsl:choose>
<xsl:when test="@style">
<xsl:value-of select="@style"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="ancestor::page[(_at_)style][1]/@style"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates/>
</page>
It gets the first page ancestor that has a @style attribute, and uses that
@style attribute.
Ancestors are shown in reverse order, so [1] is the closest ancestor.
"An axis is either a forward axis or a reverse axis. An axis that only ever
contains the context node or nodes that are after the context node in
document order is a forward axis. An axis that only ever contains the
context node or nodes that are before the context node in document order is
a reverse axis. Thus, the ancestor, ancestor-or-self, preceding, and
preceding-sibling axes are reverse axes; all other axes are forward axes."
Kind regards,
James Carlyle
FableFlow : MMS templating and delivery
Multimedia Messaging commentary : http://www.fableflow.com/weblog/
Telephone : +44 (0)20 7813 0665
-----Original Message-----
From: owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
[mailto:owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com]On Behalf Of
Sean O'Halpin
Sent: 25 October 2002 17:28
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] Inheriting an attribute from first ancestor that defines
it
Hello,
XSLT newbie warning! :)
I apologise in advance if this question has been answered before. I tried
searching the list on "inherit attribute" (and numerous
variations) but had
no luck.
I apologise also for the length of this post - but one thing I've
learnt in
the couple of weeks I've been doing XSLT is that if you can't tolerate
longwinded then it ain't for you ;)
Anyway, here's my problem:
I'd like to have child elements inherit an attribute from the
first ancestor
in their ancestry that defines it.
Specifically, is there a more general way (than specifying
test="../@attr",
test="../../@attr") to select the first ancestor travelling back
up the tree
that defines a specific attribute?
This is my example xml doc:
<?xml version="1.0" encoding="utf-8"?>
<doc style="doc">
<page id="0" style="default">
<page id="1" style="page1">
<page id="2">
<page id="3"/>
</page>
</page>
<page id="4">
<page id="5" style="page5">
<page id="6"/>
<page id="7" style="page7"/>
</page>
</page>
</page>
</doc>
Please note that the ids are just for reference here - I don't
want to refer
to them in the stylesheet.
I'd like page[(_at_)id=2] and page[(_at_)id=3] to inherit @style from
page[(_at_)id=1],
page[(_at_)id=4] to inherit @style from page[(_at_)id=0], page[(_at_)id=6] to
inherit from
page[(_at_)id=5], and page[(_at_)id=7] to use its own @style attribute.
In other words, I'd like the following output:
<?xml version="1.0" encoding="utf-8"?><doc style="doc">
<page id="0" style="default">
<page id="1" style="page1">
<page id="2" style="page1">
<page id="3" style="page1"></page>
</page>
</page>
<page id="4" style="default">
<page id="5" style="page5">
<page id="6" style="page5"></page>
<page id="7" style="page7"></page>
</page>
</page>
</page>
</doc>
Now, this stylesheet works for my particular example (with the above level
of nesting):
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version = '1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method="xml" encoding="utf-8"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="//page">
<page>
<xsl:copy-of select="@*"/>
<xsl:attribute name="style">
<xsl:choose>
<xsl:when test="@style">
<xsl:value-of select="@style"/>
</xsl:when>
<!-- parent's attribute -->
<xsl:when test="../@style">
<xsl:value-of select="../@style"/>
</xsl:when>
<!-- grandparent's attribute -->
<xsl:when test="../../@style">
<xsl:value-of select="../../@style"/>
</xsl:when>
<!-- ancestor's attribute -->
<xsl:otherwise>
<xsl:value-of select="ancestor::*/@style"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates/>
</page>
</xsl:template>
<!-- Identity transformation -->
<xsl:template match="@*|*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
But if I add more levels of nesting, I have to define further
rules to match
../../../, etc.
My problem with "ancestor::*/@style" is that it selects the outermost
ancestor's attribute.
For example, if I remove the selector for the grandparent's
attribute, I get
the following:
<?xml version="1.0" encoding="utf-8"?><doc>
<page id="0" style="default">
<page id="1" style="page1">
<page id="2" style="page1">
<page id="3" style="default"></page>
</page>
</page>
<page id="4" style="default">
<page id="5" style="page5">
<page id="6" style="page5"></page>
<page id="7" style="page7"></page>
</page>
</page>
</page>
</doc>
You'll note that page[(_at_)id=3] has now inherited @style from the outermost
ancestor that defines a style attribute (page[(_at_)id=0), which is not what I
want - I want it to inherit from page[(_at_)id=1](_dot_)
Thanks in advance for any help you can offer.
Regards,
Sean O'Halpin
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list