Reputation: 763
I'm having trouble finding a suitable example to merge 2 XML files into 1, as per below:
movies.xml
<movies>
<movie>
<name>ET</name>
<director>Steven Spielberg</director>
<date>15 January 2000</date>
</movie>
<movie>
<name>The Neverending Story</name>
<director>Steven Spielberg</director>
<date>4 November 2006</date>
</movie>
</movies>
directos.xml
<directors>
<director>
<name>Steven Spielberg</name>
<age>55</age>
<sex>male</sex>
</director>
</directors>
required output:
<directors>
<director>
<name>Steven Spielberg</name>
<age>55</age>
<sex>male</sex>
<movies>
<movie>
<name>ET</name>
<date>15 January 2000</date>
</movie>
<movie>
<name>The Neverending Story</name>
<date>4 November 2006</date>
<movie>
</movies>
</director>
</directors>
XSL:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "xml" indent = "yes" />
<xsl:variable name="movieFile" select="document('movies.xml')" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="$movieFile/movies/movie/director">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
At the moment, it is printing the whole director list within each movie group.
Can somebody please give me some guidance?
Upvotes: 3
Views: 1159
Reputation: 116959
If you can indeed use XSLT 2.0, then this could be quite simple:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:variable name="movieFile" select="document('movies.xml')" />
<xsl:key name="movie-by-director" match="movie" use="director" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="director">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<movies>
<xsl:apply-templates select="key('movie-by-director', name, $movieFile)" />
</movies>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Reputation: 23637
If you replace your second template with this one, and feed the 'directors.xml' file as input it should work:
<xsl:template match="director">
<xsl:variable name="director-name" select="name"/>
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
<xsl:apply-templates select="document('movies.xml')/movies/movie[director=$director-name]" />
</xsl:copy>
</xsl:template>
You copy each node using the identity template except the director
node above, in which you add the matching contents of the movie
file.
Upvotes: 2