xmlxslt

XSLT remove parent node if child node contains specific value


I'm trying to remove the position node and all its children if OPERATION = REMOVE. I've tried something but what happens is the entire employee record gets deleted instead of just the position node that has the REMOVE operation. I want to retain everything else. I am limited to try to accomplish this with only xslt version 2.0.

** XML Sample**

<pi:Payroll_Extract_Employees xmlns:pi="urn:com.workday/picof">
    <pi:PayGroup>
        
        <pi:Employee>
            <pi:Summary>
                <pi:Employee_ID>123456</pi:Employee_ID>
                <pi:Name>Ford Harrison</pi:Name>
            </pi:Summary>
            <pi:Status>
                <pi:Employee_Status>Active</pi:Employee_Status>
                <pi:Hire_Date>2024-05-07</pi:Hire_Date>
            </pi:Status>
            <pi:Position>
                <pi:Operation>ADD</pi:Operation>
                <pi:Position_ID pi:PriorValue="">
                                    P38531
                                </pi:Position_ID>
                <pi:Business_Site pi:PriorValue="">
                                    3F_ABC
                                </pi:Business_Site>
            </pi:Position>
            <pi:Position>
                <pi:Operation>REMOVE</pi:Operation>
                <pi:Position_ID>P3131236</pi:Position_ID>
                <pi:Business_Site>3F_EFG</pi:Business_Site>
            </pi:Position>
        </pi:Employee>
    </pi:PayGroup>
</pi:Payroll_Extract_Employees>

What I want to achieve:

<EmployeeID>123456</EmployeeID>
<EmployeeName>Ford Harrison</EmployeeName>
<LocationName>3F ABC</LocationName>

Thanks in advance for the help!

Here's what I've done in XSLT so far:

OUTPUTS ALL ROWS EXCEPT EMPLOYEES WITH REMOVE OPERATION

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:pi="urn:com.workday/picof"
                exclude-result-prefixes="xs pi is"
                xmlns:is="java:com.workday.esb.intsys.xpath.ParsedIntegrationSystemFunctions"
                version="2.0">
    <xsl:output method="xml"
                omit-xml-declaration="yes"/>
    <xsl:template match="/pi:Employee[not(/pi:Employee/pi:Position/pi:Operation = 'REMOVE')]">
        <employee_record>
            <EmployeeID>
                <xsl:value-of select="/pi:Employee/pi:Summary/pi:Employee_ID"/>
            </EmployeeID>
            <EmployeeName>
                <xsl:value-of select="/pi:Employee/pi:Summary/pi:Name"/>
            </EmployeeName>
            
            <LocationName>
                <xsl:value-of select="replace(/pi:Employee/pi:Position/pi:Business_Site,'_',' ')"/>
            </LocationName>
        </employee_record>
    </xsl:template>
</xsl:stylesheet>

Solution

  • You ask for something like this I reckon:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:pi="urn:com.workday/picof"
                    version="2.0">
        <xsl:output method="xml"
                    omit-xml-declaration="yes"/>
        <xsl:template match="pi:Payroll_Extract_Employees/pi:PayGroup/pi:Employee">
            <employee_record>
                <EmployeeID>
                    <xsl:value-of select="pi:Summary/pi:Employee_ID"/>
                </EmployeeID>
                <EmployeeName>
                    <xsl:value-of select="pi:Summary/pi:Name"/>
                </EmployeeName>
                <xsl:if test="pi:Position/pi:Operation != 'REMOVE'">
                  <LocationName>
                    <xsl:value-of select="pi:Position/pi:Business_Site" />
                  </LocationName>
                </xsl:if>
            </employee_record>
        </xsl:template>
    
    </xsl:stylesheet>