Recursive variable - xslt

First XML
<?xml version="1.0"?>
<response>
<status>
<code>0</code>
</status>
<newsList>
<news>
<id>1</id>
<title>some</title>
<date>30.11.2011T00:00.00</date>
<shortText>some short text</shortText>
<important>LOW</important>
</news>
Second XML
<?xml version="1.0"?>
<response>
<status>
<code>0</code>
</status>
<newsList>
<news>
<id>1</id>
<text>
Some text here
</text>
</news>
The result should be dysplaing title date and short Text from the first XML and the text from the second XML.
Below the XSLT I got so far.
<xsl:template match="response">
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">shortText</th>
<th align="left">date</th>
<th align="left">text</th>
</tr>
<xsl:for-each select="newsList/news">
<tr>
<td><xsl:value-of select="title" /></td>
<td><xsl:value-of select="shortText" /></td>
<td><xsl:value-of select="date" /></td>
<td><xsl:value-of select="document('news-details.xml')//news[id=$id_news]/text"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
But this will always show the text from the news number 1.
I know is't not possible to update the vaulue but how can get it done?

Here is an example using a key:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" version="5.0"/>
<xsl:param name="url2" select="'news-details.xml'"/>
<xsl:variable name="doc2" select="document($url2, /)"/>
<xsl:key name="k1" match="news" use="id"/>
<xsl:template match="/">
<html>
<head>
<title>Example</title>
</head>
<body>
<table>
<thead>
<tr>
<th>Title</th>
<th>short text</th>
<th>date</th>
<th>text</th>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="//news"/>
</tbody>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="news">
<xsl:variable name="id" select="id"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="shortText"/></td>
<td><xsl:value-of select="date"/></td>
<td>
<xsl:for-each select="$doc2">
<xsl:value-of select="key('k1', $id)/text"/>
</xsl:for-each>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>

<xsl:template match="response">
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">shortText</th>
<th align="left">date</th>
<th align="left">text</th>
</tr>
<xsl:apply-templates select="newsList/news"/>
</table>
</xsl:template>
<xsl:template match="newsList/news">
<xsl:variable name="id_news" select="ID"/>
<tr>
<td><xsl:value-of select="title" /></td>
<td><xsl:value-of select="shortText" /></td>
<td><xsl:value-of select="date" /></td>
<td>
<xsl:apply-templates select="document('news-details.xml')//news[id=$id_news]/text"/>
</td>
</tr>
</xsl:template>
<xsl:template match="text">
<xsl:value-of select="."/>
</xsl:template>

Related

how locate an element in source xml file dynamically in a loop

if we have the following xml input:
<root xmlns:ns="http://www.blabla">
<ns:element1 attribute="attr1">10</ns:element1>
<ns:element1 attribute="attr2">20</ns:element1>
<ns:element2 attribute="attr1">30</ns:element1>
<ns:element2 attribute="attr2">40</ns:element1>
</root>
how can we locate each element inside a for-each in xslt?
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="root">
<html>
<body>
<h2>My Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Column 1</th>
<th style="text-align:left">Column 2</th>
</tr>
<xsl:for-each select="1 to 10">
<xsl:variable name="name" select="concat('element', .)"/>
<tr>
<td>
<xsl:value-of select="???what should be here???[lower-case(#attribute)='attr0']"/>
</td>
<td>
<xsl:value-of select="???same question???[lower-case(#attribute)='attr1']"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
Please note that I want to follow this procedure (if possible) as the input is very dynamic and we don't always get all elements in every row.
I appreciate your help.
The expression you want is this...
<xsl:value-of select="*[local-name() = $name][lower-case(#attribute)='attr1']"/>
... Except this will fail with an error along the lines of Required item type of context item for the child axis is node(); supplied expression (.) has item type xs:integer, due to the code being executed in the context of the xsl:for-each on atomic values. To get around this, you will need to save a reference to the child elements in a variable before the xsl:for-each.
Try this XSLT
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="root">
<html>
<body>
<h2>My Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Title</th>
</tr>
<xsl:variable name="children" select="*" />
<xsl:for-each select="1 to 10">
<xsl:variable name="name" select="concat('element', .)"/>
<tr>
<td>
<xsl:value-of select="$children[local-name() = $name][lower-case(#attribute)='attr1']"/>
</td>
<td>
<xsl:value-of select="$children[local-name() = $name][lower-case(#attribute)='attr2']"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Or slightly better, to reduce code duplication...
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="root">
<html>
<body>
<h2>My Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Title</th>
</tr>
<xsl:variable name="children" select="*" />
<xsl:for-each select="1 to 10">
<xsl:variable name="name" select="concat('element', .)"/>
<xsl:variable name="element" select="$children[local-name() = $name]"/>
<tr>
<td>
<xsl:value-of select="$element[lower-case(#attribute)='attr1']"/>
</td>
<td>
<xsl:value-of select="$element[lower-case(#attribute)='attr2']"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Note, I would really consider changing your input XML if you have control over it. Numbering elements using the element name makes it harder to manipulate. Ideally you would do this instead...
<ns:element num="1" attribute="attr1">10</ns:element>
If you dont have control try to take count of the elements and run the loop as per count like this:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://www.blabla">
<xsl:template match="root">
<html>
<body>
<h2>My Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Column 1</th>
<th style="text-align:left">Column 2</th>
</tr>
<xsl:variable name="all-element" select="count(//*:element)"/>
<xsl:for-each select="*[concat('ns:element', (1 to $all-element))]">
<xsl:message select="."/>
<tr>
<td>
<xsl:value-of select="#attribute"/>
</td>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

XSL-FO Table break every 5 columns

I am creating an fo:table that has 25 columns.
When I am converting to PDF the table is too wide for the size of the page (A4), how can I break the table by column, for example, every 5 columns I want to write on another page?
Thanks
I have taken an example of table which has nine column like:
<Table>
<thead>
<tr>
<td>Head1</td>
<td>Head2</td>
<td>Head3</td>
<td>Head4</td>
<td>Head5</td>
<td>Head6</td>
<td>Head7</td>
<td>Head8</td>
<td>Head9</td>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>2-1</td>
<td>2-2</td>
<td>2-3</td>
<td>2-4</td>
<td>2-5</td>
<td>2-6</td>
<td>2-7</td>
<td>2-8</td>
<td>2-9</td>
</tr>
<tr>
<td>3-1</td>
<td>3-2</td>
<td>3-3</td>
<td>3-4</td>
<td>3-5</td>
<td>3-6</td>
<td>3-7</td>
<td>3-8</td>
<td>3-9</td>
</tr>
</tbody>
</Table>
Now, I have created XSLT to break it into multiple table by passing integer value in <xsl:param name="columnNumber"/> param:
<?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output indent="yes"/>
<xsl:param name="columnNumber" select="xs:integer(4)"/>
<xsl:template match="Table">
<xsl:param name="countColumn" select="count(//tbody/tr[1]/td)"/>
<xsl:choose>
<xsl:when test="$countColumn gt $columnNumber">
<xsl:call-template name="divideTable">
<xsl:with-param name="tableToGenerate" select="ceiling($countColumn div $columnNumber)"/>
<xsl:with-param name="orginialTable" select="self::*"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="*"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="divideTable">
<xsl:param name="tableToGenerate"/>
<xsl:param name="orginialTable"/>
<xsl:param name="start" select="xs:integer(1)"/>
<xsl:param name="end" select="$columnNumber"/>
<xsl:param name="counter" select="xs:integer(1)"/>
<xsl:choose>
<xsl:when test="$counter le $tableToGenerate">
<Table>
<thead>
<xsl:copy-of
select="$orginialTable/thead/tr/td[position() le $end and position() ge $start]"/>
</thead>
<tbody>
<xsl:for-each select="$orginialTable/tbody/tr">
<tr>
<xsl:copy-of select="td[position() le $end and position() ge $start]"/>
</tr>
</xsl:for-each>
</tbody>
</Table>
<xsl:call-template name="divideTable">
<xsl:with-param name="start" select="xs:integer(($columnNumber * $counter) + 1)"/>
<xsl:with-param name="end" select="xs:integer(($columnNumber * $counter) + $columnNumber)"/>
<xsl:with-param name="tableToGenerate" select="$tableToGenerate"/>
<xsl:with-param name="orginialTable" select="$orginialTable"/>
<xsl:with-param name="counter" select="xs:integer($counter + 1)"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
It gives me ouput:
<?xml version="1.0" encoding="UTF-8"?>
<Table xmlns:xs="http://www.w3.org/2001/XMLSchema">
<thead>
<td>Head1</td>
<td>Head2</td>
<td>Head3</td>
<td>Head4</td>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>2-1</td>
<td>2-2</td>
<td>2-3</td>
<td>2-4</td>
</tr>
<tr>
<td>3-1</td>
<td>3-2</td>
<td>3-3</td>
<td>3-4</td>
</tr>
</tbody>
</Table>
<Table xmlns:xs="http://www.w3.org/2001/XMLSchema">
<thead>
<td>Head5</td>
<td>Head6</td>
<td>Head7</td>
<td>Head8</td>
</thead>
<tbody>
<tr>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
</tr>
<tr>
<td>2-5</td>
<td>2-6</td>
<td>2-7</td>
<td>2-8</td>
</tr>
<tr>
<td>3-5</td>
<td>3-6</td>
<td>3-7</td>
<td>3-8</td>
</tr>
</tbody>
</Table>
<Table xmlns:xs="http://www.w3.org/2001/XMLSchema">
<thead>
<td>Head9</td>
</thead>
<tbody>
<tr>
<td>9</td>
</tr>
<tr>
<td>2-9</td>
</tr>
<tr>
<td>3-9</td>
</tr>
</tbody>
</Table>
Please have a look on this and check if this example helps
My solution was creating two independent tables.
Then I created two block of xsl templates, to differentiate the first block of the second block I used mode function.
Like this:
Table
....
<xsl:apply-templates select="content[#teste='1']" mode="first" />
....
<xsl:apply-templates select="content[#teste='1']" mode="second" />
....
XSL Templates block
....
<xsl:template match="content[#teste='1']" mode="first">
....
<xsl:template match="content[#teste='1']" mode="second">
....

How to delete an empty column in HTML table using XSLT?

How to delete an empty column in HTML table using XSLT, and having something like this:
<table id="cas6">
<tr>
<td />
<td>
<table>
<tr>
<td>rechin</td>
<td />
</tr>
<tr>
<td>amarillo</td>
<td />
</tr>
</table>
</td>
</tr>
</table>
<table id="cas7">
<tr>
<td>rechin</td>
<td />
</tr>
<tr>
<td>amarillo</td>
<td />
</tr>
<tr>
<td>this shouldn't been</td>
<td>deleted</td>
</tr>
</table>
To delete the empty column, this being said to remove td's which are empty in all tr's in a Xth position
Here is a very simple solution:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|#*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="td[not(node())]">
<xsl:variable name="vPos" select="position()"/>
<xsl:if test="../../tr/td[position() = $vPos]/node()">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document (made well-formed):
<html>
<table border="1" id="cas6">
<tr>
<td/>
<td>
<table border="1">
<tr>
<td>rechin</td>
<td />
</tr>
<tr>
<td>amarillo</td>
<td />
</tr>
</table></td>
</tr>
</table>
<table border="1" id="cas7">
<tr>
<td>rechin</td>
<td />
</tr>
<tr>
<td>amarillo</td>
<td />
</tr>
<tr>
<td>this shouldn't been</td>
<td>deleted</td>
</tr>
</table>
</html>
The wanted correct result is produced:
<html>
<table border="1" id="cas6">
<tr>
<td>
<table border="1">
<tr>
<td>rechin</td>
</tr>
<tr>
<td>amarillo</td>
</tr>
</table></td>
</tr>
</table>
<table border="1" id="cas7">
<tr>
<td>rechin</td>
<td></td>
</tr>
<tr>
<td>amarillo</td>
<td></td>
</tr>
<tr>
<td>this shouldn't been</td>
<td>deleted</td>
</tr>
</table>
</html>
This is the XSLT that worked for me.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="td[not(node())]">
<xsl:variable name="pos" select="position()" />
<xsl:variable name="emptyTds" select="count(../../tr/td[position() = $pos and not(node())])" />
<xsl:variable name="allTds" select="count(../../tr/td[position() = $pos])" />
<xsl:if test="$emptyTds != $allTds">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
If my understanding of the question is correct, for a given table, if all entries in the nth column are empty, you want to delete that column from the table?
Try this XSLT then
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="td">
<xsl:variable name="columnNumber" select="position()"/>
<xsl:if test="../../tr/td[position()=$columnNumber][* or text()]">
<xsl:copy>
<xsl:value-of select="$columnNumber"/>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
This is the 'identity' transform, but when it matches a TD element, it first gets the column number, and then checks if any other column in other rows are empty. If it finds any non-empty cells in the same column, it copies the TD element, otherwise it is ignored.

Xslt transformation for-each

Could anyone help me with the following transformation?
Here is the XML
<Chart>
<Chart.Series>
<DataSeries LegendText="Complete On Time" >
<DataSeries.DataPoints>
<DataPoint AxisXLabel="Sep 09" YValue="10" />
<DataPoint AxisXLabel="Oct 09" YValue="11" />
<DataPoint AxisXLabel="Nov 09" YValue="12" />
</DataSeries.DataPoints>
</DataSeries>
<DataSeries LegendText="Complete Overdue" >
<DataSeries.DataPoints>
<DataPoint YValue="1" />
<DataPoint YValue="2" />
<DataPoint YValue="3" />
</DataSeries.DataPoints>
</DataSeries>
</Chart.Series>
</Chart>
and here is the output id like
<table>
<thead>
<tr>
<th></th>
<th>Complete On Time</th>
<th>Complete Overdue</th>
</tr>
</thead>
<tbody>
<tr>
<th>Sep 09</th>
<th>10</th>
<th>1</th>
</tr>
<tr>
<th>Oct 09</th>
<th>11</th>
<th>2</th>
</tr>
<tr>
<th>Nov 09</th>
<th>12</th>
<th>3</th>
</tr>
</tbody>
A more natural solution:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<!-- basic table structure -->
<xsl:template match="Chart">
<table>
<thead>
<xsl:apply-templates select="Chart.Series" mode="thead" />
</thead>
<tbody>
<xsl:apply-templates select="Chart.Series" mode="tbody" />
</tbody>
</table>
</xsl:template>
<!-- table head -->
<xsl:template match="Chart.Series" mode="thead">
<tr>
<th />
<xsl:for-each select="DataSeries">
<th>
<xsl:value-of select="#LegendText" />
</th>
</xsl:for-each>
</tr>
</xsl:template>
<!-- table body -->
<xsl:template match="Chart.Series" mode="tbody">
<xsl:variable name="ds" select="DataSeries" />
<!-- the first data series contains the labels -->
<xsl:for-each select="$ds[1]/*/DataPoint">
<xsl:variable name="pos" select="position()" />
<tr>
<td>
<xsl:value-of select="#AxisXLabel" />
</td>
<!-- process all data points at the current position -->
<xsl:apply-templates select="$ds/*/DataPoint[$pos]" />
</tr>
</xsl:for-each>
</xsl:template>
<!-- data points become a <td> -->
<xsl:template match="DataPoint">
<td>
<xsl:value-of select="#YValue" />
</td>
</xsl:template>
</xsl:stylesheet>
Note that I use template modes to do different things with the same input.
The result is:
<table>
<thead>
<tr>
<th />
<th>Complete On Time</th>
<th>Complete Overdue</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sep 09</td>
<td>10</td>
<td>1</td>
</tr>
<tr>
<td>Oct 09</td>
<td>11</td>
<td>2</td>
</tr>
<tr>
<td>Nov 09</td>
<td>12</td>
<td>3</td>
</tr>
</tbody>
</table>
This is something close. It's been a couple of year for me though that I've done XSLT - ignore bad style.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output indent="yes" omit-xml-declaration="yes" ></xsl:output>
<xsl:template match="/">
<table>
<thead>
<tr>
<th></th>
<xsl:apply-templates select=".//DataSeries" />
</tr>
</thead>
<tbody>
<xsl:apply-templates select="//DataSeries[1]//DataPoint">
<xsl:with-param name="datablock">1</xsl:with-param>
</xsl:apply-templates>
</tbody>
</table>
</xsl:template>
<xsl:template match="DataSeries">
<th>
<xsl:value-of select="#LegendText"></xsl:value-of>
</th>
</xsl:template>
<xsl:template match="DataPoint">
<xsl:param name="datablock" />
<xsl:variable name="posi" select="position()"></xsl:variable>
<xsl:if test="$datablock = 1">
<tr>
<xsl:for-each select="#*">
<th>
<xsl:value-of select="."></xsl:value-of>
</th>
</xsl:for-each>
<xsl:apply-templates select="//DataSeries[$datablock+1]//DataPoint[$posi]">
<xsl:with-param name="datablock" select="$datablock + 1">
</xsl:with-param>
</xsl:apply-templates>
</tr>
</xsl:if>
<xsl:if test="$datablock != 1">
<xsl:for-each select="#*">
<th>
<xsl:value-of select="."></xsl:value-of>
</th>
</xsl:for-each>
<xsl:apply-templates select="//DataSeries[$datablock+1]//DataPoint[$posi]">
<xsl:with-param name="datablock" select="$datablock + 1">
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
</xsl:template>

Matrix transposition in XSLT

I'm trying to go from this kind of input:
<col title="one">
<cell>a</cell> <cell>b</cell> <cell>c</cell> <cell>d</cell>
</col>
<col title="two">
<cell>e</cell> <cell>f</cell> <cell>g</cell>
</col>
... to this HTML output with XSLT:
<table>
<tr> <th>one</th> <th>two</th> </tr>
<tr> <td>a</td> <td>e</td> </tr>
<tr> <td>b</td> <td>f</td> </tr>
<tr> <td>c</td> <td>g</td> </tr>
<tr> <td>d</td> </tr>
</table>
In other words I want to perform a matrix transposition. I couldn't find a simple way to do that, there probably isn't, I guess; how about a complicated one? While searching on Google I found hints that a way to solve this was through recursion. Any idea appreciated.
One possibility is to find the <col> with the most cells and then iterate over them in a nested loop. This guarantees the generation of a structurally valid HTML table.
<!-- this variable stores the unique ID of the longest <col> -->
<xsl:variable name="vMaxColId">
<xsl:for-each select="/root/col">
<xsl:sort select="count(cell)" data-type="number" order="descending" />
<xsl:if test="position() = 1">
<xsl:value-of select="generate-id()" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
<!-- and this selects the children of that <col> for later iteration -->
<xsl:variable name="vIter" select="
/root/col[generate-id() = $vMaxColId]/cell
" />
<xsl:template match="root">
<xsl:variable name="columns" select="col" />
<table>
<!-- output the <th>s -->
<tr>
<xsl:apply-templates select="$columns/#title" />
</tr>
<!-- make as many <tr>s as there are <cell>s in the longest <col> -->
<xsl:for-each select="$vIter">
<xsl:variable name="pos" select="position()" />
<tr>
<!-- make as many <td>s as there are <col>s -->
<xsl:for-each select="$columns">
<td>
<xsl:value-of select="cell[position() = $pos]" />
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template match="col/#title">
<th>
<xsl:value-of select="." />
</th>
</xsl:template>
Applied to
<root>
<col title="one">
<cell>a</cell> <cell>b</cell> <cell>c</cell> <cell>d</cell>
</col>
<col title="two">
<cell>e</cell> <cell>f</cell> <cell>g</cell>
</col>
</root>
this produces:
<table>
<tr>
<th>one</th> <th>two</th>
</tr>
<tr>
<td>a</td> <td>e</td>
</tr>
<tr>
<td>b</td> <td>f</td>
</tr>
<tr>
<td>c</td> <td>g</td>
</tr>
<tr>
<td>d</td> <td></td>
</tr>
</table>
From Marrow:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="input">
<table border="1">
<xsl:apply-templates select="col[1]/cell"/>
</table>
</xsl:template>
<xsl:template match="cell">
<xsl:variable name="curr-pos" select="position()"/>
<tr>
<td>
<xsl:copy-of select="node()|../following-sibling::col/cell[$curr-pos]/node()"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
I put input tags around your xml to make it closer match an example I found.
(getting closer).
BTW: you can test by adding this as your 2nd line to your xml:
<?xml-stylesheet type="text/xsl" href="NonLinear.xslt"?>