Reputation: 906
I have two xml files, which need to be merged into one xml. Here is the example:
orginal.xml file :
<employees>
<employee id="1">
<name> Name1 </name>
<email> email1 <email>
</employee>
<employee id="2">
<name> Name2 </name>
<email> email2 <email>
</employee>
</employees>
update.xml file:
<employees>
<employee id="2">
<name> Name2 </name>
<email> email_New <email>
</employee>
<employee id="3">
<name> Name3 </name>
<email> email3 <email>
</employee>
</employees>
they should be merged to a xml file like this:
<employees>
<employee id="1">
<name> Name1 </name>
<email> email1 <email>
</employee>
<employee id="2">
<name> Name2 </name>
<email> email_New <email>
</employee>
<employee id="3">
<name> Name3 </name>
<email> email3 <email>
</employee>
</employees>
Actually, I'd like to use the update.xml to update the orginal.xml :
new employee in update.xml should be added to original.xml
modified employee information in update.xml should overwrite the corresponding employee node.
I know a little of XSLT, but my knowledge is not enough to figure out the right XSLT for the merge.
Upvotes: 1
Views: 11625
Reputation: 101682
Please give this a try:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="fileName" select="'update.xml'" />
<xsl:param name="updates" select="document($fileName)" />
<xsl:variable name="updateEmployees" select="$updates/employees/employee" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="employees">
<xsl:copy>
<xsl:apply-templates select="employee[not(@id = $updateEmployees/@id)]" />
<xsl:apply-templates select="$updateEmployees" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When run with your first XML as the input and with the update.xml present in the same folder, this produces:
<employees>
<employee id="1">
<name> Name1 </name>
<email>
email1 </email>
</employee>
<employee id="2">
<name> Name2 </name>
<email>
email_New
</email>
</employee>
<employee id="3">
<name> Name3 </name>
<email>
email3
</email>
</employee>
</employees>
fileName
and updates
are declared as parameters, so if the updates are in a file named something other than "update.xml" or you want to pass the update XML in directly, you can do that without making any modifications to the XSLT.
Upvotes: 3