Home > Blockchain >  SAP CPI Groovy Script XML Parser check Node and Add
SAP CPI Groovy Script XML Parser check Node and Add

Time:11-28

i have following problem. I need to add a Node, if its not available. For example

INPUT IS :

<DataTable>
    <DataRow>
        <Field1>1</Field1>
    </DataRow>
    <DataRow>
        <Field1>1</Field1>
        <Field2>1</Field2>
    </DataRow>
    <DataRow>
        <Field1>1</Field1>
        <Field2>1</Field2>
        <Field3>1</Field3>
    </DataRow>
</DataTable>

OUTPUT SHOULD BE THIS:

<DataTable>
    <DataRow>
        <Field1>1</Field1>
        <Field2/>
        <Field3/>
    </DataRow>
    <DataRow>
        <Field1>1</Field1>
        <Field2>1</Field2>
        <Field3/>
    </DataRow>
    <DataRow>
        <Field1>1</Field1>
        <Field2>1</Field2>
        <Field3>1</Field3>
    </DataRow>
</DataTable>

So if one Node is not available, than it should be added to it in the output file. This is what i tried.

This my code, it works only with a flat xml.

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

Message processData(Message message) {
    def fields = ['Field1', 'Field2', 'Field3']
    def payload = new XmlParser().parse(message.getBody(Reader))
    (fields - (payload.children() as List<Node>)*.name()).each { payload.appendNode(it) }
    message.setBody(XmlUtil.serialize(payload))
    return message
}

I want to add Tag to the output file.

Can me help someone ? I would be very thankful. Thank you

I want to add Tag to the output file.

Can me help someone ? I would be very thankful. Thank you

CodePudding user response:

So, for the conversion we can write a function that takes a string (the input xml) and a list of required fields, and returns the new xml

import groovy.xml.XmlParser
import groovy.xml.XmlNodePrinter

String extendFields(String xmlInput, List<String> fields) {
    def xml = new XmlParser().parseText(xmlInput)
    xml.findAll { it.name() == 'DataRow' }.each { row ->
        fields.each { field ->
            if (!row."$field") {
                row.appendNode(field)
            }
        }
    }
    new StringWriter().with { out ->
        new XmlNodePrinter(new PrintWriter(out)).with { writer ->
            writer.preserveWhitespace = true
            writer.print(xml)
        }
        out.toString()
    }
}

Calling this with your input XML:

def input = '''<DataTable>
    <DataRow>
        <Field1>1</Field1>
    </DataRow>
    <DataRow>
        <Field1>1</Field1>
        <Field2>1</Field2>
    </DataRow>
    <DataRow>
        <Field1>1</Field1>
        <Field2>1</Field2>
        <Field3>1</Field3>
    </DataRow>
</DataTable>'''

println extendFields(input, ['Field1', 'Field2', 'Field3'])

prints

<DataTable>
  <DataRow>
    <Field1>1</Field1>
    <Field2/>
    <Field3/>
  </DataRow>
  <DataRow>
    <Field1>1</Field1>
    <Field2>1</Field2>
    <Field3/>
  </DataRow>
  <DataRow>
    <Field1>1</Field1>
    <Field2>1</Field2>
    <Field3>1</Field3>
  </DataRow>
</DataTable>

So then, you can change your method in the question to call this new method:

Message processData(Message message) {
    def fields = ['Field1', 'Field2', 'Field3']
    def payload = extendFields(message.getBody(Reader), fields)
    message.setBody(payload)
    return message
}

Pulling this out into a separate method also has the advantage of making it more easily testable

  • Related