Reputation: 3
I got this xml (the 'other' elements have different names, just skipped them for clarity):
<root>
<elements1>
<element>
<id>1</id>
<other>a</other>
<other>b</other>
<other>c</other>
</element>
<element><id>2</id>
<other>a</other>
<other>b</other>
<other>c</other>
</element>
<element><id>3</id>
<other>a</other>
<other>b</other>
<other>c</other>
</element>
</elements1>
<elements2>
<element>
<id2>1</id2>
<other2>a</other2>
<other2>b</other2>
<other2>c</other2>
</element>
<element>
<id2>2</id2>
<other2>a</other2>
<other2>b</other2>
<other2>c</other2>
</element>
<elements2>
</root>
I need to filter it so it shows something like this:
<root>
<elements>
<element>
<id>1</id>
<id2>1</id2>
<other>a</other>
<other>b</other>
<other>c</other>
<other2>a</other2>
<other2>b</other2>
<other2>c</other2>
</element>
<element>
<id>2</id>
<id2>2</id2>
<other>a</other>
<other>b</other>
<other>c</other>
<other2>a</other2>
<other2>b</other2>
<other2>c</other2>
</element>
</elements>
</root>
So it should take the children of two different elements and put them together as one element filtering by the id and id2.
Not sure how to do it. I've tried two for-each elements to filter the xml but it wouldnt work.
Upvotes: 0
Views: 963
Reputation: 167571
Here is an XSLT 2.0 stylesheet using a key:
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:key name="id2" match="elements2/element" use="id2"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<elements>
<xsl:apply-templates select="elements1/element[key('id2', id)]"/>
</elements>
</xsl:copy>
</xsl:template>
<xsl:template match="elements1/element">
<xsl:variable name="el2" select="key('id2', id)"/>
<xsl:copy>
<xsl:copy-of select="id, $el2/id2, (., $el2)/(* except (id, id2))"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
A similar approach with XSLT 1.0 is
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:key name="id2" match="elements2/element" use="id2"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<elements>
<xsl:apply-templates select="elements1/element[key('id2', id)]"/>
</elements>
</xsl:copy>
</xsl:template>
<xsl:template match="elements1/element">
<xsl:variable name="el2" select="key('id2', id)"/>
<xsl:copy>
<xsl:copy-of select="id | $el2/id2 | *[not(self::id)] | $el2/*[not(self::id2)]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1