Compare Two XML Elements and Filter using WSO2 EI
Think about an integration scenario, where you are getting a list of data from a service endpoint(Data 1) and you want to exclude or match this response against the data returned by another service endpoint(Data 2).
In such a situation, first, you need to have a unique attribute in both data set to exclude or match elements. So in my use case, list of data and matching content is as below
<CodeLists> <CodeList> <Id>O</Id> <Name>Open</Name> </CodeList> <CodeList> <Id>C</Id> <Name>Cancelled</Name> </CodeList> <CodeList> <Id>X</Id> <Name>Denied</Name> </CodeList> <CodeList> <Id>P</Id> <Name>Pending</Name> </CodeList> <CodeList> <Id>D</Id> <Name>Duplicate</Name> </CodeList> </CodeLists>
Data 1
<CodeLists> <CodeList> <Id>O</Id> <Name>Open</Name> </CodeList> <CodeList> <Id>P</Id> <Name>Pending</Name> </CodeList> </CodeLists>
Data 2
<property name="elementsToBeHide" expression="string-join(//CodeLists/CodeList/Id, ',')" scope="default" type="STRING"/>
Then I am calling my XSLT with elementsToBeHide as a parameter.
<xslt key="conf:/xslts/xslt_FilterResults.xslt"> <property name="elementsToBeHide" expression="$ctx:elementsToBeHide"/> </xslt>
My XSLT file is stored in the registry. However, if you are using a Micro Integrator profile, you can add this XSLT as a local entry. Inside my XSLT document, I am looping all code list elements and check whether each ID exists in 'elementsToBeHide' parameter. You can use the same XSLT Choose Condition to filter data based on matching or not matching scenarios. In my example, if ID is not matching to the current ID, it will be added to Code element.
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sy="http://ws.apache.org/ns/synapse" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <xsl:strip-space elements="*" /> <xsl:param name="elementsToBeHide" /> <xsl:template match="/CodeLists"> <CodeLists> <CodeList> <xsl:for-each select="CodeList"> <xsl:choose> <xsl:when test="matches($elementsToBeHide,Id)"> <!-- match senarios --> </xsl:when> <xsl:otherwise> <!-- not matching --> <Code> <Name><xsl:value-of select="Name"/></Name> <Id><xsl:value-of select="Id"/></Id> </Code> </xsl:otherwise> </xsl:choose> </xsl:for-each> </CodeList> </CodeLists> </xsl:template> </xsl:stylesheet>
The output of the XSLT transformation is as below and it only includes elements which are not matching to the filtering data set.
<CodeLists> <CodeList> <Code> <Id>C</Id> <Name>Cancelled</Name> </Code> <Code> <Id>X</Id> <Name>Denied</Name> </Code> <Code> <Id>D</Id> <Name>Duplicate</Name> </Code> </CodeList> </CodeLists>
Comments