Re: [xsl] Re: xsl-list Digest 9 Nov 2006 06:10:00 -0000 Issue 953

Subject: Re: [xsl] Re: xsl-list Digest 9 Nov 2006 06:10:00 -0000 Issue 953
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Thu, 09 Nov 2006 18:16:17 -0500
Dear Eric,

Sorry, I write in some haste.

But you will find a couple of suggestive examples of recursion in the FAQ at

Also there are plenty of others on the net, if you care to dig, or in such classics of XSLT 1.0 lore as Jeni Tennison's _XSLT On the Edge_ and Sal Mangano's _XSLT Cookbook_.

However, I should warn you going in: you've got quite a task on your hands if you've never done it, as XSLT 1.0 really wasn't designed for this sort of thing. In your case, not only do you need to recurse to generate the correct number of rows, but you will need a string-chopping routine (itself recursive) to nibble away at the value of @fieldnames to generate your fields. Not pretty.

XSLT 2.0 is much nicer for this kind of thing: not only can you iterate over a sequence of integers, but also you have handy functions like tokenize() around.

(Or dare one suggest using something like Python or Perl?)

Back in the day, you could possibly have induced a friendly XSLT enthusiast with too much time on their hands to show you some code. If you phrase it right, you still might. (Sorry I'm not taking the bait: I leave on a road trip tomorrow.)

Good luck,

At 01:30 PM 11/9/2006, you wrote:
Hi Wendell,

Thank you for responding, I guess I removed too much of my original
post and ended up being less clear.

>>I have an excerpt of a wddx data being generated from query data in
>>ColdFusion 5 and I need to simplify the structure with an intermediate
>>xsl transform so that I can consume the simplified form in a mail merge
>I realize the following code does not work but it is the
>pull/procedural approach I keep getting stuck heading towards:
><xsl:template match="var/recordset">
>         <xsl:variable name="rowCount" select="@rowCount"/>
>         <xsl:variable name="fieldNames" select="@fieldNames"/>
>         <xsl:for-each from="1" to="$rowCount" index="row">
>                 <xsl:element name="{../@name}">
>                         <xsl:for-each list="$fieldNames" index="col">
>                                 <xsl:element name="{$fieldNames[$col]}">
>                                         <xsl:value-of
> select="field[@name=$col]::child[position()=$row]"/>
>                                 <xsl:element>
>                         </xsl:for-each>
>                 </xsl:element>
>         </xsl:for-each>
>Can anyone point me towards a better approach using a push/functional
>approach to make simplification of wddx recordsets contextually

First, a simple question: are you using XSLT 2.0?

I'm using SAXON 6.5.3 via javax in a 1.4.2 java applet, (but not via the XSLTProcessorApplet interface, ) so this needs to be XSLT 1.0.

The reason I ask is that in XSLT 1.0 you can't generate nodes in the
result by iterating over a set of numbers, which is effectively what
you are trying to do here. xsl:for-each doesn't accept "from" and
"to" attributes, as its purpose is to select a set of *nodes* (from
the source tree) and operate with each of them in turn as the current
node. (In this, it's really just a shortcut to allow you to do this
locally without calling a new template rule, which is what you'd
ordinarily do.)

Due to its expanded data model, however, in XSLT 2.0 you can say

<xsl:for-each select="1 to $rowCount">...</xsl:for-each>

and (due to the semantics of the 'to' operator) operate over a
sequence of numbers (integers, actually), 1 to whatever $rowCount is.

Hence, in XSLT 2.0 the correction would be a simple syntax tweak.

In XSLT 1.0, however, you would have to execute this recursively,
calling a template from itself and counting up to or down from
$rowCount with a parameter as you did so, to effect a stop condition.
(There are examples from that in the XSL FAQ.)

Can you point out the specific entries in the FAQ? I'm not searching with the right words to find how to approach that recursive template call appropriately.

Here is an brief version of the wddx data:

<?xml version="1.0" encoding="UTF-8"?>
<wddxPacket version='1.0'><header></header><data><struct>
<var name='party'>
<recordset rowCount='2'
<field name='PARTY_ID'>
<field name='PARTY_ROLE_ID'>
<field name='FIRST_NAME'>
<field name='LAST_NAME'>
<field name='SUFFIX'>
<field name='BIRTH_DT'>
<var name='alias'>
<recordset rowCount='1' fieldNames='ALIAS_ID,PARTY_ID,FIRST_NAME,LAST_NAME'>
<field name='ALIAS_ID'>
<field name='PARTY_ID'>
<field name='FIRST_NAME'>
<field name='LAST_NAME'>

And the output I am hoping to get as a result is:

<?xml version="1.0" encoding="UTF-8"?>

If it is possible to do in one style sheet I would also like to make a
copy of the alias element into the party element where the party_id
identical.  But I figured that could be a separate question.

Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.      
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
  Mulberry Technologies: A Consultancy Specializing in SGML and XML

Current Thread