Home. 
.

transparent

transparent

transparent

Altova Mailing List Archives


Re: Creating tables with missing cells

From: Diego TERCERO <diego.tercero@--------.-->
To: NULL
Date: 12/3/2004 12:43:00 AM
Blackops wrote:
> Hi,
> 
> I'm a little stumped with trying to put data into a table from a set of XML
> data that has some cells missing, and which should be left blank in the
> resulting table. I have a set of XML data describing the periodic table of
> elements, which I want to display as the standard periodic table using HTML
> tables and to help with this each atom has a 'period' (row) and 'group'
> (column) value to determine where that element should appear in the table.
> 
> My initial thinking was to have 2 nested loops which generate the row and
> column values of the table, with which I could search for the element that
> corresponds to these values and display it's data in a HTML table cell. But
> I can't find any XSL command which will let me do this, so maybe I'm
> approaching this from the wrong angle, I don't know.
> 
> E.g. The first row of the periodic table has Hydrogen (H) in the first
> column and Helium (He) in the last (18th) column with nothing in between:
> 
> <atom>
>   <name>Hydrogen</name>
>   <symbol>H</symbol>
>   <row>1</row>
>   <col>1</col>
> </atom>
> 
> <atom>
>   <name>Helium</name>
>   <symbol>He</symbol>
>   <row>1</row>
>   <col>18</col>
> </atom>
> 
> Needs to be transformed to:
> 
> <table>
>   <tr>
>     <td>H</td>
>     ... 16 empty cells (i.e. <td></td>)
>     <td>He</td>
>   </tr>
> </table>
> 
> Since the XML data does not contain empty atom elements for the gaps (and
> why should it?) I can't see how I can get my XSL code to create the empty
> cells. My line of thinking was to try the following (pseudo code):
> 
> foreach row from 1 to 9
>   write <tr>
>   foreach col from 1 to 18
>     write <td>
>     search for the atom node with row-element value = row and col-element
> value = col
>     display the symbol of the element we have found (if one was found)
>     write </td>
>   endforeach
>   write </tr>
> endforeach
> 
> Can this be done in XSL?
> 
> TIA

Hi.. it can be done with XSL but it's not easy.
Implementing such algorithms in XSLT can be a little hard since you
don't have variables in the way we use them in conventional programming 
languages. Variables in XSLT
may only have their value set once (like constants in conventional 
programming), then, in order
to simulate loops with iterators (like from i = 1 to 9) you can tweak 
XSLT in order to get what you
want using recursive templates.
Here's my solution to your problem that I found interesting to solve.

The trick here is to increment the current counter when calling the 
template recursively and
testing wheter you have reached your limit or not in order to keep-on 
calling the template or
stop doing it.


<xsl:call-template name="generate-row">
    <xsl:with-param name="current-row" select="1"/>
</xsl:call-template>

<xsl:template name="generate-row">
    <xsl:param name="current-row"/>
    <xsl:param name="max-row" select="9"/>
    <tr>
       <xsl:call-template name="generate-column">
          <xsl:with-param name="current-row" select="$current-row"/>
          <xsl:with-param name="current-column" select="1"/>
       </xsl:call-template>
    </tr>

    <xsl:if test="number($current-row) < number($max-row)">
      <xsl:call-template name="generate-row">
         <xsl:with-param name="current-row" select="$current-row + 1"/>
      </xsl:call-template>
    </xsl:if>
</xsl:template>


<xsl:template name="generate-column">
   <xsl:param name="current-row"/>
   <xsl:param name="current-column"/>
   <xsl:param name="max-column" select="18"/>

   <td>
      <!-- if the row cell exists, the template will be applied, 
otherwise it will remain empty -->
      <xsl:apply-templates select="atom[row = number($current-row) and 
column = number($current-column)]"/>
   </td>

   <xsl:if test="number($current-column) < number($max-column)">
      <xsl:call-template name="generate-column">
        <xsl:with-param name="current-row" select="$current-row"/>
        <xsl:with-param name="current-column" select="$current-coumn + 1"/>
        <xsl:with-param name="max-coumn" select="$max-column"/>
      </xsl:call-template>
   </xsl:if>
</xsl:template>

<xsl:template match="atom">
  <!-- put code here for whatever you want
    to generate once you have an atom element
  -->
</xsl:template>


transparent
Print
Mail
Like It
Disclaimer
.

These Archives are provided for informational purposes only and have been generated directly from the Altova mailing list archive system and are comprised of the lists set forth on www.altova.com/list/index.html. Therefore, Altova does not warrant or guarantee the accuracy, reliability, completeness, usefulness, non-infringement of intellectual property rights, or quality of any content on the Altova Mailing List Archive(s), regardless of who originates that content. You expressly understand and agree that you bear all risks associated with using or relying on that content. Altova will not be liable or responsible in any way for any content posted including, but not limited to, any errors or omissions in content, or for any losses or damage of any kind incurred as a result of the use of or reliance on any content. This disclaimer and limitation on liability is in addition to the disclaimers and limitations contained in the Website Terms of Use and elsewhere on the site.

.
.

transparent

transparent