cancel
Showing results for 
Search instead for 
Did you mean: 

Groovy or XSLT to remove XML Tag(not values) in sap cpi payload

nidhi_srivastava22
Active Contributor
0 Kudos
781

Hi Experts,

I have a XML payload from which I need to remove only the XML tag and the values should pass to the parent tag. Sample payload mentioned below -

nidhi_srivastava22_0-1727005601585.png

I tried few groovy functions mentioned on the community but that is replacing the entire <AdditionalComments/> tag to blank which is not expected.

Please help me if we can take this with groovy or I need to go with XSLT?

Thanks.

Best Regards,

Nidhi Srivastava

View Entire Topic
nageshrao
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Nidhi, 

As Ryan mentioned, the provided sample XML payload is invalid. If the source XML contains unescaped special characters like '@', '<', or '>', XSLT processing will fail. A Groovy script is a better option for handling invalid XML and generating valid output. The script is more robust than XSLT as it can handle XML validity issues. However, it assumes a specific structure, so you may need to modify it based on changes in your payload. Use the script below as a reference starting point to build/ customise as per your requirement.

Groovy Script - 

import com.sap.gateway.ip.core.customdev.util.Message
import groovy.xml.*

// Function to process the incoming message
def Message processData(Message message) {
    // Get the body of the message as a String
    def body = message.getBody(String)
    def result

    try {
        // Parse the XML body using XmlParser
        def xmlParser = new XmlParser(false, false)
        def rootNode = xmlParser.parseText(body)

        // Prepare to build the new XML output
        def writer = new StringWriter()
        def xmlBuilder = new MarkupBuilder(writer)

        // Create the Root element
        xmlBuilder.Root {
            // Traverse all nodes in the XML
            rootNode.depthFirst().each { node ->
                // Check for the Root1 element
                if (node.name() == 'Root1') {
                    Root1 {
                        // Process each child node of Root1
                        node.children().each { childNode ->
                            // If the child is AssignedTo, extract the email
                            if (childNode.name() == 'AssignedTo') {
                                def emailMatch = (childNode.text() =~ /([^<\s]+@[^>]+)/)
                                if (emailMatch) {
                                    // Add only the email to the output
                                    AssignedTo(emailMatch[0][0])
                                }
                            } else if (childNode.name() == 'AdditionalComments') {
                                // Extract comments from the div tag
                                AdditionalComments(childNode.div.text())
                            } else {
                                // Add other child nodes as they are
                                "${childNode.name()}"(childNode.text())
                            }
                        }
                    }
                }
            }
        }

        // Convert the writer output to string
        result = writer.toString()
    } catch (Exception e) {
        // If parsing fails, handle it with a more lenient approach
        def lines = body.readLines()
        // Initialize the output with the XML declaration and Root tag
        def output = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Root>\n")

        boolean inRoot1 = false
        // Process each line of the original XML
        lines.each { line ->
            // Skip XML declaration and Root tags
            if (line.contains('<?xml') || line.contains('<Root>') || line.contains('</Root>')) {
                return
            }
            // Detect the start of Root1 and set the flag
            if (line.contains('<Root1>')) {
                inRoot1 = true
                output << "  <Root1>\n"
                return
            }
            // Detect the end of Root1 and reset the flag
            if (line.contains('</Root1>')) {
                inRoot1 = false
                output << "  </Root1>\n"
                return
            }
            // If we are inside Root1, process its children
            if (inRoot1) {
                if (line.contains('<AssignedTo>')) {
                    // Extract email from AssignedTo using regex
                    def emailMatch = (line =~ /([^<\s]+@[^>]+)/)
                    if (emailMatch) {
                        output << "    <AssignedTo>${emailMatch[0][0]}</AssignedTo>\n"
                    }
                } else if (line.contains('<AdditionalComments>')) {
                    // Extract comments from the div tag
                    def comment = line.findAll(/<div>(.*?)<\/div>/)
                    if (comment) {
                        output << "    <AdditionalComments>${comment[0][1]}</AdditionalComments>\n"
                    }
                } else if (line.trim().startsWith('<') && line.trim().endsWith('>')) {
                    // Add other tags as they are
                    output << "    ${line.trim()}\n"
                }
            }
        }

        // Close the Root tag
        output << '</Root>'
        result = output.toString()
    }

    // Set the transformed XML as the body of the message
    message.setBody(result)
    return message
}


Source Invalid XML - 

<?xml version='1.0' encoding='UTF-8'?>
<Root>
<Root1>
<ADONumber>12345</ADONumber>
<State></State>
<AssignedTo>SRIVASTAVA Nidhi (External) <nidhi.srivastava.ext@XXXXX.eu> </AssignedTo>
<Priority></Priority>
<AdditionalComments>
<div>Comment 5</div>
</AdditionalComments>
</Root1>
</Root>

Output Valid XML - 

<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Root1>
<ADONumber>12345</ADONumber>
<State></State>
<AssignedTo>nidhi.srivastava.ext@XXXXX.eu</AssignedTo>
<Priority></Priority>
<AdditionalComments>d</AdditionalComments>
</Root1>
</Root>



nidhi_srivastava22
Active Contributor
0 Kudos
Thanks a lot Nagesh for your help. Marking the solution as accepted.
nidhi_srivastava22
Active Contributor
0 Kudos

Hi Nagesh @nageshrao  ,

I have another issue related to this blog which I posted in another thread as this thread was already closed. If you can suggest, it will be of great help. 

https://community.sap.com/t5/technology-q-a/structure-formatting-for-receiver-in-sap-cpi-through-gro... 

Thanks.

Best Regards,

Nidhi Srivastava