Reputation: 3
I am new to XSLT and need your help. I have to create word tables in XSLT. The number of columns and rows is dynamic.
This is an example XML:
<Movies>
<Genre name="Action">
<Movie>
<Name>Crash</Name>
<Released>2005</Released>
</Movie>
</Genre>
<Genre name="Drama">
<Movie>
<Name>The Departed</Name>
<Released>2006</Released>
</Movie>
<Movie>
<Name>The Pursuit of Happyness</Name>
<Released>2006</Released>
</Movie>
</Genre>
<Genre name="Comedy">
<Movie>
<Name>The Bucket List</Name>
<Released>2007</Released>
</Movie>
</Genre>
</Movies>
The genre element can contain any number of movie elements.
The Table should look like this:
This is the XSLT:
<xsl:template match="/">
<w:document>
<w:body>
<w:tbl>
<w:tr>
<xsl:for-each select="/Movies/Genre">
<w:tc>
<w:p>
<w:r>
<w:t>
<xsl:value-of select="@name"/>
</w:t>
</w:r>
</w:p>
</w:tc>
</xsl:for-each>
</w:tr>
<!-- Movies? -->
</w:tbl>
</w:body>
</w:document>
</xsl:template>
The column header is not a problem, but how can I write the movie elements as desired? Is there a way with two for-each loops, or do I have to use apply-templates? Thanks for your support!
Upvotes: 0
Views: 2407
Reputation: 474
Unfortunately I'm not familiar with DOCX format, so you may want to correct the output, but as for the XSLT, the following should do the trick
<xsl:template match="/">
<w:document>
<w:body>
<w:tbl>
<w:tr>
<xsl:for-each select="/Movies/Genre">
<w:tc>
<w:p>
<w:r>
<w:t>
<xsl:value-of select="@name"/>
</w:t>
</w:r>
</w:p>
</w:tc>
</xsl:for-each>
</w:tr>
<!-- Movies? -->
<xsl:call-template name="movies-row">
<xsl:with-param name="i" select="1"></xsl:with-param>
</xsl:call-template>
</w:tbl>
</w:body>
</w:document>
</xsl:template>
<xsl:template name="movies-row">
<xsl:param name="i"/>
<w:tr>
<xsl:for-each select="/Movies/Genre">
<w:tc>
<w:p>
<w:r>
<w:t>
<xsl:choose>
<xsl:when test="count(Movie) >= $i">
<xsl:value-of select="concat(Movie[$i]/Name, ' (', Movie[$i]/Released, ')')"/>
</xsl:when>
<xsl:otherwise>
<!-- empty cell -->
</xsl:otherwise>
</xsl:choose>
</w:t>
</w:r>
</w:p>
</w:tc>
</xsl:for-each>
</w:tr>
<xsl:if test="/Movies/Genre[count(Movie) > $i]">
<xsl:call-template name="movies-row">
<xsl:with-param name="i" select="$i + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Upvotes: 1