Reputation: 876
I have the following XML file that stores movies and actors:
<database
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="movies.xsd">
<movies>
<movie movieID="1">
<title>Movie 1</title>
<actors>
<actor actorID="1"></actor>
<actor actorID="2"></actor>
</actors>
</movie>
</movies>
<actors>
<actor actorID="1">
<name>Bob</name>
</actor>
<actor actorID="2">
<name>Mike</name>
</actor>
</actors>
</database>
I want to connect actorID from database/movies/movie/actors/actor
with the actorID from database/actors/actor
and display actors' names:
This is my XSLT:
<xsl:variable name="selectActors" select="database/actors/actor[@actorID]"/>
<xsl:variable name="inputRoot" select="/"/>
<xsl:template match="/">
<xsl:apply-templates select="database/movies/movie"/>
</xsl:template>
<xsl:template match="movie">
Title:
<xsl:value-of select="title"/>
<br/>
Actors:
<xsl:for-each select="actors/actor[@actorID=$selectActors]">
<xsl:value-of select="$inputRoot/database/actors/actor/name"/>
<br/>
</xsl:for-each>
<br/>
</xsl:template>
This is the end result that I want to display:
Title: Movie 1
Actors: Bob
Mike
I cannot get actor names to display on my page. I am not sure if I have interlinked my actorID's correctly as I'm very new to XSLT in general.
Upvotes: 0
Views: 128
Reputation: 101730
There is a problem with the XPath in your for-each
and the one in your value-of
but a more efficient (and more elegant) approach than what you're attempting is to use keys:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kActor" match="database/actors/actor" use="@actorID"/>
<xsl:template match="/">
<div>
<xsl:apply-templates select="database/movies/movie"/>
</div>
</xsl:template>
<xsl:template match="movie">
<xsl:value-of select="concat('Title: ', title)"/>
<br />
<xsl:text>Actors: </xsl:text>
<xsl:apply-templates select="key('kActor', actors/actor/@actorID)" />
<br />
</xsl:template>
<xsl:template match="actor">
<xsl:value-of select="name"/>
<br />
</xsl:template>
</xsl:stylesheet>
When run on your sample input, the result is:
<div>
Title: Movie 1<br />Actors: Bob<br />Mike<br /><br />
</div>
And just so you can see what was incorrect with your XPath, here is how you could have fixed your existing solution to work correctly:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:variable name="selectActors" select="database/actors/actor"/>
<xsl:template match="/">
<div>
<xsl:apply-templates select="database/movies/movie"/>
</div>
</xsl:template>
<xsl:template match="movie">
Title:
<xsl:value-of select="title"/>
<br/>
Actors:
<xsl:for-each
select="$selectActors[@actorID = current()/actors/actor/@actorID]">
<xsl:value-of select="name"/>
<br/>
</xsl:for-each>
<br/>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1