xsl-list
[Top] [All Lists]

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

2004-04-19 13:10:20
-----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