Home > database >  How to merge XML nodes with common subnodes while concatenating text of one differing subnode in XSL
How to merge XML nodes with common subnodes while concatenating text of one differing subnode in XSL

Time:01-11

How to merge XML nodes with common subnodes while concatenating the text of one differing subnode in XSLT? I can use XSLT 1 or 2. I have basic XSLT knowledge but do not know where to start with this one.

This is the given XML:

<fields>
    <field>
        <dc-schema>dc</dc-schema>
        <dc-element>description</dc-element>
        <dc-qualifier>abstract</dc-qualifier>
        <type-bind>Audio</type-bind>
    </field>
    
    <field>
        <dc-schema>dc</dc-schema>
        <dc-element>description</dc-element>
        <dc-qualifier>abstract</dc-qualifier>
        <type-bind>Video</type-bind>
    </field>
    
    <field>
        <dc-schema>dc</dc-schema>
        <dc-element>description</dc-element>
        <dc-qualifier>sponsorship</dc-qualifier>
        <type-bind>Audio</type-bind>
    </field>
</fields>

This is the desired result:

<fields>
    <field>
        <dc-schema>dc</dc-schema>
        <dc-element>description</dc-element>
        <dc-qualifier>abstract</dc-qualifier>
        <type-bind>Audio, Video</type-bind>
    </field>
    
    <field>
        <dc-schema>dc</dc-schema>
        <dc-element>description</dc-element>
        <dc-qualifier>sponsorship</dc-qualifier>
        <type-bind>Audio</type-bind>
    </field>
</fields>

CodePudding user response:

You could do a grouping like this :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <xsl:for-each-group select="fields/field" group-by="concat(dc-schema,dc-element,dc-qualifier)">
      <xsl:copy>
        <xsl:copy-of select="*[not(self::type-bind)]"/>
        <type-bind><xsl:value-of select="current-group()/type-bind" separator=", "/></type-bind>
      </xsl:copy>
    </xsl:for-each-group>
  </xsl:template>
  
</xsl:stylesheet>

See it working here : https://xsltfiddle.liberty-development.net/93F8dUv

  •  Tags:  
  • Related