Technology Blog Posts by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
purna22
Discoverer
895

This blog post walks through a common integration scenario: comparing two XML structures using XSLT to identify what has changed and needs to be synchronized. We'll detect added and updated elements and generate a clean delta XML for downstream processing.

 Use Case

Imagine the following XML document representing two data sources:

purna22_1-1751280810687.png

We aim to compare R1 (source) and User (target) to detect:
  • Fields in R1 missing in User → flagged as ADD

  • Fields in both, but with different values → flagged as UPDATE

  • Nested elements like Address are also compared deeply

 XSLT Logic

Below is the complete XSLT 1.0 code that performs the comparison and outputs the results in a <Root><R2> structure. This can be used in SAP Cloud Integration’s message mappings, PI/PO mappings, or any tool that supports XSLT.

 Full XSLT Code

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

  <xsl:template match="/Main">
    <Root>
      <R2>
        <xsl:variable name="r1" select="R1"/>
        <xsl:variable name="r2" select="User"/>

        <!-- Add operation: elements present in R1 but not in User -->
        <xsl:for-each select="$r1/*">
          <xsl:variable name="name" select="name()"/>
          <xsl:if test="not($r2/*[name() = $name])">
            <Add>
              <operation>ADD</operation>
              <xsl:copy-of select="."/>
            </Add>
          </xsl:if>
        </xsl:for-each>

        <!-- Update operation -->
        <xsl:for-each select="$r1/*">
          <xsl:variable name="name" select="name()"/>
          <xsl:variable name="r1node" select="."/>
          <xsl:variable name="r2node" select="$r2/*[name() = $name]"/>

          <!-- Direct value changes (non-nested) -->
          <xsl:if test="$r2node and not($r1node/*) and normalize-space($r1node) != normalize-space($r2node)">
            <update>
              <operation>Update</operation>
              <xsl:copy-of select="$r1node"/>
            </update>
          </xsl:if>

          <!-- Nested structure comparison -->
          <xsl:if test="$r1node/* and $r2node/*">
            <xsl:variable name="hasDifference">
              <xsl:for-each select="$r1node/*">
                <xsl:variable name="subname" select="name()"/>
                <xsl:variable name="r1sub" select="."/>
                <xsl:variable name="r2sub" select="$r2node/*[name() = $subname]"/>
                <xsl:if test="normalize-space($r1sub) != normalize-space($r2sub)">
                  <xsl:text>yes</xsl:text>
                </xsl:if>
              </xsl:for-each>
            </xsl:variable>
            <xsl:if test="contains($hasDifference, 'yes')">
              <update>
                <operation>Update</operation>
                <xsl:copy-of select="$r1node"/>
              </update>
            </xsl:if>
          </xsl:if>
        </xsl:for-each>
      </R2>
    </Root>
  </xsl:template>
</xsl:stylesheet>

🧾 Sample Output

With the above input and XSLT, the result is:

purna22_4-1751280810760.png

This output structure is ideal for triggering update APIs, generating change logs, or sending notification messages.

If you're working with XML transformations in SAP Cloud Integration (CPI) and need to identify differences between nested XML structures, this XSLT-based approach can save you hours of manual comparison and debugging.

 

Have you encountered similar scenarios in CPI where comparing XML payloads was necessary? Share your solutions, questions, or challenges in the comments—let’s learn from each other!