RE: [xsl] Traversing nodes and storing a matched value

Subject: RE: [xsl] Traversing nodes and storing a matched value
From: Mat Bergman <matbergman@xxxxxxxxx>
Date: Wed, 29 Jun 2005 11:34:48 -0700 (PDT)
This looks like a most elegant solution. One
head-scratching error occurs when I play with it using
the MSXML processor:
Variables may not be used within this expression.
menu[not(existes = -->$siteID<--)]

When I hard-code the value in place of the variable,
it works fine. Am I missing something?

Thanks,

-Mat

--- Aron Bock <aronbock@xxxxxxxxxxx> wrote:

> Mat,
> 
> You may want to change your calling sequence -- by
> the time you 
> "parseExclusions" you've already written an "ul". 
> Anyway, to answer your 
> question, XSL is set oriented, so you could
> something like this to write 
> only those menus containing at least 1 <existes>  =
> siteID:
> 
> This input:
> 
> <data>
>     <menu id="1"><existes>01</existes></menu>
>     <menu
>
id="2"><existes>1</existes><existes>2</existes></menu>
>     <menu id="3"><existes>2</existes></menu>
> </data>
> 
> Against this XSL:
> 
> <?xml version="1.0" encoding="iso8859-1"?>
> <xsl:stylesheet version="1.0" 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>     <xsl:output method="xml" indent="yes"/>
>     <xsl:strip-space elements="*"/>
> 
>     <xsl:variable name="siteID" select="2"/>
> 
>     <xsl:template match="node()|@*">
>         <xsl:copy><xsl:apply-templates
> select="node()|@*"/></xsl:copy>
>     </xsl:template>
> 
>     <xsl:template match="menu[not(existes =
> $siteID)]"/>
> 
> </xsl:stylesheet>
> 
> produces:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <data>
>   <menu id="2">
>     <existes>1</existes>
>     <existes>2</existes>
>   </menu>
>   <menu id="3">
>     <existes>2</existes>
>   </menu>
> </data>
> 
> Thus, when you call write-menu, you may want to pass
> in only those menus 
> with contain a qualifying existes.
> 
> --A
> 
> 
> >From: Mat Bergman <matbergman@xxxxxxxxx>
> >Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> >To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> >Subject: [xsl] Traversing nodes and storing a
> matched value
> >Date: Tue, 28 Jun 2005 20:52:17 -0700 (PDT)
> >
> >My efforts to streamline my stylesheet into
> something
> >well-formed are paying off with help from this
> list. I
> >am currently working with XML input that looks like
> >this:
> >
> ><menudata>
> >	<menu name="link1">
> >	<exsites>0</exsites>
> >	</menu>
> >	<menu name="link2">
> >	<exsites>0</exsites>
> >		<menu name="link2a">
> >		<exsites>1</exsites>
> >		<exsites>2</exsites>
> >		</menu>
> >	</menu>
> ></menudata>
> >
> >The value of the <exsites> element determines if
> its
> >parent <menu> element will appear in the output,
> based
> >on a $siteID parameter set in the stylesheet. In
> some
> >cases, <menu> has multiple <exsites> children.
> >
> >I'm not clear how to use XSL to say, "if the value
> of
> >ANY <exsite> matches $siteID, then flag its
> parent's
> >node for different processing". Here's my attempt
> (the
> >section where I'm in trouble is commented):
> >
> ><?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" indent="yes"/>
> ><xsl:strip-space elements="*"/>
> >
> ><!-- siteID determines if a link is displayed for a
> >specific cobrand -->
> ><xsl:param name="siteID" select="2"/>
> >
> ><xsl:template match="/menudata">
> >	<xsl:call-template name="write-menu">
> >		<xsl:with-param name="items" select="menu"/>
> >	</xsl:call-template>
> ></xsl:template>
> >
> ><xsl:template name="write-menu">
> >	<xsl:param name="items" select="/.."/>
> >
> >	<ul>
> >		<xsl:for-each select="$items">
> >			<xsl:call-template name="parseExclusions"/>
> >		</xsl:for-each>
> >	</ul>
> >
> ></xsl:template>
> >
> ><xsl:template name="parseExclusions">
> >
> ><!-- Check <exsites> for a match against $siteID -
> if
> >a match, don't display -->
> >	<xsl:for-each select="exsites">
> >		<xsl:if test="current()=$siteID">
> >
> ><!-- This is where I need the stylesheet not to
> write
> >the link if any of the <exsites> values match the
> >$siteID parameter -->
> ><!-- For now I'm just writing out the value if it
> >matches $siteID -->
> >		<xsl:value-of select="current()"/>
> >		</xsl:if>
> >	</xsl:for-each>
> >
> >		<li>
> >			<xsl:value-of select="@name"/>
> >			<xsl:if test="menu">
> >				<xsl:call-template name="write-menu">
> >					<xsl:with-param name="items" select="menu"/>
> >				</xsl:call-template>
> >			</xsl:if>
> >		</li>
> >
> ></xsl:template>
> >
> ></xsl:stylesheet>
> >
> >
> >My instinct is to set a boolean variable if any
> ><exsite> element matches, then use that variable to
> >control the output. Something like this (in
> >pseudo-code):
> >
> ><xsl:for-each select="exsites">
> >	<xsl:if test="current()=$siteID">
> >	<!-- set variable - var excludeFlag = 1 -->
> >	</xsl:if>
> ></xsl:for-each>
> >
> ><!-- write tag - if (excludeFlag!=1) -->
> ><li>
> ><xsl:value-of select="@name"/>
> >
> ></li>
> ><!-- /if -->
> 
>
_________________________________________________________________
> Is your PC infected? Get a FREE online computer
> virus scan from McAfee. 
> Security.
>
http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963
> 
> 



		
____________________________________________________ 
Yahoo! Sports 
Rekindle the Rivalries. Sign up for Fantasy Football 
http://football.fantasysports.yahoo.com

Current Thread