Subject: Re: [xsl] Changing Attributes Based on Ancestry From: "Joerg Heinicke" <joerg.heinicke@xxxxxx> Date: Tue, 9 Apr 2002 01:00:26 +0200 |
Hello Eric, you have a few mistakes in your code. > <xsl:template name="top_bar"> > <xsl:apply-templates select="document('./nav.xml')"/> > </xsl:template> > > <xsl:template name="bottom_bar"> > <xsl:apply-templates select="document('./nav.xml')"/> > </xsl:template> > > <xsl:template match="navigate"> > <xsl:if test='ancestor::top_bar'> > <xsl:param name="navColor">#ffffff</xsl:param> > </xsl:if> > <xsl:if test='ancestor::bottom_bar'> > <xsl:param name="navColor">#000000</xsl:param> > </xsl:if> I don't know whether I understand it correctly what you want to reach here. But I think you want to know from which template (top or bottom_bar) you are "called", don't you? The axes refer to the XML, so this test for ancestor can only work if you have a structure like <top_bar> <navigate> </navigate> </top_bar> If you really only want to know whether you are at the bottom or at the top, it is better to pass a parameter fom one template to the other. <xsl:apply-templates select="foo"> <xsl:with-param name="param" select="value"/> </xsl:apply-templates> For your stylesheet it can look so: <xsl:template match="top_bar"> <xsl:apply-templates select="document('nav.xml')"> <xsl:with-param name="position" select="'top'"/> </xsl:apply-templates> </xsl:template> Pay attention on the single quotes around top. This means you want to sent top as string. Otherwise a top-element will be searched and the value of this will be used. Now you have a new problem. The above code applies a template to the root node '/' of nav.xml. You should add the document element there, which I think is <navigate>, because the param will be passed to the template matching on '/', but no step further. <xsl:apply-templates select="document('nav.xml')/navigate"> > <xsl:if test='ancestor::top_bar'> > <xsl:param name="navColor">#ffffff</xsl:param> > </xsl:if> But your code in this template has more errors. You create a param not at the very beginning of the template. You should use xsl:variable here. And the param/variable is only available at the childs/descendants of the <xsl:if>. If you are outside <xsl:if>, you will get an error "$navColor is out of scope" or so. You have to put the variable outside the xsl:if: <xsl:variable name="navColor"> <xsl:if test="bla">...</xsl:if> <xsl:if test="foo">...</xsl:if> </xsl:variable> Futhermore you can use xsl:choose, xsl:when, xsl:otherwise here as you did it in the code below. Here it makes sense. > <xsl:value-of select="$navColor"/> > <xsl:for-each select="lnk"> > <a href="{@href}" style="color:{$navColor}; > font-size:9pt"><xsl:value-of select="."/></a> > <xsl:choose> > <xsl:when test="position() == last()"> But here not ;-) A simple xsl:if is enough here (if you haven't shortened the code). And the doubled '=' should be wrong too. > </xsl:when> > <xsl:otherwise> > <span style="color:{$navColor}"><xsl:text> | </xsl:text></span> You don't need <xsl:text> here if you write it in one line. > </xsl:otherwise> > </xsl:choose> > </xsl:for-each> > </xsl:template> So at the end I have the following templates: <xsl:template name="top_bar"> <xsl:apply-templates select="document('./nav.xml')"> <xsl:with-param name="position" select="'top'"/> </xsl:apply-templates> </xsl:template> <xsl:template name="bottom_bar"> <xsl:apply-templates select="document('./nav.xml')"> <xsl:with-param name="position" select="'bottom'"/> </xsl:apply-templates> </xsl:template> <xsl:template match="navigate"> <xsl:param name="position"/> <xsl:variable name="navColor"> <xsl:choose> <xsl:when test="$position = 'top'">#ffffff</xsl:when> <xsl:when test="$position = 'bottom'">#000000</xsl:when> </xsl:choose> </xsl:variable> <xsl:value-of select="$navColor"/> <xsl:for-each select="lnk"> <a href="{@href}" style="color:{$navColor};font-size:9pt"><xsl:value-of select="."/></a> <xsl:if test="position() != last()"> <span style="color:{$navColor}"> | </span> </xsl:if> </xsl:for-each> </xsl:template> If it's not necessary to know whether you are creating top-nav or bottom-nav at the moment, but only the color, you can pass the navColor directly to the navigate template (again as string). The template is a bit shorter then. <xsl:template name="top_bar"> <xsl:apply-templates select="document('./nav.xml')"> <xsl:with-param name="navColor" select="'#ffffff'"/> </xsl:apply-templates> </xsl:template> <xsl:template match="navigate"> <xsl:param name="navColor"/> <xsl:value-of select="$navColor"/> ... </xsl:template> > Basically, I want the color for the top_bar to be white and the bottom bar > to be black, but it's not applying. I also tried using: <xsl:template > match="//navigate"> but that didn't work either. This does not change anything. As the name says it is only a "template". An the matcher says on which nodes to match. If you write match="navigate" (match navigate elements without limitations) or match="//navigate" (match navigate elements anywhere in the tree without limitations) there is no difference - maybe it changes the priority of the template. The arbitrative is the xsl:apply-templates. There you select on which nodes a template should be applied. This is why I add on the xsl:apply-templates on document('nav.xml') the /navigate. > (is it not working because it's importing from an outside file?) No, definitively not. With external documents you have to pay attention on some special things (as the new root node), but they behave exactly as the input tree. Hope this helps (nothing of the code is tested, it's difficult without knowing the exact XML too), Joerg XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Changing Attributes Based on , eric | Thread | Re: [xsl] Changing Attributes Based, Robert Koberg |
[xsl] columns and a new page in FO, Jaideep Chadha | Date | Re: [xsl] grouping data of an xml f, Joerg Heinicke |
Month |