Search code examples
xmlxsltxslt-grouping

Merge similar data xml nodes using an attribute as key ( xsl )


I want to convert a file with N sections with this format:

<File>
        <Sections Section="Section1" fieldName="field1" fieldValue="value1"/>
        <Sections Section="Section1" fieldName="field2" fieldValue="value2"/>
        <Sections Section="Section1" fieldName="field3" fieldValue="value3"/>
        <Sections Section="Section2" fieldName="field1" fieldValue="value1"/>
        <Sections Section="Section2" fieldName="field2" fieldValue="value2"/>
        <Sections Section="Section2" fieldName="field3" fieldValue="value3"/>
</File>

Into

<File>
   <Section1 field1="value1" field2="value2" field3="value3"/>
   <Section2 field1="value1" field2="value2" field3="value3"/>
</File>

Using attribute Section's value as key to create elements.

I tried somethings, but i couldn't.

Could you help me?

Thanks.


Solution

  • Here is an XSLT 1.0 stylesheet:

    <xsl:stylesheet 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0">
    
      <xsl:output indent="yes"/>
    
      <xsl:key name="k1" match="File/Sections" use="@Section"/>
    
      <xsl:template match="File">
        <xsl:copy>
          <xsl:apply-templates select="Sections[generate-id() = generate-id(key('k1', @Section)[1])]" mode="group"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="Sections" mode="group">
        <xsl:element name="{@Section}">
          <xsl:apply-templates select="key('k1', @Section)"/>
        </xsl:element>
      </xsl:template>
    
      <xsl:template match="Sections">
        <xsl:attribute name="{@fieldName}">
          <xsl:value-of select="@fieldValue"/>
        </xsl:attribute>
      </xsl:template>
    
    </xsl:stylesheet>