Subject: Re: [xsl] Can't identify last ancestor node From: "Sam D. Chuparkoff" <sdc@xxxxxxxxxx> Date: Tue, 28 Jun 2005 05:48:16 -0700 |
On Tue, 2005-06-28 at 01:36 -0700, Mat Bergman wrote: > 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? Don't use xsl:text to write xml. Don't think in terms of generating start and end tags. You can't separate the two. Forget about the ul s for a bit, pull out your conditions, and make certain your creation of li s looks something like: <li><xsl:value-of select="@name"/></li> and nothing like: <xsl:text disable-output-escaping="yes"><li></xsl:text> <xsl:value-of select="@name"/> <xsl:text disable-output-escaping="yes"></li></xsl:text> Then you can start asking: How do I get some ul s in there? (Hint: no xsl:text allowed. Really.) Though someone else will have to answer because I'll be offline. sdc > 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" /> > <xsl:with-param name="level" select="$level" /> > </xsl:call-template> > </xsl:when> > <xsl:otherwise> > <xsl:call-template name="_tokenize-delimiters"> > <xsl:with-param name="string" select="$string" > /> > <xsl:with-param name="delimiters" > select="substring($delimiters, 2)" /> > <xsl:with-param name="level" select="$level" /> > </xsl:call-template> > </xsl:otherwise> > </xsl:choose> > </xsl:template> > > > <xsl:template name="process-includeExclude" > match="menu"> > <xsl:param name="currentExsite" select="''" /> > > <!-- check if siteID is excluded or included --> > <xsl:if test="$currentExsite!=$siteID"> > <xsl:if test="@incsites=$siteID or @incsites=0"> > > <!-- Write <li> tags --> > <xsl:text > disable-output-escaping="yes"><li></xsl:text> > > <!-- Write list content --> > <xsl:value-of select="@name"/> > > <!-- Nested list - Write nested <ul> tags --> > <xsl:if test="count(menu) > 0"> > <xsl:text > disable-output-escaping="yes"> <ul> </xsl:text> > </xsl:if> > > <!-- Write </li> tags for top-level and nested items > --> > <xsl:if test="count(menu) = 0"> > > <xsl:choose> > > <!-- This is where I am having trouble. I want this > to appear only at the last menu/menu node. Instead > it's selecting all menu ancestors. --> > > <!-- If it's the last sub-menu, close with an </li> > and a </ul> --> > <xsl:when test="ancestor::menu[last()]"> > <xsl:text > disable-output-escaping="yes"></li></ul> > </xsl:text> > </xsl:when> > > <!-- If it's not the last sub-menu, close with an > </li> --> > <xsl:otherwise> > <xsl:text > disable-output-escaping="yes"></li> > </xsl:text> > </xsl:otherwise> > > </xsl:choose> > > </xsl:if> > > </xsl:if> > </xsl:if> > > > </xsl:template> > > </xsl:stylesheet> > > > Thanks, > > -Mat > > > > > __________________________________________________ > Do You Yahoo!? > Tired of spam? Yahoo! Mail has the best spam protection around > http://mail.yahoo.com
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Can't identify last ances, Michael Kay | Thread | RE: [xsl] Can't identify last ances, Mat Bergman |
Re: [xsl] gathering entities when t, David Carlisle | Date | [xsl] xsl transform, Philippe LAPLANCHE |
Month |