Reputation: 1
I have an xml file about movies that looks like this (short version)
<movie id="movie_tt0004994">
<title>Bound on the Wheel </title>
<stars idref="star_nm0933368 star_nm0913085 star_nm0151606"/>
</movie>
<star id="star_nm0933368">
<name>Elsie Jane Wilson</name>
</star>
I want to transform this xml into html, using xslt. The html should be a table with the movie title in the first column, and the star NAMES (which are at most 3) in the following three columns.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<html>
<body>
<h2>movie list</h2>
<table border="1">
<th>Title</th>
<th colspan="3">Stars</th>
</tr>
<xsl:for-each select="IMDb/movie">
<tr>
<td><xsl:value-of select="title" /></td>
<xsl:for-each select="stars/@idref">
<xsl:variable name="curr_ref" select="."/>
<td><xsl:value-of select="//IMDb/star[@id=$curr_ref]/name"/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</font>
</body>
</html>
</xsl:template>
</xsl:transform>
The problem is that it only works for movies with one star. If there are multiple star ids in stars (like in the movie in the given part of my xml) then the corresponding columns in my table remain empty. I think this is because the line then makes curr_ref one long string of all the idrefs instead of three seperate ones. How should I go about this?
Upvotes: 0
Views: 623
Reputation: 167436
Assuming XSLT 2.0 you can use
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="star" match="star" use="@id"/>
<xsl:template match="/">
<html>
<body>
<h2>movie list</h2>
<table border="1">
<tr>
<th>Title</th>
<th colspan="3">Stars</th>
</tr>
<xsl:for-each select="IMDb/movie">
<tr>
<td><xsl:value-of select="title" /></td>
<xsl:for-each select="for $ref in tokenize(stars/@idref, '\s+') return key('star', $ref)">
<td><xsl:value-of select="name"/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:transform>
Assuming XSLT 1.0 (or later) and DTD support you can use
<!DOCTYPE IDMb [
<!ATTLIST star
id ID #REQUIRED>
<!ATTLIST stars
idref IDREFS #REQUIRED>
]>
<IMDb>
<movie id="movie_tt0004994">
<title>Bound on the Wheel </title>
<stars idref="star_nm0933368 star_nm0913085 star_nm0151606"/>
</movie>
<star id="star_nm0933368">
<name>Elsie Jane Wilson</name>
</star>
</IMDb>
and
<xsl:template match="/">
<html>
<body>
<h2>movie list</h2>
<table border="1">
<tr>
<th>Title</th>
<th colspan="3">Stars</th>
</tr>
<xsl:for-each select="IMDb/movie">
<tr>
<td><xsl:value-of select="title" /></td>
<xsl:for-each select="id(stars/@idref)">
<td><xsl:value-of select="name"/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
Upvotes: 2