RE: [xsl] Outputing tables on the fly (Was incrementing mid-stream part 4) - [Long: XML/XSL samples included]

Subject: RE: [xsl] Outputing tables on the fly (Was incrementing mid-stream part 4) - [Long: XML/XSL samples included]
From: "Andreas L. Delmelle" <a_l.delmelle@xxxxxxxxxx>
Date: Mon, 19 Apr 2004 22:10:20 +0200
> -----Original Message-----
> From: Durston, Andrew (AGRE)
>

Hi,

> The usual caveats about this probably being lousy code (haven't
> coded in years and new to XSL to boot). We are taking the XML
> file and generating HTML documents from it.
>

Well, based on your input XML and XSL code, let's try to devise an alternate
solution in order to demonstrate to you some features of XSLT --beware
though, may turn out to be lousy code anyway ;)

First things first... since all the objects you *do* want to process have to
have an objectnumber child that contains (or is it starts-with?) '1.2.2.',
you can easily filter those out with an XPath like so:

<xsl:for-each select="test-plan/doorsobject[
                starts-with(objectnumber,'1.2.2.')]">

And, perhaps more importantly: stop thinking loops, start thinking
hierarchies. Your input XML seems a perfect example, so trade the
xsl:for-each for an xsl:apply-templates, and define templates where you put
the rest of the code:

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:template match="/">
  <html>
    <xsl:apply-templates select="test-plan/doorsobject[
                starts-with(objectnumber,'1.2.2.')]" />
  </html>
</xsl:template>

<xsl:template match="doorsobject[objectlevel=4]">
  <!-- If object level 4, then test header -->
    <h4>[Test case]
      <xsl:value-of select="concat(objectnumber,' ')"/>
      <xsl:value-of select="objectheading"/>
    </h4>
</xsl:template>

<xsl:template match="doorsobject[objectlevel &gt;= 5 and
                                  tabletype='TableNone']">
  <!-- If object level 5 or greater, and paragraph,
       process like a paragraph -->
  <p>[Starting point for Test cases]
    <xsl:value-of select="objecttext"/>
  </p>
</xsl:template>

<xsl:template match="doorsobject[objectlevel &gt; 5 and
                                  tabletype='TableCell' and
                                  tablecell/tablecellrow=1 and
                                  tablecell/tablecellcol=1]">
  <!-- If object level 5 or greater, and a table entry,
       and first table entry, then initiate table-creation -->
  <p>Found a table beginning</p>
    <table border="1">
    <xsl:apply-templates select=". |
                           following-sibling::doorsobject[
                           starts-with(objectnumber,substring(
                             current()/objectnumber,1,6)) and
                           objectlevel = current()/objectlevel and
                           tabletype=current()/tabletype and
                           tablecell/tablecellcol=
                             current()/tablecell/tablecellcol]"
                         mode="table-row" />
    </table>
  <p>
    <xsl:text>end of table starting at &apos;</xsl:text>
    <xsl:value-of select="objecttext"/>
    <xsl:text>&apos;</xsl:text>
  </p>
</xsl:template>

<xsl:template match="doorsobject" mode="table-row">

  <!-- a row -->
  <tr>
    <xsl:for-each select=". | following-sibling::doorsobject[
                    starts-with(objectnumber,substring(
                      current()/objectnumber,1,6)) and
                    objectlevel = current()/objectlevel and
                    tabletype=current()/tabletype and
                    tablecell/tablecellrow=
                      current()/tablecell/tablecellrow]">
      <!-- a column -->
      <td>
        <xsl:copy-of select="objecttext"/>
      </td>
    </xsl:for-each>
  </tr>

</xsl:template>

<xsl:template match="text()" />

</xsl:stylesheet>


AFAICT, the tablenumrows and tablenumcols nodes are negligeable quantities,
so I did neglect them...


Hope this helps!

Cheers,

Andreas

Current Thread