xsl-list
[Top] [All Lists]

RE: Traversing nodes and storing a matched value

2005-06-29 11:52:24
XSLT 1.0 doesn't allow variables to be used in a match pattern.

Michael Kay
http://www.saxonica.com/
 

-----Original Message-----
From: Mat Bergman [mailto:matbergman(_at_)yahoo(_dot_)com] 
Sent: 29 June 2005 19:35
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: RE: [xsl] Traversing nodes and storing a matched value

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(_at_)hotmail(_dot_)com> 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(_at_)yahoo(_dot_)com>
Reply-To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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 McAfeeR 
Security.

http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963



--~------------------------------------------------------------------
XSL-List info and archive: 
http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to:
http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





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

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--