Subject: RE: [xsl] Can't identify last ancestor node From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Tue, 28 Jun 2005 17:23:36 +0100 |
The two nodes you identify can be selected by if (not(following-sibling::menu) and not(child::menu)) then ... Michael Kay http://www.saxonica.com/ > -----Original Message----- > From: Mat Bergman [mailto:matbergman@xxxxxxxxx] > Sent: 28 June 2005 17:20 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: RE: [xsl] Can't identify last ancestor node > > 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: [xsl] 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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Can't identify last ances, Mat Bergman | Thread | RE: [xsl] Can't identify last ances, Aron Bock |
RE: [xsl] Can't identify last ances, Mat Bergman | Date | [xsl] finding the position of the p, Nadia . Swaby |
Month |