RE: [xsl] Inheriting an attribute from first ancestor that defines it

Subject: RE: [xsl] Inheriting an attribute from first ancestor that defines it
From: "James Carlyle" <james.carlyle@xxxxxxxxxxxx>
Date: Thu, 17 Oct 2002 19:09:42 +0100
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[@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@xxxxxxxxxxxxxxxxxxxxxx
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx]On Behalf Of Sean O'Halpin
> Sent: 25 October 2002 17:28
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> 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[@id=2] and page[@id=3] to inherit @style from page[@id=1],
> page[@id=4] to inherit @style from page[@id=0], page[@id=6] to
> inherit from
> page[@id=5], and page[@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[@id=3] has now inherited @style from the outermost
> ancestor that defines a style attribute (page[@id=0), which is not what I
> want - I want it to inherit from page[@id=1].
>
> 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


Current Thread