tags:

views:

155

answers:

1

Say I have an xml document consisting of a list as shown below:

<Items>
  <Item>First Item</Item>
  <Item>Second Item</Item>
  <Item>Third Item</Item>
  <Item>4</Item>
  <Item>Five</Item>
</Items>

I want to convert it to a html table with two columns for the Item elements (I'm not fussed at the moment whether it's ordererd top-bottom-left-right or left-right-top-bottom).

<table>
  <tr>
    <td>First Item</td>
    <td>Second Item</td>
  </tr>
  <tr>
    <td>Third Item</td>
    <td>4</td>
  </tr>
  <tr>
    <td>Five</td>
    <td></td>
  </tr>
</table>

I understand I can get a table with a single column with the following xslt transform, but can't figure out how to get multiple columns.

<table>
  <xsl:for-each select="Items">
    <tr>
      <td><xsl:value-of select="Item"/></td>
    </tr>
  </xsl:for-each>
</table>
+1  A: 

Try this:

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:template match="/Items">
    <table>
      <xsl:for-each select="Item[position() mod 2 = 1]">
        <xsl:variable name="pos" select="position() - 1" />
        <tr>
          <td><xsl:value-of select="."/></td>
          <td><xsl:value-of select="//Item[position() = ($pos * 2) + 2]"/></td>
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>
</xsl:stylesheet>
Rubens Farias
Cool thanks for this. One question though, I'm already using a template to select other elements which come before the html table. It's looking like I can't nest a template within another template, is this correct?
mdresser
How do you mean nested? You could call one template from within another, e.g. using `xsl:call-template`.
0xA3
@mdresser, as divo said, you can do that without problems; if you wish, update this question (or open another one) explaining your complete problem;
Rubens Farias
@Rubens Farias sorry for the confusion. I commented before realising that I just needed to slot your <xsl:for-each> code into my stylesheet and that did the trick. Please ignore my first comment.
mdresser