Search code examples
xsltxslt-2.0xslt-3.0xslt-grouping

XSLT - Update value based on conditions from child of sibling element


I need to update event and eventReason of Job from Job_event based on values by comparing fields "startdate", "J_Seq_Number" of Job with fields "eventDate", "JE_Seq_Number" of Job_event. Any help would be appreciate, Thank you.

Input XML

 <Response>
    <Employee>
        <ID>1234</ID>
        <Person>
            <personalData>
                <firstname>FirstName</firstname>
                <lastname>Lastname</lastname>
            </personalData>
            <address>
                <address1>test</address1>
            </address>
            <Job>
                <startDate>2022-01-01</startDate>
                <event>1J</event>
                <eventReason>1J_ER</eventReason>
                <J_Seq_Number>2</J_Seq_Number>
            </Job>
            <Job>
                <startDate>2022-01-01</startDate>
                <event>1J</event>
                <eventReason>1J_ER</eventReason>
                <J_Seq_Number>1</J_Seq_Number>
            </Job>
            <Job>
                <startDate>2022-02-01</startDate>
                <event>3J</event>
                <eventReason>3J_ER</eventReason>
                <J_Seq_Number>1</J_Seq_Number>
            </Job>
            <Job_event>
                <eventDate>2022-01-01</eventDate>
                <event>1JE_Update</event>
                <eventReason>1JE_ER_Update</eventReason>
                <JE_Seq_Number>2</JE_Seq_Number>
            </Job_event>
            <Job_event>
                <eventDate>2022-01-01</eventDate>
                <event>2JE_Update</event>
                <eventReason>2JE_ER_Update</eventReason>
                <JE_Seq_Number>1</JE_Seq_Number>
            </Job_event>
            <Job_event>
                <eventDate>2022-02-01</eventDate>
                <event>3JE_Update</event>
                <eventReason>3JE_ER_Update</eventReason>
                <JE_Seq_Number>1</JE_Seq_Number>
            </Job_event>
        </Person>
    </Employee>
</Response>

        

Expect output XML, Event in Job has been updated from Job Event by comparing

<Response>
    <Employee>
        <ID>1234</ID>
        <Person>
            <personalData>
                <firstname>FirstName</firstname>
                <lastname>Lastname</lastname>
            </personalData>
            <address>
                <address1>test</address1>
            </address>
            <Job>
                <startDate>2022-01-01</startDate>
                <event>1JE_Update</event>
                <eventReason>1JE_ER_Update</eventReason>
                <J_Seq_Number>2</J_Seq_Number>
            </Job>
            <Job>
                <startDate>2022-01-01</startDate>
                <event>2JE_Update</event>
                <eventReason>2JE_ER_Update</eventReason>
                <J_Seq_Number>1</J_Seq_Number>
            </Job>
            <Job>
                <startDate>2022-02-01</startDate>
                <event>3JE_Update</event>
                <eventReason>3JE_ER_Update</eventReason>
                <J_Seq_Number>1</J_Seq_Number>
            </Job>
            <Job_event>
                <eventDate>2022-01-01</eventDate>
                <event>1JE_Update</event>
                <eventReason>1JE_ER_Update</eventReason>
                <JE_Seq_Number>2</JE_Seq_Number>
            </Job_event>
            <Job_event>
                <eventDate>2022-01-01</eventDate>
                <event>2JE_Update</event>
                <eventReason>2JE_ER_Update</eventReason>
                <JE_Seq_Number>1</JE_Seq_Number>
            </Job_event>
            <Job_event>
                <eventDate>2022-02-01</eventDate>
                <event>3JE_Update</event>
                <eventReason>3JE_ER_Update</eventReason>
                <JE_Seq_Number>1</JE_Seq_Number>
            </Job_event>
        </Person>
    </Employee>
</Response>

Solution

  • For that single Employee/Person document it should suffice to use

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        expand-text="yes"
        exclude-result-prefixes="#all"
        version="3.0">
    
      <xsl:mode on-no-match="shallow-copy"/>
    
      <xsl:output method="xml" indent="yes"/>
      
      <xsl:key name="job_event" match="Job_event" composite="yes" use="eventDate, JE_Seq_Number"/>
    
      <xsl:template match="Job[key('job_event', (startDate, J_Seq_Number))]/event">
        <xsl:copy>{key('job_event', ../(startDate, J_Seq_Number))/event}</xsl:copy>
      </xsl:template>
      
      <xsl:template match="Job[key('job_event', (startDate, J_Seq_Number))]/eventReason">
        <xsl:copy>{key('job_event', ../(startDate, J_Seq_Number))/eventReason}</xsl:copy>
      </xsl:template>
      
    </xsl:stylesheet>