I know there are multiple articles about merging and grouping with XSLT, however I couldn't really find an article specific for my case and to be honest, I think merging/grouping in XSLT is rather complex for an occasional developer like me. Especially when there are multiple "arrays" in the nested xml. An article that is comparable to mine is f.e.: XML merge nodes with XSLT ... but in that article this is a grouping inside one "scenario" instead of grouping over different "scenario's".
My case goes as follows:
I want to merge two "message"-elements (it will always be two) in one XML file (root = "messages"). Inside that merged "message" there should also be a merge of "object"-elements based on the ID of that object and only keep the merged "object"-elements.
Example:
Initial XML:
<?xml version="1.0" encoding="UTF-8"?>
<messages>
<message>
<submessage>
<object>
<ID>991</ID>
<Extra>ABC</Extra>
</object>
<object>
<ID>992</ID>
<Extra>BCD</Extra>
</object>
<object>
<ID>993</ID>
<Extra>CDE</Extra>
</object>
</submessage>
</message>
<message>
<submessage>
<object>
<ID>992</ID>
<Name>Marcel</Name>
<Description>XXX</Description>
</object>
<object>
<ID>993</ID>
<Name>Peter</Name>
<Description>YYY</Description>
</object>
<object>
<ID>994</ID>
<Name>Lola</Name>
<Description>ZZZ</Description>
</object>
</submessage>
</message>
</messages>
Result XML:
<?xml version="1.0" encoding="UTF-8"?>
<messages>
<message>
<submessage>
<object>
<ID>992</ID>
<Name>Marcel</Name>
<Description>XXX</Description>
<Extra>BCD</Extra>
</object>
<object>
<ID>993</ID>
<Name>Peter</Name>
<Description>YYY</Description>
<Extra>CDE</Extra>
</object>
</submessage>
</message>
</messages>
As you can see, the result XML should only contain the objects where the ID of the object of the message matches the ID of the object of the other message. For this example that means objects with ID 991 in the first message and 994 in the other message get deleted, but 992 and 993 can stay and are merged with all elements within the object. FYI: the "submessage"-element only occurs once per "message"-element.
Can someone please enlighten me how to do this with XSLT 1.0?
Thank you in advance.
If I understand the desired logic correctly, you want to do something like:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="obj" match="/messages/message[2]/submessage/object" use="ID" />
<xsl:template match="/messages">
<messages>
<message>
<submessage>
<xsl:for-each select="message[1]/submessage/object[key('obj', ID)]">
<object>
<xsl:copy-of select="*"/>
<xsl:copy-of select="key('obj', ID)/*[not(self::ID)]"/>
</object>
</xsl:for-each>
</submessage>
</message>
</messages>
</xsl:template>
</xsl:stylesheet>