3

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?

6
  • 1
    w3.org/TR/xslt#document Commented Feb 24, 2015 at 10:31
  • Show us the XSLT code you've tried so far and we'll be happy to help you debug it, but SO won't write the whole thing for you. Commented Feb 24, 2015 at 10:31
  • I've added some code @IanRoberts. I wasn't expecting anybody to write the whole thing. Was hoping for a nudge in the right direction :) Commented Feb 24, 2015 at 11:08
  • 1
    Before asking new questions, accept or otherwise respond to the answer to your previous question. Commented Feb 24, 2015 at 11:14
  • 1
    This is a lookup problem, and the correct solution is to use a key. The exact implementation depends on whether you're using XSLT 1.0 or 2.0. Please make it a habit to indicate your version when asking an XSLT question. Commented Feb 24, 2015 at 11:38

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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>

2 Comments

I added another director and movie. It doesn't compile @michael.hor257k
@CocaCola I don't know what you mean by "doesn't compile". Why don't you provide your actual (new) example and the exact result your get?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.