xsl-list
[Top] [All Lists]

RE: converting empty nodes to col/rowspan values

2004-04-13 14:30:45
The key is picking the empty cells before the next occupied cell, and after the 
current cell. You can do this using the following-sibling, and 
preceding-sibling axis' like this:

  <xsl:variable name="the-cell" select="."/>
  <xsl:variable name="num-joined" select="
              count(following-sibling::cell[ .='' and 
                      (generate-id(preceding-sibling::cell[not(.='')][1]) = 
generate-id($the-cell))
                    ])"/>

following-sibling::cell[.=''] selects only cells with no text content

preceding-sibling::cell[not(.='')][1] selects the nearest preceding sibling 
that has text content

Use generate-id to ensure that you are comparing the correct node, and not the 
node value.

Put it all together and get something like this:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
        <xsl:output method="xml" indent="yes" encoding="utf-8"/>

<xsl:template match="/">
  <html>
      <xsl:apply-templates/>
  </html>
</xsl:template>

<xsl:template match="table">
  <table border="1">
    <xsl:apply-templates/>
  </table>
</xsl:template>

<xsl:template match="row">
  <tr>
  <!-- apply templates only to those that are not empty, or if they are the 
first empty -->
    <xsl:apply-templates select="cell[not(preceding-sibling::cell) or 
not(.='')]"/>
  </tr>
</xsl:template>

<xsl:template match="cell">
  <xsl:variable name="the-cell" select="."/>
  <xsl:variable name="num-joined" select="
              count(following-sibling::cell[ .='' and 
                      (generate-id(preceding-sibling::cell[not(.='')][1]) = 
generate-id($the-cell))
                    ])"/>
  <td>
  <xsl:if test="$num-joined">
    <xsl:attribute name="colspan">
      <xsl:value-of select="$num-joined + 1"/>
    </xsl:attribute>
  </xsl:if>
    <xsl:value-of select="."/>
  </td>
</xsl:template>

</xsl:stylesheet>


Josh

-----Original Message-----
From: Reece, Michael Clark [mailto:REECEM(_at_)MAIL(_dot_)ECU(_dot_)EDU]
Sent: Tuesday, April 13, 2004 1:40 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] converting empty nodes to col/rowspan values


I am try to format an html with colspan and rowspan values for empty nodes.
For example with:
 
<?xml version="1.0"?>
<table>
  <row>
    <cell>Sample Table</cell>
    <cell></cell>
    <cell></cell>
    <cell></cell>
    <cell></cell>
  </row>
  <row>
    <cell>A</cell>
    <cell>B</cell>
    <cell></cell>
    <cell>C</cell>
    <cell></cell>
  </row>
  <row>
    <cell></cell>
    <cell>D</cell>
    <cell>E</cell>
    <cell>F</cell>
    <cell>G</cell>
  </row>
  <row>
    <cell>H</cell>
    <cell>I</cell>
    <cell>J</cell>
    <cell>K</cell>
    <cell></cell>
  </row>
</table>
 
I want the first row to be:
  <tr><td colspan=5>Sample Table</td></tr>
And the second row to be:
  <tr><td rowspan=2>A</td><td colspan=2>B</td><td colspan=2>C</td></tr>
 
And so forth...
 
This is my template:
 
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform
<http://www.w3.org/1999/XSL/Transform> ">
<xsl:template match="/">
      <html>
      <table border="1">
      <xsl:apply-templates/>
      </table>
      </html>
</xsl:template>
<xsl:template match="table">
      <xsl:for-each select="row">
            <tr><xsl:apply-templates/></tr>
      </xsl:for-each>
</xsl:template>
<xsl:template match="cell">
      <td><xsl:value-of select="."/></td>
</xsl:template>
</xsl:stylesheet>
 
I have tried many iterations but cannot figure this out.  Thanks...
 
Michael Reece

--+------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--+--

<Prev in Thread] Current Thread [Next in Thread>