How to merge 2 xml docs with xslt?

How do I merge two XML docs with XSLT (can be XSLT 2.0)?

  • I have two files with related information that is gathered separately. When each processor is done gathering the xml data in the same format, how can I merge the two xml files using XSLT? For example: AllSets_Names.xml <Sets> <Set id="1"> <SetName>World Champ Decks 1999</SetName> </Set> <Set id="2"> <SetName>World Champ Decks 1999</SetName> </Set> <Set id="3"> <SetName>World Champ Decks 1999</SetName> </Set> <Set id="4"> <SetName>World Champ Decks 1999</SetName> </Set> <Set id="5"> <SetName>World Champ Decks 1999</SetName> </Set> </Sets> AllSets_ShortNames.xml <Sets> <Set id="1"> <SetShortName>W99</SetShortName> </Set> <Set id="2"> <SetShortName>W00</SetShortName> </Set> <Set id="3"> <SetShortName/> </Set> <Set id="4"> <SetShortName>WD2</SetShortName> </Set> <Set id="5"> <SetShortName>WD3</SetShortName> </Set> </Sets> Desired Output: AllSets_NamesAndShortNames.xml <Sets> <Set id="1"> <SetName>World Champ Decks 1999</SetName> <SetShortName>W99</SetShortName> </Set> <Set id="2"> <SetName>World Champ Decks 1999</SetName> <SetShortName>W00</SetShortName> </Set> <Set id="3"> <SetName>World Champ Decks 1999</SetName> <SetShortName/> </Set> <Set id="4"> <SetName>World Champ Decks 1999</SetName> <SetShortName>WD2</SetShortName> </Set> <Set id="5"> <SetName>World Champ Decks 1999</SetName> <SetShortName>WD3</SetShortName> </Set> </Sets>

  • Answer:

    You could do it this way: 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:strip-space elements="*"/> <xsl:param name="short-names-path" select="'AllSets_ShortNames.xml'"/> <xsl:key name="set-by-id" match="Set" use="@id" /> <!-- identity transform --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="Set"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> <xsl:copy-of select="key('set-by-id', @id, document($short-names-path))/SetShortName"/> </xsl:copy> </xsl:template> </xsl:stylesheet> This assumes you are processing the AllSets_Names.xml document and passing the path to AllSets_ShortNames.xml as a parameter.

Brian T Hannan at Stack Overflow Visit the source

Was this solution helpful to you?

Other answers

A good way to do this is using grouping: <xsl:template name="main"> <Sets> <xsl:for-each-group select="document(('Names.xml','ShortNames.xml'))/Sets/Set" group-by="@id"> <Set> <xsl:copy-of select="current-group()/(@*, *)"/> </Set> </xsl:for-each-group> </Sets> </xsl:template>

Michael Kay

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.