[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

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


Subject: [xsl] Re: xsl-list Digest 9 Nov 2006 06:10:00 -0000 Issue 953
From: "Eric Pheatt" <eric.pheatt@xxxxxxxxx>
Date: Thu, 9 Nov 2006 10:30:34 -0800

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
>
>[snipped]
>
>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>
></xsl:template>
>
>Can anyone point me towards a better approach using a push/functional
>approach to make simplification of wddx recordsets contextually
>generic?

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'
fieldNames='PARTY_ID,PARTY_ROLE_ID,FIRST_NAME,LAST_NAME,BIRTH_DT'>
<field name='PARTY_ID'>
      <number>2127652</number>
      <number>2127653</number></field>
<field name='PARTY_ROLE_ID'>
      <number>51</number>
      <number>24</number></field>
<field name='FIRST_NAME'>
      <string>Bob</string>
      <string>Donte</string></field>
<field name='LAST_NAME'>
      <string>Jones</string>
      <string>Smith</string></field>
<field name='SUFFIX'>
      <string></string>
      <string></string></field>
<field name='BIRTH_DT'>
      <string></string>
      <dateTime>1990-6-4T0:0:0-8:0</dateTime></field>
</recordset>
</var>
<var name='alias'>
<recordset rowCount='1' fieldNames='ALIAS_ID,PARTY_ID,FIRST_NAME,LAST_NAME'>
<field name='ALIAS_ID'>
      <number>1</number></field>
<field name='PARTY_ID'>
      <number>2127652</number></field>
<field name='FIRST_NAME'>
      <string>Bobby</string></field>
<field name='LAST_NAME'>
      <string>Joneson</string></field>
</recordset>
</var>
</struct></data></wddxPacket>


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


<?xml version="1.0" encoding="UTF-8"?>
<partyList>
      <party>
              <PARTY_ID>2127652</PARTY_ID>
              <PARTY_ROLE_ID>51</PARTY_ROLE_ID>
              <FIRST_NAME>Bob</FIRST_NAME>
              <LAST_NAME>Jones</LAST_NAME>
              <SUFFIX/>
              <BIRTH_DT/>
      </party>
      <party>
              <PARTY_ID>2127653</PARTY_ID>
              <PARTY_ROLE_ID>24</PARTY_ROLE_ID>
              <FIRST_NAME>Donte</FIRST_NAME>
              <LAST_NAME>Smith</LAST_NAME>
              <SUFFIX/>
              <BIRTH_DT>1990-6-4T0:0:0-8:0</BIRTH_DT>
      </party>
      <alias>
              <ALIAS_ID>1</ALIAS_ID>
              <PARTY_ID>2127652</PARTY_ID>
              <FIRST_NAME>Bobby</FIRST_NAME>
              <LAST_NAME>Joneson</LAST_NAME>
      </alias>
</partyList>

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.

Thanks again,
Eric


Current Thread
Keywords