2

So I have an xml file like this:

<?xml version="1.0"?>
<class>

    <students>
        <name origin="English" firstname="Jeff" lastname="Richards"/>
        <name origin="French" firstname="Martel" lastname="Francois"/>
    </students>

    <teachers>
        <name origin="Spanish" firstname="Enrique" lastname="Rosa"/>
    </teachers>

</class>

And have another xml file like this:

 <?xml version="1.0"?>
    <name origin="English" firstname="Richard" lastname="Priestly"/>
    <name origin="Russian" firstname="Alexey" lastname="Romanov"/>

Using xslt, how can I add the two elements in the second file into the student element in the first file? In other words, how can I create a file that looks like this:

<?xml version="1.0"?>
    <class>

        <students>
            <name origin="English" firstname="Jeff" lastname="Richards"/>
            <name origin="French" firstname="Martel" lastname="Francois"/>
            <name origin="English" firstname="Richard" lastname="Priestly"/>
            <name origin="Russian" firstname="Alexey" lastname="Romanov"/>
        </students>

        <teachers>
            <name origin="Spanish" firstname="Enrique" lastname="Rosa"/>
        </teachers>

    </class>

If it is not possible using xslt, is it doable using XPath?

Thanks a bunch!

2
  • Check this stackoverflow.com/questions/15194718/… and your XML examples are not valid. The second don't have a root node, and the last one you miss the <class> tag Commented Oct 15, 2013 at 23:27
  • Your second document is not an XML file. Once you fix that, you could use the document() function to parse and process the second file and include it's content as part of the transformation of the first XML file. Commented Oct 15, 2013 at 23:29

1 Answer 1

6

Here is one way, assuming you make the second file well-formed by adding a 'students' root node and name it 'students.xml':

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output indent="yes" method="xml"/>

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

<xsl:template match="students">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <xsl:for-each select="document('students.xml')/students/name">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

5 Comments

I tried this and am getting the following error--Error:The processing instruction target matching "[xX][mM][lL]" is not allowed.'
Never mind. It was because one of my files had a space before the xml header began. Thank you!!
Is there any way to copy it so that it indents properly. Using the above, the name elements are shifted all the way to the left. I would like them to be indented.
You are missing the xsl:stylesheet end tag.
@4thex sorry about that. The closing tag was there but it was hidden by code formatting. Fixed now.

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.