我正在使用XSLT循环遍历XML文档。
文档的根节点称为电影,它可以包含一个或多个电影元素。但是,这些电影元素包含除 actor 元素之外的单个元素。如何循环显示多个演员?我已经使用<xsl:for-each>
循环播放每部电影
这是xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="/movies">
<html>
<head>
<link rel="stylesheet" href="stylecss.css" />
<title>My Movies Collection</title>
</head>
<body>
<!-- Use for each loop to extract all child nodes and their information-->
<xsl:for-each select="/movies/movie">
<!--Add title as well as year-->
<h1><xsl:value-of select="title" />
<xsl:text> ( </xsl:text>
<xsl:value-of select="@year" />
<xsl:text> ) </xsl:text>
</h1>
<p>
<img>
<xsl:attribute name="src">
<xsl:value-of select="poster" />
</xsl:attribute>
</img>
<span id="details">
<xsl:text>Review: </xsl:text>
<xsl:value-of select="@review" />
<xsl:text>, Type: </xsl:text>
<xsl:value-of select="@type" />
<br></br>
<xsl:text>Producer: </xsl:text>
<xsl:value-of select="producer" />
<br/>
<xsl:text>Actor: </xsl:text>
<xsl:value-of select="actor"/> <br/>
<xsl:text>Director: </xsl:text>
<xsl:value-of select="director" /><br/>
<br/>
<i> <xsl:text>Comments: </xsl:text>
<xsl:value-of select="comments" /> </i>
</span>
</p>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
xml文档本身:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="stylesheet.xslt" ?>
<movies>
<movie type="comedy" rating="PG" review="4" year="1997">
<title>How To Be A Player</title>
<writer>Mark Brown</writer>
<producer>Todd R. Baker</producer>
<director>Russell Simmons</director>
<actor>Bill Bellamy</actor>
<actor>Mari Morrow</actor>
<poster>img/htbap.jpeg</poster>
<comments>Promotes polygamy</comments>
</movie>
<movie type="comedy" rating="PG" review="5" year="2010">
<title>Grown Ups</title>
<writer>Adam Sandler</writer>
<producer>Jack Giarraputo</producer>
<director>Fred Wolf</director>
<actor>Chris Rock</actor>
<actor>Rob Schneider</actor>
<poster>img/gu.jpeg</poster>
<comments>Funny stuff</comments>
</movie>
<movie type="drama" rating="PG" review="5" year="2010">
<title>The Social Network</title>
<writer>Dana Brunetti</writer>
<producer>Scott Rudin</producer>
<director>David Fincher</director>
<actor>Jesse Eisenberg</actor>
<actor>Justin Timberlake</actor>
<poster>img/sn.jpeg</poster>
<comments>So innovative</comments>
</movie>
<movie type="comedy" rating="PG" review="5" year="2012">
<title>Project X</title>
<writer>Nima Nourizadeh</writer>
<producer>Todd Phillips</producer>
<director>Nima Nourizadeh</director>
<actor>Thomas Mann</actor>
<actor>Oliver Cooper</actor>
<poster>img/px.jpeg</poster>
<comments>Best party to ever</comments>
</movie>
</movies>
答案 0 :(得分:3)
@Tim C:非常好的答案,+1为此!但是 actor 节点的额外template
也可以完成这项工作,对吗?
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/movies">
<html>
<head>
<link rel="stylesheet" href="stylecss.css"/>
<title>My Movies Collection</title>
</head>
<body>
<!-- Use for each loop to extract all child nodes and their information-->
<xsl:for-each select="/movies/movie">
<!--Add title as well as year-->
<h1>
<xsl:value-of select="title"/>
<xsl:text> ( </xsl:text>
<xsl:value-of select="@year"/>
<xsl:text> ) </xsl:text>
</h1>
<p>
<img>
<xsl:attribute name="src">
<xsl:value-of select="poster"/>
</xsl:attribute>
</img>
<span id="details">
<xsl:text>Review: </xsl:text>
<xsl:value-of select="@review"/>
<xsl:text>, Type: </xsl:text>
<xsl:value-of select="@type"/>
<br></br>
<xsl:text>Producer: </xsl:text>
<xsl:value-of select="producer"/>
<br/>
<xsl:text>Actor: </xsl:text>
<!-- <xsl:value-of select="actor"/> -->
<!-- apply the 'actor' node -->
<xsl:apply-templates select="actor"/>
<br/>
<xsl:text>Director: </xsl:text>
<xsl:value-of select="director"/>
<br/>
<br/>
<i>
<xsl:text>Comments: </xsl:text>
<xsl:value-of select="comments"/>
</i>
</span>
</p>
</xsl:for-each>
</body>
</html>
</xsl:template>
<!-- the additional actor template -->
<xsl:template match="actor">
<!-- get the value -->
<xsl:value-of select="."/>
<!-- set a comma and a whitespace if it is not the last 'actor' node -->
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:2)
没有理由可以将xsl:for-each
嵌套在另一个中。所以你可以用这个
<xsl:value-of select="actor"/>
,它只输出第一个演员的文本
<xsl:for-each select="actor">
<xsl:value-of select="." /><br />
</xsl:for-each>
请注意select
中的xpath表达式是相对表达式;它与您当前所在的movie
节点相关,因此将选择作为其子元素的所有actor
元素。 (这也意味着您当前的<xsl:for-each select="/movies/movie">
实际上只能是<xsl:for-each select="movie">
)
话虽如此,在XSLT中,通常最好使用基于模板的解决方案,而不是使用xsl:for-each
,因为您可能会重复使用模板,例如,如果您有多个编写者或导演太
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="/movies">
<html>
<head>
<link rel="stylesheet" href="stylecss.css" />
<title>My Movies Collection</title>
</head>
<body>
<xsl:apply-templates select="movie" />
</body>
</html>
</xsl:template>
<xsl:template match="movie">
<h1>
<xsl:value-of select="title" />
<xsl:text> ( </xsl:text><xsl:value-of select="@year" /><xsl:text> ) </xsl:text>
</h1>
<p>
<img src="{poster}"/>
<span id="details">
<xsl:text>Review: </xsl:text>
<xsl:value-of select="@review" />
<xsl:text>, Type: </xsl:text>
<xsl:value-of select="@type" />
<br></br>
<xsl:text>Producer: </xsl:text>
<xsl:apply-templates select="producer" />
<br/>
<xsl:text>Actor: </xsl:text>
<xsl:apply-templates select="actor" />
<br/>
<xsl:text>Director: </xsl:text>
<xsl:apply-templates select="director" />
<br/>
<i>
<xsl:text>Comments: </xsl:text>
<xsl:value-of select="comments" />
</i>
</span>
</p>
</xsl:template>
<xsl:template match="movie/*">
<xsl:value-of select="."/> <br/>
</xsl:template>
</xsl:stylesheet>
还要注意在创建img
元素
<img src="{poster}"/>
花括号表示要计算的表达式,而不是字面输出。