Search code examples
xmlxsltxslt-2.0xslt-grouping

Combine 2 different xml tags based on common attribute using XSLT


I have a xml with the following example

<Message>
 <Person>
  <Key>111</Key>
  <Name>John</Name>
  <Age>20</Age>
 </Person>
 <Person>
  <Key>112</Key>
  <Name>Alex</Name>
  <Age>20</Age>
 </Person>
 <Person>
  <Key>113</Key>
  <Name>Sean</Name>
  <Age>20</Age>
 </Person>
 <Car>
  <Key>111</Key>
  <Make>Toyota</Make>
  <Model>Camry</Model>
 </Car>
 <Car>
  <Key>111</Key>
  <Make>Toyota</Make>
  <Model>Corolla</Model>
 </Car>
 <Car>
  <Key>112</Key>
  <Make>Honda</Make>
  <Model>Civic</Model>
 </Car>
 <Car>
  <Key>113</Key>
  <Make>Lexus</Make>
  <Model>G300</Model>
 </Car>
</Message>

I would like to create a xml with the following using xslt:

<Message>
  <Person>
    <Key>111</Key>
    <Name>John</Name>
    <Age>20</Age>
  </Person>
  <Car>
    <Key>111</Key>
    <Make>Toyota</Make>
    <Model>Camry</Model>
  </Car>
  <Car>
    <Key>111</Key>
    <Make>Toyota</Make>
    <Model>Corolla</Model>
  </Car>
</Message>

I want to create a Message segment for each key and have the <person> and <car> segments in there for each key. How can I do this with xslt 2.0?


Solution

  • To use for-each-group as suggested in a comment use

      <xsl:template match="Message">
          <xsl:for-each-group select="*" group-by="Key">
              <Message>
                  <xsl:copy-of select="current-group()"/>
              </Message>
          </xsl:for-each-group>
      </xsl:template>
    

    full stylesheet is

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="xs"
        version="3.0">
    
      <xsl:output indent="yes"/>
    
      <xsl:template match="Message">
          <xsl:for-each-group select="*" group-by="Key">
              <Message>
                  <xsl:copy-of select="current-group()"/>
              </Message>
          </xsl:for-each-group>
      </xsl:template>
    
    </xsl:stylesheet>
    

    online at https://xsltfiddle.liberty-development.net/gWmuiJs.