I have multiple xml elements which actually refer to the same "object", they may have the same data, or they may have different data. Any may have elements which the others do not. I want my xsl to output the sum of the elements of all of these xml "objects". We won't worry about overlap. How can you merge like this using XSL?
Example:
<root>
<object>
<property1>value</property1>
</object>
<object>
<property1>value</property1>
<property2>value</property2>
</object>
...
<object>
<propertyN>value</propertyN>
</object>
</root>
Outcome:
<root>
<object>
<property1>value</property1>
<property2>value</property2>
...
<propertyN>value</propertyN>
</object>
</root>
This transform applied to your sample .xml
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ext="www.foo.com">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<object>
<xsl:for-each select="/root/object//*">
<xsl:copy-of select="."/>
</xsl:for-each>
</object>
</root>
</xsl:template>
</xsl:stylesheet>
Produces this output :
<?xml version="1.0" encoding="UTF-8"?>
<root>
<object>
<property1>value</property1>
<property1>value</property1>
<property2>value</property2>
<propertyN>value</propertyN>
</object>
</root>
Although you will probably want to do something better later, this should get you going.
This could be achieved by Meunchian grouping.
First define a key to match the property elements (in this case I am assuming all child nodes of the object are properties), using the name as the look-up.
Next, you need to match the first occurrence of each property name, by checking it is the first such property in the look-up key
<xsl:apply-templates
select="//object/*[generate-id() = generate-id(key('property', local-name())[1])]" />
You can then simply copy such matches.
Here is the full XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="property" match="object/*" use="local-name()"/>
<xsl:template match="/">
<object>
<xsl:apply-templates select="//object/*[generate-id() = generate-id(key('property', local-name())[1])]"/>
</object>
</xsl:template>
<xsl:template match="*">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
When applied to your sample XML, the output is as follows:
<object>
<property1>value</property1>
<property2>value</property2>
<propertyN>value</propertyN>
</object>
In this case, only the first occurrence of the property name is returned. If you wanted to combine elements, you could for example (assuming the values were all numeric), sum them
<xsl:template match="*">
<xsl:copy>
<xsl:value-of select="sum(key('property', local-name()))" />
</xsl:copy>
</xsl:template>
So, given this input XML....
<root>
<object>
<property1>1</property1>
</object>
<object>
<property1>2</property1>
<property2>3</property2>
</object>
...
<object>
<propertyN>4</propertyN>
</object>
</root>
The output would be...
<object>
<property1>3</property1>
<property2>3</property2>
<propertyN>4</propertyN>
</object>