#html #xml #xslt #xpath
#HTML #xml #xslt #xpath
Вопрос:
Я создал XML-файл, содержащий мои 15 любимых фильмов, которые имеют несколько атрибутов. XML-файл можно увидеть ниже:
<?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>
На основе приведенного выше XML-файла я смог создать шаблон, который отображает все данные в форматированной таблице. Что я хотел бы сделать, так это создать две таблицы на основе <year>
атрибута в каждом узле movie. Так, например, я хотел бы, чтобы каждый фильм, выпущенный до 2005 года, был в первой таблице, затем оставьте пробел и добавьте еще одну таблицу, содержащую все фильмы 2005 года и новее. Я пытался использовать оператор if в корневом шаблоне и шаблоне «movie» и не могу заставить его работать.
Ниже приведен мой код xslt, пытающийся решить проблему:
<?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>
<!-- amp;< is the hex for < and amp;> 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 amp;< 2005">
<xsl:apply-templates select="AllMovies/movie">
<xsl:sort select="title" order="ascending"/>
</xsl:apply-templates>
</xsl:if>
<tr></tr>
<xsl:if test="year amp;> 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>
Ниже приведено изображение моего вывода с помощью инструкции if:
И это изображение является результатом без инструкции if, где вся информация отображается в одной таблице:
Заранее благодарю вас за помощь.
Ответ №1:
Вам нужно переместить условие в year
, которое проверяет наличие year
элемента, относящегося к узлу документа верхнего уровня, чтобы оно было частью фактического xsl:apply-templates
предложения select
т.е. вместо этого….
<xsl:if test="year amp;< 2005">
<xsl:apply-templates select="AllMovies/movie">
<xsl:sort select="title" order="ascending"/>
</xsl:apply-templates>
</xsl:if>
Сделайте это….
<xsl:apply-templates select="AllMovies/movie[year amp;< 2005]">
<xsl:sort select="title" order="ascending"/>
</xsl:apply-templates>
Обратите внимание, что для другого шаблона вам нужно будет выполнить amp;>=
, а не просто amp;>
Комментарии:
1. Что действительно интересно, так это то, как я так близко подобрался к решению с помощью различных методов, которые я пробовал, но так и не получил его. Спасибо, Тим, ты здорово помог.
Ответ №2:
Если вы хотите иметь две отдельные таблицы, тогда ваш основной шаблон должен быть структурирован в соответствии с этими строками:
<xsl:template match="/AllMovies">
<html>
<head>
<title>Assignment 1</title>
<style>
/*removed for brevity*/
</style>
</head>
<body>
<xsl:variable name="header">
<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:variable>
<h1>Before 2005</h1>
<table>
<xsl:copy-of select="$header"/>
<xsl:apply-templates select="movie[year amp;< 2005] ">
<xsl:sort select="title" order="ascending"/>
</xsl:apply-templates>
</table>
<h1>2005 and later</h1>
<table>
<xsl:copy-of select="$header"/>
<xsl:apply-templates select="movie[year >= 2005] ">
<xsl:sort select="title" order="ascending"/>
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
Комментарии:
1. Спасибо, Майкл, ваше решение сработало, но мне пришлось изменить «movie [год выпуска amp; < 2005] » на полное расположение «AllMovies / movie [год выпуска …..».
2. Вы, вероятно, пропустили, что у меня есть
<xsl:template match="/AllMovies">
.