[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: Can't identify last ancestor node

Subject: RE: Can't identify last ancestor node
From: Mat Bergman <matbergman@xxxxxxxxx>
Date: Tue, 28 Jun 2005 09:20:23 -0700 (PDT)
mat bergman
This is close to what I need, but I need to be more
clear. In this case, the context node is
/menudata/menu/menu. I want to apply unique output for
the last <menu> nodes in /menudata/menu/menu. For
instance:

<menudata>
     <menu name="link1">
          <menu name="link1a"/>
          <menu name="link1b"/>
          <menu name="link1c"/>
     </menu>
     <menu name="link2">
          <menu name="link2a"/>
          <menu name="link2b"/>
          <menu name="link2c"/>
     </menu>     
</menudata>

The <menu> nodes with name="link1c" and name="link2c"
are the nodes that I'm after, but I can't figure out
how to identify those nodes with XPath. 

Working with <xsl:variable name="last-menu"
select="(//menu)[last()]"/> gives me the last <menu>
node in the entire nodeset, so that my custom output
is applied only to name="link2c". So maybe [last()] is
not the predicate that I need.

Thanks for bearing with me,

-Mat







--- Michael Kay <mike@xxxxxxxxxxxx> wrote:

> You haven't told us what the context node is for
> your code snippets -
> presumably it's the <menu> element that you're
> testing? In that case they
> don't make any sense at all. Looking at the
> ancestors of a node can't tell
> you whether it has any following siblings, for
> example. (From your question,
> I think you may have confused your ancestors with
> your descendants).
> 
> Best way to do this is probably to set a global
> variable to the last menu
> element:
> 
> <xsl:variable name="last-menu"
> select="(//menu)[last()]"/>
> 
> and then when processing each menu element, test
> 
> <xsl:if test=". is $last-menu">  (XSLT 2.0)
> 
> <xsl:if test="generate-id(.) =
> generate-id($last-menu)"/>  (XSLT 1.0)
> 
> Michael Kay
> http://www.saxonica.com/
>  
> 
> > -----Original Message-----
> > From: Mat Bergman [mailto:matbergman@xxxxxxxxx] 
> > Sent: 28 June 2005 09:36
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Subject:  Can't identify last ancestor node
> > 
> > Using this XML data:
> > 
> > <menudata>
> > 	<menu name="link1"/>
> > 	<menu name="link2">
> > 		<menu name="link2a"/>
> > 		<menu name="link2b"/>
> > 	</menu>
> > </menudata>
> > 
> > 
> > I am producing this HTML output:
> > <ul>
> > <li>link1</li>
> > <li>link2
> > 	<ul>
> > 	<li>link2a</li>
> > 	<li>link2b</li>
> > 	</ul>
> > </li>
> > </ul>
> > 
> > I am using a convoluted stylesheet that tokenizes
> an
> > attribute and generates the HTML output based on
> the
> > attribute's value. My problem is identifying the
> last
> > nested node, in this example "link2b", so that I
> can
> > customize that node's output.
> > 
> > My complete stylesheet is below, but to summarize
> I
> > made two attempts:
> > 
> > <xsl:for-each select="ancestor::menu">
> > 	<xsl:if test="position()=last()">
> > 	<xsl:text>Write custom end text here</xsl:text>
> > 	</xsl:if>
> > </xsl:for-each>
> > 
> > and
> > 
> > <xsl:if test="ancestor::menu[last()]">
> > <xsl:text>Write custom end tag here</xsl:text>
> > </xsl:if>
> > 
> > Both attempts wrote to each individual node, not
> just
> > the last one. How can I tell my stylesheet to
> write
> > one thing for the last <menu> node, and something
> else
> > for the rest?
> > 
> > Here's the entire stylesheet:
> > 
> > <?xml version="1.0"?>
> > <xsl:stylesheet version="1.0"
> >               
> > xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> > 	
> > <xsl:output method="html" indent="yes"/>
> > 
> > <!-- siteID determines if a link is displayed for
> a
> > specific cobrand -->
> > <xsl:param name="siteID" select="2"/>
> > 
> > <!-- Displays navigation -->
> > <xsl:template match="/">
> > 
> > 	<ul>
> > 
> > 	<!-- tokenize all <menu> nodes -->
> > 	<xsl:for-each select="//menu">
> > 
> > 		<!-- Tokenize attributes to check if siteID is
> > excluded -->
> > 		<xsl:call-template name="tokenize">
> > 			<xsl:with-param name="string" 
> > select="@exsites"/>
> > 			<xsl:with-param name="delimiters"
> select="','"/>
> > 			<xsl:with-param name="level"
> > select="'process-includeExclude'"/>
> > 		</xsl:call-template>
> > 
> > 	</xsl:for-each>
> > 
> > 	</ul>
> > 
> > </xsl:template>
> > 
> > 
> > <!-- Extract individual values from
> comma-delimited
> > attribute -->
> > <xsl:template name="tokenize">
> > 	<xsl:param name="string" select="''" />
> > 	<xsl:param name="delimiters" select="'
> 	
'"
> > />
> > 	<xsl:param name="level" select="''" />
> > 
> > 	<xsl:call-template name="_tokenize-delimiters">
> > 		<xsl:with-param name="string" select="$string"
> />
> > 		<xsl:with-param name="delimiters"
> > select="$delimiters" />
> > 		<xsl:with-param name="level" select="$level" />
> > 	</xsl:call-template>
> > 
> > </xsl:template>
> > 
> > 
> > <xsl:template name="_tokenize-delimiters">
> > 
> > 	<xsl:param name="string" />
> > 	<xsl:param name="delimiters" />
> > 
> > 	<xsl:param name="level" />
> > 
> > 	<xsl:param name="last-delimit"/> 
> > 	<xsl:variable name="delimiter"
> > select="substring($delimiters, 1, 1)" />
> > 	
> > 	<xsl:choose>
> > 		<xsl:when test="not($delimiter)">
> > 
> > 		<!-- Sends individual attribute value for
> processing
> > -->
> > 		<xsl:call-template name="process-includeExclude"
> >
> > 			<xsl:with-param 
> > name="currentExsite"><xsl:value-of
> > select="$string"/></xsl:with-param>	
> > 		</xsl:call-template>
> > 
> > 	   </xsl:when>
> > 
> > 	<!-- process string until all tokens are
> separated
> > -->
> >    <xsl:when test="contains($string, $delimiter)">
> >      <xsl:if test="not(starts-with($string,
> > $delimiter))">
> >        <xsl:call-template
> name="_tokenize-delimiters">
> >          <xsl:with-param name="string"
> > select="substring-before($string, $delimiter)" />
> >          <xsl:with-param name="delimiters"
> > select="substring($delimiters, 2)" />
> >        <xsl:with-param name="level"
> select="$level" />
> > 
> >        </xsl:call-template>
> >      </xsl:if>
> >      <xsl:call-template
> name="_tokenize-delimiters">
> >        <xsl:with-param name="string"
> > select="substring-after($string, $delimiter)" />
> >        <xsl:with-param name="delimiters"
> > select="$delimiters" />
> 
=== message truncated ===


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.