Thomas Smith
Thomas Smith

Reputation: 1

Concat two XML files with XSLT

I have to XML source files:

1.xml

<person>
    <firstname>John</firstname>
    <lastname>Snow</lastname>
</person>

2.xml

<person>
    <firstname>Jonny</firstname>
    <lastname>Hill</lastname>
</person>

Target file

<employee_list>
    <employee>
        <first>John</firstname>
        <last>Snow</lastname>
    </employee>
    <employee>
        <first>Jonny</first>
        <last>Hill</last>
    </employee>
</employee_list>

I need to concat the two files as well as to change the element names. My XSLT file so far looks like this:

XSLT file

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <xsl:copy>
                <xsl:apply-templates select="person"/>

                <xsl:apply-templates select="document('2.xml')/person"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

However spacing in the output file is wrong and I'm failing to add the additional element and change the other ones.

Upvotes: 0

Views: 335

Answers (1)

Aniket V
Aniket V

Reputation: 3247

Please modify the <xsl:template match="/"> as below

<xsl:template match="/">
    <employee_list>
        <employee>
            <xsl:apply-templates select="person/*" />
        </employee>
        <employee>
            <xsl:apply-templates select="document('2.xml')/person/*" />
        </employee>
    </employee_list>
</xsl:template>

Add 2 more templates for modifying element names viz. <firstname> to <first> and <lastname> to <last>.

<!-- Rename <firstname> to <first> -->
<xsl:template match="firstname">
    <first>
        <xsl:apply-templates />
    </first>
</xsl:template>

<!-- Rename <lastname> to <last> -->
<xsl:template match="lastname">
    <last>
        <xsl:apply-templates />
    </last>
</xsl:template>

The complete XSLT and output is as below

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*" />

    <!-- Identity Transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <!-- Prepare output structure -->
    <xsl:template match="/">
        <employee_list>
            <employee>
                <xsl:apply-templates select="person/*" />
            </employee>
            <employee>
                <xsl:apply-templates select="document('2.xml')/person/*" />
            </employee>
        </employee_list>
    </xsl:template>

    <!-- Rename <firstname> to <first> -->
    <xsl:template match="firstname">
        <first>
            <xsl:apply-templates />
        </first>
    </xsl:template>

    <!-- Rename <lastname> to <last> -->
    <xsl:template match="lastname">
        <last>
            <xsl:apply-templates />
        </last>
    </xsl:template>
</xsl:stylesheet>

Output

<employee_list>
    <employee>
        <first>John</first>
        <last>Snow</last>
    </employee>
    <employee>
        <first>Jonny</first>
        <last>Hill</last>
    </employee>
</employee_list>

Upvotes: 1

Related Questions