Christopher Johnson Christopher Johnson - 1 month ago 15
HTML Question

Create two tables from xml using xslt based on it an node attribute that is less than a integer value

I created an xml file containing my 15 favorite movies that have several attributes. The xml file can be seen below:

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="movies.xslt" type="text/xsl" ?>

<AllMovies>
<movie id="01">
<title>Wizard of Oz</title>
<director>King Vidor</director>
<year>1939</year>
<genre>
<g1>Classics, </g1>
<g2>Sci-Fi, </g2>
<g3>Fantasy</g3>
</genre>
<link>https://www.rottentomatoes.com/m/the_wizard_of_oz_1939/</link>
</movie>
<movie id="02">
<title>The Third Man</title>
<director>Carol Reed</director>
<year>1949</year>
<genre>
<g1>Classics, </g1>
<g2>Mystery, </g2>
<g3>Suspense</g3>
</genre>
<link>https://www.rottentomatoes.com/m/the-third-man/</link>
</movie>
<movie id="03">
<title>Citizen Kane</title>
<director>Orson Welles</director>
<year>1941</year>
<genre>
<g1>Classics, </g1>
<g2>Drama, </g2>
<g3>Mystery, </g3>
<g4>Suspense</g4>
</genre>
<link>https://www.rottentomatoes.com/m/citizen_kane/</link>
</movie>
<movie id="04">
<title>The Godfather</title>
<director>Francis Ford Coppola</director>
<year>1972</year>
<genre>
<g1>Suspense, </g1>
<g2>Drama</g2>
</genre>
<link>https://www.rottentomatoes.com/m/godfather/</link>
</movie>
<movie id="05">
<title>Inside Out</title>
<director>Pete Docter</director>
<year>2015</year>
<genre>
<g1>Comedy, </g1>
<g2>Animation, </g2>
<g3>Children</g3>
</genre>
<link>https://www.rottentomatoes.com/m/inside_out_2015/</link>
</movie>
<movie id="06">
<title>E.T. The Extra-Terrestrial</title>
<director>Steven Spielberg</director>
<year>1982</year>
<genre>
<g1>Sci-Fi, </g1>
<g2>Children, </g2>
<g3>Fantasy</g3>
</genre>
<link>https://www.rottentomatoes.com/m/et_the_extraterrestrial/</link>
</movie>
<movie id="07">
<title>Toy Story 3</title>
<director>Lee Unkrich</director>
<year>2010</year>
<genre>
<g1>Animation, </g1>
<g2>Comedy, </g2>
<g3>Children, </g3>
<g4>Sci-Fi</g4>
</genre>
<link>https://www.rottentomatoes.com/m/toy_story_3/</link>
</movie>
<movie id="08">
<title>Selma</title>
<director>Ava DuVernay</director>
<year>2015</year>
<genre>
<g1>Biopic, </g1>
<g2>History</g2>
</genre>
<link>https://www.rottentomatoes.com/m/selma/</link>
</movie>
<movie id="09">
<title>Zootopia</title>
<director>Bryon Howard</director>
<year>2016</year>
<genre>
<g1>Animation, </g1>
<g2>Comedy, </g2>
<g3>Action, </g3>
<g4>Adventure</g4>
</genre>
<link>https://www.rottentomatoes.com/m/zootopia/</link>
</movie>
<movie id="10">
<title>Taxi Driver</title>
<director>Martin Scorsese</director>
<year>1976</year>
<genre>
<g1>Drama, </g1>
<g2>Mystery, </g2>
<g3>Suspense</g3>
</genre>
<link>https://www.rottentomatoes.com/m/taxi_driver/</link>
</movie>
<movie id="11">
<title>The Dark Knight</title>
<director>Christopher Nolan</director>
<year>2008</year>
<genre>
<g1>Action, </g1>
<g2>Crime, </g2>
<g3>Drama</g3>
</genre>
<link>https://www.rottentomatoes.com/m/the_dark_knight</link>
</movie>
<movie id="12">
<title>The Girl with The Dragon Tattoo</title>
<director>David Fincher</director>
<year>2011</year>
<genre>
<g1>Drama, </g1>
<g2>Mystery, </g2>
<g3>Suspense</g3>
</genre>
<link>https://www.rottentomatoes.com/m/the_girl_with_the_dragon_tattoo/</link>
</movie>
<movie id="13">
<title>The Last King of Scotland</title>
<director>Kevin Macdonald</director>
<year>2006</year>
<genre>
<g1>Drama, </g1>
<g2>Thriller</g2>
</genre>
</movie>
<movie id="14">
<title>The Hurt Locker</title>
<director>Kathryn Gigelow</director>
<year>2009</year>
<genre>
<g1>Action, </g1>
<g2>Adventure, </g2>
<g3>Drama</g3>
</genre>
</movie>
<movie id="15">
<title>Aliens</title>
<director>James Cameron</director>
<year>1986</year>
<genre>
<g1>Horror, </g1>
<g2>Thriller, </g2>
<g3>Adventure, </g3>
<g4>Sci-Fi</g4>
</genre>
</movie>
</AllMovies>


Based on the above xml file I have been able to make a template that displays all the data in a formatted table. What I would like to do is create two tables based on the attribute in each movie node. So for example I would like every movie that was released before the year 2005 to be on the first table then have a space and add another table that has all the movies from 2005 and newer. I have tried using an if statement in the root template and the "movie" template and can not get it to work.

Below is my xslt code attemp to solve the problem:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>

<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>Assignment 1</title>
<style>
body{
font-family: Arial, Helvetica, sans-serif
}

table{
background-color: #d4ecfb;
border-collapse: collapse;
margin-left: 10px;
}

th, tr, td{
border: 1px solid black;
}

#id{
width:3%;
text-align: left;
padding-left: 3px;
}

#title{
width:25%;
text-align: left;
}

#director{
width:20%;
text-align: left;
}

#year{
width: 5%;
text-align: left;
}

#headers{
background-color: #FF69B4;
}

td{
padding-left: 3px;
}
</style>
</head>
<body>
<h1>Top 15 Favorite Movies</h1>
<!-- &lt; is the hex for < and &gt; is for the > symbol-->
<table>
<tr id="headers">
<th id="id">ID</th>
<th id="title">Title</th>
<th id="director">Director</th>
<th id="year">Year</th>
<th id="genre">Genre</th>
<th id="link">Link</th>
</tr>
<xsl:if test="year &lt; 2005">
<xsl:apply-templates select="AllMovies/movie">
<xsl:sort select="title" order="ascending"/>
</xsl:apply-templates>
</xsl:if>
<tr></tr>
<xsl:if test="year &gt; 2005">
<xsl:apply-templates select="AllMovies/movie">
<xsl:sort select="title" order="ascending"/>
</xsl:apply-templates>
</xsl:if>
</table>
</body>
</html>
</xsl:template>

<xsl:template match="AllMovies/movie">
<tr>
<td>
<xsl:value-of select="@id"/>
</td>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="director"/>
</td>
<td>
<xsl:value-of select="year"/>
</td>
<td>
<xsl:value-of select="genre"/>
</td>
<td>
<xsl:value-of select="link"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>


The following is an image of my output with the if statement:
Not working if statement

And this image is the output without the if statement where all the information is displayed in a single table:
Single table with all data displayed

Thank you in advance for you help.

Answer

You need to move the condition on the year, which is checking for a year element relative the top level document node, to be part of the actual xsl:apply-templates select clause

i.e Instead of this....

 <xsl:if test="year &lt; 2005">
     <xsl:apply-templates select="AllMovies/movie">
        <xsl:sort select="title" order="ascending"/>
    </xsl:apply-templates>
 </xsl:if>

Do this....

<xsl:apply-templates select="AllMovies/movie[year &lt; 2005]">
   <xsl:sort select="title" order="ascending"/>
</xsl:apply-templates>

Note that for the other template, you will need to do &gt;= and not just &gt;

Comments