Condition to merge --> Below are condition to merge sample xml
1. Merge multiple nodes based on Operations and
2. Attribute with value as
/:Request/:Attribute[:Name='ID']/:Value/*:NewValue**
Input XML message-->
<?xml version = '1.0' encoding = 'UTF-8'?>
<tns:Requests xmlns:tns="http://sample.com/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://sample.com/v1">
<?audit suppress oracle.ide.xml.validation-error?>
<tns:Request>
<tns:System>ABC</tns:System>
<tns:Operation>Modify</tns:Operation>
<tns:Attribute>
<tns:Name>ID</tns:Name>
<tns:Value>
<tns:NewValue>999</tns:NewValue>
</tns:Value>
</tns:Attribute>
<tns:Attribute>
<tns:Name>TITLE</tns:Name>
<tns:Value>
<tns:NewValue>Manager</tns:NewValue>
</tns:Value>
</tns:Attribute>
</tns:Request>
<tns:Request>
<tns:System>ABC</tns:System>
<tns:Operation>Modify</tns:Operation>
<tns:Attribute>
<tns:Name>ID</tns:Name>
<tns:Value>
<tns:NewValue>999</tns:NewValue>
</tns:Value>
</tns:Attribute>
<tns:Attribute>
<tns:Name>COUNTRY</tns:Name>
<tns:Value>
<tns:NewValue>Ghana</tns:NewValue>
</tns:Value>
</tns:Attribute>
</tns:Request>
<tns:Request>
<tns:System>ABC</tns:System>
<tns:Operation>Disable</tns:Operation>
<tns:Attribute>
<tns:Name>ID</tns:Name>
<tns:Value>
<tns:NewValue>888</tns:NewValue>
</tns:Value>
</tns:Attribute>
<tns:Attribute>
<tns:Name>STATUS</tns:Name>
<tns:Value>
<tns:NewValue>Inactive</tns:NewValue>
</tns:Value>
</tns:Attribute>
</tns:Request>
</tns:Requests>
Need to use XSLT to transform input xml message to expected output
**Expected Output** <?xml version="1.0" encoding="UTF-8"?> <tns:Requests xmlns:tns="http://sample.com/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://sample.com/v1"> <?audit suppress oracle.ide.xml.validation-error?> <tns:Request> <tns:System>ABC</tns:System> <tns:Operation>Modify</tns:Operation> <tns:Attribute> <tns:Name>ID</tns:Name> <tns:Value> <tns:NewValue>999</tns:NewValue> </tns:Value> </tns:Attribute> <tns:Attribute> <tns:Name>TITLE</tns:Name> <tns:Value> <tns:NewValue>Manager</tns:NewValue> </tns:Value> </tns:Attribute> <tns:Attribute> <tns:Name>COUNTRY</tns:Name> <tns:Value> <tns:NewValue>USA</tns:NewValue> </tns:Value> </tns:Attribute> </tns:Request> <tns:Request> <tns:System>ABC</tns:System> <tns:Operation>Disable</tns:Operation> <tns:Attribute> <tns:Name>ID</tns:Name> <tns:Value> <tns:NewValue>888</tns:NewValue> </tns:Value> </tns:Attribute> <tns:Attribute> <tns:Name>STATUS</tns:Name> <tns:Value> <tns:NewValue>Inactive</tns:NewValue> </tns:Value> </tns:Attribute> </tns:Request> </tns:Requests>
Not able to merge multiple nodes as explain in output section using xslt based on multiple attribute
How to group based on Attribute
Code
<?xml version="1.0"?> <!-- current-grouping-key.xsl --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output method="xml" indent="yes"/> <xsl:template match="@*|node()" name="identity"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="Requests"> <xsl:copy> <xsl:apply-templates select="@*|* except Request"/> <xsl:for-each-group select="Request" group-by="Operation"> <Request> <System>ABC</System> <Operation> <xsl:value-of select="current-grouping-key()"/> </Operation> <xsl:for-each-group select="Attribute" group-by="NewValue"> <Attribute> <Name>ID</Name> <Value> <NewValue> <xsl:value-of select="current-grouping-key()"/></NewValue> </Value> </Attribute> <xsl:for-each select="current-group()"> <Attribute> <Name> <xsl:value-of select="Name"/></Name> <Value> <NewValue><Name> <xsl:value-of select="NewValue"/></Name></NewValue> </Value> </Attribute> </xsl:for-each> </xsl:for-each-group> </Request> </xsl:for-each-group> </xsl:copy> </xsl:template> </xsl:stylesheet>
CodePudding user response:
I think you want
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xpath-default-namespace="http://sample.com/v1">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Requests">
<xsl:copy>
<xsl:apply-templates select="@*|* except Request"/>
<xsl:for-each-group select="Request" group-by="Operation">
<xsl:copy>
<xsl:apply-templates select="System, Operation"/>
<xsl:for-each-group select="current-group()/Attribute" group-by="Value/NewValue">
<xsl:copy>
<xsl:apply-templates select="Name, Value"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>