Home > Mobile >  removing duplicate nodes XML using xslt - multiple records (xslt 2 or 3)
removing duplicate nodes XML using xslt - multiple records (xslt 2 or 3)

Time:04-26

I have an XML with hundreds of records in this format (only 2 shown here)

<assessment> 
<subject>
    <Name>470  470 015</Name>
    <LAD>3.446887644423149</LAD>
    <LAD>3.446887644423149</LAD>
    <LM>4.049357373198344</LM>
    <LM>4.049357373198344</LM>
    <RCA>3.283339910532276</RCA>
    <RCA>3.283339910532276</RCA>
</subject>
<subject>
    <Name>230 230067</Name>
    <LAD>2.392278459908628</LAD>
    <LAD>2.392278459908628</LAD>
    <LM>3.50258194988953</LM>
    <LM>3.50258194988953</LM>
    <RCA>3.274917502338067</RCA>
    <RCA>3.274917502338067</RCA>
</subject>
</assessment>

I would like to remove the duplicate nodes such that it looks like this

<assessment> 
<subject>
    <Name>470  470 015</Name>
    <LAD>3.446887644423149</LAD>
    <LM>4.049357373198344</LM>
    <RCA>3.283339910532276</RCA>
</subject>
<subject>
    <Name>230 230067</Name>
    <LAD>2.392278459908628</LAD>
    <LM>3.50258194988953</LM>
    <RCA>3.274917502338067</RCA>
</subject>
</assessment>

Based on code noted below from a previous answer to a similar question (https://stackoverflow.com/a/37078109/18941723), I was able to process the first record, but not all the records in the file.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:for-each-group select="*" group-by="name()">
                <xsl:apply-templates select="current-group()[1]"/>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

CodePudding user response:

Try changing:

match="/*"

to:

match="subject"

CodePudding user response:

You had the right approach, here's how I would do it :

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
    
    <xsl:template match="subject">
      <xsl:copy>
        <xsl:for-each-group select="*" group-by="name()">
            <xsl:copy-of select="current-group()[1]"/>
        </xsl:for-each-group>
      </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

See it working here : https://xsltfiddle.liberty-development.net/6qjt5SC

  • Related