(XSLT 2.0) I am attempting to take a record, and split it into multiple records based off the grouped values of specific child elements - but I need to retain all other elements such that:
Sample XML
<?xml version="1.0" encoding="UTF-8"?>
<Report>
<Record>
<Name>Testing</Name>
<Due_Date>2021-10-08</Due_Date>
<Customer>
<Name>Test Customer</Name>
<State>GA</State>
</Customer>
<To_Transaction>
<Contact name="John Smith">
<ID>12345</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>100.00</Amount>
</To_Transaction>
<To_Transaction>
<Contact name="John Smith">
<ID>12345</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>150.00</Amount>
</To_Transaction>
<To_Transaction>
<Contact name="Jane Doe">
<ID>54321</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>100.00</Amount>
</To_Transaction>
<From_Transaction>
<Contact name="John Smith">
<ID>12345</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>8.00</Amount>
</From_Transaction>
<From_Transaction>
<Contact name="Jane Doe">
<ID>54321</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>75.00</Amount>
</From_Transaction>
<From_Transaction>
<Contact name="Jane Doe">
<ID>54321</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>50.00</Amount>
</From_Transaction>
</Record>
</Report>
Becomes... Expected Result
<Report>
<Record>
<Name>Testing</Name>
<Due_Date>2021-10-08</Due_Date>
<Customer>
<Name>Test Customer</Name>
<State>GA</State>
</Customer>
<To_Transaction>
<Contact name="John Smith">
<ID>12345</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>100.00</Amount>
</To_Transaction>
<To_Transaction>
<Contact name="John Smith">
<ID>12345</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>150.00</Amount>
</To_Transaction>
<From_Transaction>
<Contact name="John Smith">
<ID>12345</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>8.00</Amount>
</From_Transaction>
</Record>
<Record>
<Name>Testing</Name>
<Due_Date>2021-10-08</Due_Date>
<Customer>
<Name>Test Customer</Name>
<State>GA</State>
</Customer>
<To_Transaction>
<Contact name="Jane Doe">
<ID>54321</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>100.00</Amount>
</To_Transaction>
<From_Transaction>
<Contact name="Jane Doe">
<ID>54321</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>75.00</Amount>
</From_Transaction>
<From_Transaction>
<Contact name="Jane Doe">
<ID>54321</ID>
</Contact>
<Contact_Email>[email protected]</Contact_Email>
<Amount>50.00</Amount>
</From_Transaction>
</Record>
</Report>
Ideally, I would be grouping the transaction elements by the Contact @name attribute. The closest I've gotten so far is below. I've tried identity templates but can't figure out how to make it work with the grouping:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<Report>
<xsl:for-each-group select="Record" group-by="(To_Transaction,'*')">
<Record>
<xsl:copy-of select="."/>
</Record>
</xsl:for-each-group>
</Report>
</xsl:template>
</xsl:stylesheet>
AFAICT, you want to do:
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:template match="/Report">
<xsl:copy>
<xsl:for-each-group select="Record/(To_Transaction | From_Transaction)" group-by="Contact/ID">
<Record>
<xsl:copy-of select="../(Name | Due_Date | Customer)"/>
<xsl:copy-of select="current-group()"/>
</Record>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Or, if you prefer:
<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:template match="/Report">
<xsl:copy>
<xsl:for-each-group select="Record/(To_Transaction | From_Transaction)" group-by="Contact/ID">
<Record>
<xsl:copy-of select="../(* except(To_Transaction | From_Transaction))"/>
<xsl:copy-of select="current-group()"/>
</Record>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>