Altova Mailing List Archives>Archive Index >microsoft.public.xml Archive Home >Recent entries >Thread Prev - Creating tables with missing cells [Thread Next] Re: Creating tables with missing cellsTo: 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> | ||||||
| Company | Legal | Press | Partners | Careers | Sitemap | Contact Us | Altova Blog | Mobile | Full Site | |||
|
