This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
ordering and iteration problem
- To: xsl-list at lists dot mulberrytech dot com
- Subject: [xsl] ordering and iteration problem
- From: Mark Nahabedian <naha at ai dot mit dot edu>
- Date: Thu, 26 Apr 2001 21:41:16 -0400 (EDT)
- Reply-To: xsl-list at lists dot mulberrytech dot com
My source XML describes an electrical circuit breaker panel:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE circuit-breaker-panel [
<!ELEMENT circuit-breaker-panel (circuit-breaker)+>
<!ELEMENT circuit-breaker (amps,special?,description)>
<!ATTLIST circuit-breaker
column CDATA #REQUIRED
row CDATA #REQUIRED
height CDATA #IMPLIED >
<!ELEMENT amps (#PCDATA)*>
<!ELEMENT special (#PCDATA)*>
<!ELEMENT description (#PCDATA)*>]>
<circuit-breaker-panel xmlns="http://www.ai.mit.edu/people/naha/XML-namespaces/fuse-box">
<circuit-breaker column="1" row="1" height="2">
<amps>60</amps>
<special>doubled</special>
<description>heat pump</description>
</circuit-breaker>
<circuit-breaker column="1" row="3" height="1">
<amps>15</amps>
<description>upper stairs</description>
</circuit-breaker>
<circuit-breaker column="2" row="7" height="1">
<amps>15</amps>
<description>
</description>
</circuit-breaker>
<circuit-breaker column="2" row="8" height="2">
<amps>20</amps>
<special>doubled</special>
<description>
</description>
</circuit-breaker>
</circuit-breaker-panel>
For the sake of brevity I've edited out many of the <circuit-breaker>
elements. The ones above are a representative sample.
The <circuit-breaker>s can appear in any order within the
<circuit-breaker-panel>.
My goal is a stylesheet that will transform such input into an HTML
table.
I have a named template which will find the highest column number and
row number from all of the <circuit-breaker>s in the
<circuit-breaker-panel>, so I know what the highest column number and
row number will be.
To produce an HTML table, I need to generate each table row in order
based on the row numbers of the circuit breakers and then in numerical
column order generate a table cell for the <circuit-breaker> in that
row and column. Note that it's possible for a single
<circuit-breaker> to occupy more than one sequential row in a given
column. Just sorting the <circuit-breaker>s by row and column won't
work becaus ethere might be gaps in the panel.
My thinking is that I need to do something like
for each row
for each column
ooutput the <circuit-breaker> with that row and column
Since iterating over a range of integers is a useful abstraction, I've
written a named template which does do and calls another caller
specified named template for each such integer:
<template name="do-integers">
<param name="first-int" select="0"/>
<param name="last-int"/>
<param name="step" select="1"/>
<param name="body-template-name"/>
<param name="body-template-parameter-name"/>
<if test="not($first-int > $last-int)">
<call-template name="$body-template-name">
<with-param name="$body-template-parameter-name"
select="$first-int"/>
</call-template>
<call-template name="do-integers">
<with-param name="first-int" select="$first-int + $step"/>
<with-param name="step" select="$step"/>
<with-param name="last-int" select="$last-int"/>
<with-param name="body-template-name" select="$body-template-name"/>
<with-param name="body-template-parameter-name"
select="$body-template-parameter-name"/>
</call-template>
</if>
</template>
While basking in my presumed cleverness, I realized that this won't
work however because the "name" atrtributes of both <call-template>
and <with-param> must be qnames. There's also the problem of not
being able to pass additional values from the template which calls
"do-integers" to the "body-template-name" template which it calls for
each iteration. (Can you tell that I'm a Lisp programmer by trade?).
I could code the row and column iterations separatly but replicating
the code offends my sensibilities. I'd rather write something more
general with broader applicability than have to recode the
functionality of "do-integers" with slight variation each time I need
it.
Perhaps I'm approaching the problem in the wrong way but I don't see
another way of achieving the goal. Any suggestions?
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list