Re: [xsl] How do I build a nodeset "programmatically" for passing to another template?

Subject: Re: [xsl] How do I build a nodeset "programmatically" for passing to another template?
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Thu, 17 Aug 2006 21:40:55 +0530
I was about to post something about this, just when Wendell's reply
came up. He has explained the concept very nicely.

To add to his answer, I could give you some syntax (which is self-explainatory):

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";

xmlns:common="http://exslt.org/common";>

<xsl:output method="xml" indent="yes" />

<xsl:template match="/">
  <xsl:variable name="speed_table_values">
    <entry>
      <radius>30</radius>
      <speed_km_h>60.9</speed_km_h>
      <speed_mph>50.1</speed_mph>
    </entry>
    <entry>
      <radius>60</radius>
      <speed_km_h>72.9</speed_km_h>
      <speed_mph>60.1</speed_mph>
    </entry>
    <entry>
      <radius>61</radius>
      <speed_km_h>81.9</speed_km_h>
      <speed_mph>70.4</speed_mph>
    </entry>
    <entry>
      <radius>100</radius>
      <speed_km_h>99.9</speed_km_h>
      <speed_mph>75.1</speed_mph>
    </entry>
  </xsl:variable>

  <xsl:call-template name="X">
    <xsl:with-param name="param_x" select="$speed_table_values" />
  </xsl:call-template>
</xsl:template>

<xsl:template name="X">
  <xsl:param name="param_x" />

  <xsl:for-each select="common:node-set($param_x)/entry">
    <xsl:value-of select="radius" />
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

But instead, if you try to do following with an XSLT 1.0 processor:

<xsl:for-each select="$param_x/entry">
  <xsl:value-of select="radius" />
</xsl:for-each>

You will get an error. Because as Wendell said, an RTF may only be
copied to the result tree or converted to a string. Here parameter
param_x holds an RTF.

As Wendell said, XSLT 1.1 is not popular, and also not well supported,
so why not base your stylesheet on XSLT 1.0? Or, XSLT 2.0 if you like.

On 8/17/06, Zaleski, Matthew (M.E.) <mzaleski@xxxxxxxx> wrote:
I'm using Saxon 6.5.x (and XSL 1.1).

Searches on the web and this list's archives give me tantalizing hints
that what I want to do is theoretically possible.  All of the examples I
find seem to be "reducers" (e.g. sum a set of numbers spread throughout
a nodeset, or combine nodes into a single string), rather than
"builders".

My stylesheets are pull style that build XSL-FO output for further
processing by Apache-FOP.  What I'm trying to do is build a nodeset in a
variable so that I can rely on some generic fo:table templates to
produce the output rather than custom templates for each occurrence.
Due to limits of what is currently in the XML input files, I'm forced to
do some calculation/nodeset building to supplement the structure already
in the XML file.

Is it possible for a chunk of XSL like:
<xsl:variable name="max_ay"
select="/vdt:report/vdt:run_metrics/*[normalize-space(text()) = 'Avg
Ay']/vdt:statistics/vdt:statistic[@stat_name='Average']"/>
<xsl:variable name="ay_90pct" select="format-number(0.9 * $max_ay,
'#.##')"/>
<xsl:variable name="speed_table_values">
       <xsl:call-template name="ml_generate_speed_table">
               <xsl:with-param name="ay_target" select="$ay_90pct"/>
               <xsl:with-param name="radii">
                       <radius>30</radius>
                       <radius>60</radius>
                       <radius>61</radius>
                       <radius>100</radius>
               </xsl:with-param>
               <xsl:with-param
name="string_format">#.#</xsl:with-param>
       </xsl:call-template>
</xsl:variable>


To result in the variable $speed_table_values looking something like ?: <entry> <radius>30</radius> <speed_km_h>60.9</speed_km_h> <speed_mph>50.1</speed_mph> </entry> <entry> <radius>60</radius> <speed_km_h>72.9</speed_km_h> <speed_mph>60.1</speed_mph> </entry> <entry> <radius>61</radius> <speed_km_h>81.9</speed_km_h> <speed_mph>70.4</speed_mph> </entry> <entry> <radius>100</radius> <speed_km_h>99.9</speed_km_h> <speed_mph>75.1</speed_mph> </entry>

(The numbers in the table are bogus but the nodeset structure is what
I'm interested in.)

I would then have a later <xsl:call-template> that contained
<xsl:with-param select="$speed_table_values">

As you can see, this particular problem is mostly interating over nodes
provided within the XSL sheet itself rather than the source XML.  Only
the first line of my example is grabbing a value/node from the source
tree.  I need to accomplish this in a single pass (not multiple calls to
an XSLT transformer).  Assuming what I want to do is possible in XSL
1.1, any links to similar examples would be much appreciated.


Matthew Zaleski

-- Regards, Mukul Gandhi

http://gandhimukul.tripod.com

Current Thread