xmlxsltgroovysap-cpi

Remove node according to date in child


Using SAP CPI as a tool and with a Groovy script, I need to remove the "Letter" node if its creation date is older than others located at the same level.

Given this XML:

<root>
    <JobApplication>
        <OfferLetter>
            <Letter>
                <offerLetterId>699</offerLetterId>
                <createdBy>00004221</createdBy>
                <createDate>2022-09-15T13:20:17.000</createDate>
            </Letter>
            <Letter>
                <offerLetterId>724</offerLetterId>
                <createdBy>00001472</createdBy>
                <createDate>2022-09-26T13:27:39.000</createDate>
            </Letter>
        </OfferLetter>
    </JobApplication>
    <JobApplication>
        <OfferLetter>
            <Letter>
                <offerLetterId>723</offerLetterId>
                <createdBy>00001472</createdBy>
                <createDate>2022-09-26T13:27:04.000</createDate>
            </Letter>
        </OfferLetter>
    </JobApplication>
    <JobApplication>
        <OfferLetter>
            <Letter>
                <offerLetterId>695</offerLetterId>
                <createdBy>00001472</createdBy>
                <createDate>2022-09-03T14:02:37.000</createDate>
            </Letter>
        </OfferLetter>
    </JobApplication>
</root>

In the first JobApplication node, it has two "Letter" nodes and I need to keep the newer one: "2022-09-26T13:27:39.000" and remove the other node.

The result should be like this:

<root>
    <JobApplication>
        <OfferLetter>
            <Letter>
                <offerLetterId>724</offerLetterId>
                <createdBy>00001472</createdBy>
                <createDate>2022-09-26T13:27:39.000</createDate>
            </Letter>
        </OfferLetter>
    </JobApplication>
    <JobApplication>
        <OfferLetter>
            <Letter>
                <offerLetterId>723</offerLetterId>
                <createdBy>00001472</createdBy>
                <createDate>2022-09-26T13:27:04.000</createDate>
            </Letter>
        </OfferLetter>
    </JobApplication>
    <JobApplication>
        <OfferLetter>
            <Letter>
                <offerLetterId>695</offerLetterId>
                <createdBy>00001472</createdBy>
                <createDate>2022-09-03T14:02:37.000</createDate>
            </Letter>
        </OfferLetter>
    </JobApplication>
</root>

Solution

  • With XSLT 3:

      <xsl:mode on-no-match="shallow-copy"/>
    
    
      <xsl:template match="OfferLetter/Letter[not(xs:dateTime(createDate) = max(../Letter/createDate/xs:dateTime(.)))]"/>
    

    In XSLT 2 you need to remove the xsl:mode declaration and spell it out as a template

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