Home > other >  Remove other elements with the same name (not duplicate) and retain the last one?
Remove other elements with the same name (not duplicate) and retain the last one?

Time:10-13

We are receiving more than one element of the same name but need to only get the last one.

In this case, I am trying to remove the other Work element. I was hoping to remove it all then retain the last one but the XSLT I have is removing all "Change" element.

Perhaps it’s the positioning since I have removed all the Work elements, it doesn’t see the last Work anymore. Not really sure how to make this work.

INPUT XML

<?xml version='1.0' encoding='UTF-8'?>
<EmployeeInfo>
    <Summary>
        <Event>1234</Event>
        <Version>1</Version>
    </Summary>
    <Employee>
        <EmployeeSummary>
            <ID>1234</ID>
        </EmployeeSummary>
        <Change updates="1">
            <StatusReport>
                <Status>Active</Status>
            </StatusReport>
            <Work updates="1">
                <Job>1</Job>
            </Work>
            <Work>
                <Job>1</Job>
            </Work>
            <Work updates="0">
                <Job>1</Job>
            </Work>
            <Work updates="1">
                <Job>2</Job>
            </Work>
            <Compensation>
                <Salary>Monthly</Salary>
            </Compensation>
      </Change>
        <Change updates="2">
            <StatusReport>
                <Status>Active</Status>
            </StatusReport>
            <Info>
                <Email>[email protected]</Email>
            </Info>
            <Work updates="1">
                <Job>3</Job>
            </Work>
            <Work>
                <Job>3</Job>
            </Work>
            <Work updates="1">
                <Job>4</Job>
            </Work>
            <Work updates="0">
                <Job>4</Job>
            </Work>
      </Change>
    </Employee>
</EmployeeInfo>

XSLT

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="EmployeeInfo/Employee/Change/Work"/>

<xsl:template match="EmployeeInfo/Employee/Change">
    <xsl:apply-templates select="Work[last()]"/> 
</xsl:template>

OUTPUT produced by XSLT

<?xml version="1.0" encoding="UTF-8"?><EmployeeInfo>
    <Summary>
        <Event>1234</Event>
        <Version>1</Version>
    </Summary>
    <Employee>
        <EmployeeSummary>
            <ID>1234</ID>
        </EmployeeSummary>
        
        
    </Employee>
</EmployeeInfo>

DESIRED OUTPUT XML

<?xml version='1.0' encoding='UTF-8'?>
<EmployeeInfo>
    <Summary>
        <Event>1234</Event>
        <Version>1</Version>
    </Summary>
    <Employee>
        <EmployeeSummary>
            <ID>1234</ID>
        </EmployeeSummary>
        <Change updates="1">
            <StatusReport>
                <Status>Active</Status>
            </StatusReport>
            <Work updates="1">
                <Job>2</Job>
            </Work>
            <Compensation>
                <Salary>Monthly</Salary>
            </Compensation>
      </Change>
        <Change updates="2">
            <StatusReport>
                <Status>Active</Status>
            </StatusReport>
            <Info>
                <Email>[email protected]</Email>
            </Info>
            <Work updates="0">
                <Job>4</Job>
            </Work>
      </Change>
    </Employee>
</EmployeeInfo>

CodePudding user response:

AFAICT, you want to do:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Change">
    <xsl:copy>
        <xsl:apply-templates select="@* | StatusReport | Work[last()]"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
  • Related