I was wondering if it is possible using XSL to merge elements in a document. Specifically for the below example.
I want to merge elements so that the ones are effectively aggregated including any additional descendents (grandchildren) as well.
Note that the key for the Child implicitly includes the parent so 123/ABC is different to 456/ABC.
A nice to know would also be around how to determine the the nodes that "Wins" for ones where an overwrite occurs (such as parent/name).
From this
<?xml version="1.0" encoding="UTF-8"?>
<listOfParent>
<parent>
<parentId>123</parentId>
<name>Jim</name>
<value>some data</value>
<listOfChild>
<child>
<childReference>ABC</childReference>
<name>Karen</name>
</child>
</listOfChild>
</parent>
<parent>
<parentId>123</parentId>
<name>Fred</name>
<listOfChild>
<child>
<childReference>ABC</childReference>
<name>Gemma</name>
</child>
<child>
<childReference>DEF</childReference>
<name>Karen</name>
</child>
</listOfChild>
</parent>
<parent>
<parentId>456</parentId>
<name>Bill</name>
<listOfChild>
<child>
<childReference>ABC</childReference>
<name>Penny</name>
</child>
<child>
<childReference>DEF</childReference>
<name>Rose</name>
</child>
</listOfChild>
</parent>
to this
<?xml version="1.0" encoding="UTF-8"?>
<listOfParent>
<parent>
<parentId>123</parentId>
<name>not bothered</name>
<value>some data</value>
<listOfChild>
<child>
<childReference>ABC</childReference>
<name>not bothered</name>
</child>
<child>
<childReference>DEF</childReference>
<name>Karen</name>
</child>
</listOfChild>
</parent>
<parent>
<parentId>456</parentId>
<name>Bill</name>
<listOfChild>
<child>
<childReference>ABC</childReference>
<name>Penny</name>
</child>
<child>
<childReference>DEF</childReference>
<name>Rose</name>
</child>
</listOfChild>
</parent>
Here is the XSL I tried
<?altova_samplexml Untitled1.xml?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kGDByIdKey" match="parent" use="parentId"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="parent
[generate-id()
=
generate-id(key('kGDByIdKey', parentId)[1])
]">
<xsl:copy>
<xsl:apply-templates select="@*|key('kGDByIdKey', parentId)/node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="parent"/>