Re: [xsl] xsl:param and attribute testing

Subject: Re: [xsl] xsl:param and attribute testing
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Wed, 31 Jan 2001 11:59:29 +0000
Hi Reuel,

> Is it also possible to pass in a comma-separated list, parse it with xsl
> functions, and then feed that into a template?

You could definitely do it that way.  Define the parameter in the
stylesheet:

<xsl:param name="analyst_ids" />

Then set the parameter for the stylesheet in the calling script with:

  xsltProcessor.setStylesheetParam("analyst_ids", "10,103,998");

You can then count the number of Analyst elements with those ids as
the value of their 'id' attribute with something like:

  count(Analyst[contains(concat(',', $analyst_ids, ','),
                         concat(',', @id, ','))])

(assuming here that you're in a template where the Analyst elements
are children of the matched node).

The other possibility is that you use a result tree fragment (RTF) to
hold the analyst IDs that you're interested in. I'll show you how this
works first, before talking about how you actually set the parameter
using this method. You can define a parameter to hold some XML that
you create by setting its content:

<xsl:param name="analyst_ids">
   <id>10</id>
   <id>103</id>
   <id>998</id>
</xsl:param>

You can then access this as a node set if you use an extension
function: in Xalan it's xalan:nodeset().  You need to declare the
Xalan namespace in your stylesheet to use it (the namespace is
http://xml.apache.org/xalan), and you probably want to indicate that
it's a namespace that should be excluded from the result tree using
the exclude-result-prefixes attribute on xsl:stylesheet.

  xalan:nodeset($analyst_ids)

So, you can count the number of Analysts who have id attributes with a
value equal to any of these ids with:

  count(Analyst[@id = xalan:nodeset($analyst_ids)/id])

Come XSLT 1.1, you won't have to worry about xalan:nodeset at all, and
you'll just be able to do:

  count(Analyst[@id = $analyst_ids/id])

but if you try that now, it'll moan at you for treating an RTF like a
node set.

How do you change the value of a RTF parameter?  Well, it depends on
the XSLT Processor; with MSXML, you can pass DOMs as parameter values
and they are interpreted as if they were declared as RTFs.  According
to the API for the org.apache.xalan.xslt.XSLTProcessor interface,
setStylesheetParameter() only accepts a *string* as the second
argument (i.e. the value of the parameter) - the Trax
javax.xml.transform.Transformer interface on the other hand allows you
to pass any Java object as the second argument, so perhaps there's a
way around it if you study the API docs.

The other way of doing it is by actually reaching into the DOM for the
stylesheet and changing it: access the relevant xsl:param element by
selecting that node, and then add some element children (the 'id'
elements) with the values that you want.  When you use the amended DOM
as the stylesheet it will be just as if you had declared the parameter
at the top level.

A final way of approaching this is to declare the IDs that you want to
match in a separate XML document:

--- analyst_ids.xml ---
<?xml version="1.0"?>
<ids>
  <id>10</id>
  <id>103</id>
  <id>998</id>
</ids>
---

You can then access this document to get the IDs that you're after.
Using this method, the count would look like:

  count(Analyst[@id = document('analyst_ids.xml')/ids/id])

You can either edit the analyst_ids.xml document to hold the relevant
IDs or create different documents and pass the filename into the
stylesheet as a (string) parameter.  You could even create the
document on the fly in response to the stylesheet request - it doesn't
have to be physically located on the server.

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread