cancel
Showing results for 
Search instead for 
Did you mean: 

CPI: How to map multiple fields multiple times to target node

rayd
Associate
Associate
289

I have a requirement to map a list of fields, and each value multiple times to target node.

Its similar like use Many as many function - compare with the standard function use one as many.

My source xml is like below:

<Root>
    <id>123</id>
    <items>
        <itemId>1</itemId>
        <references>
            <code>c01</code>
            <id>1</id>
        </references>
        <references>
            <code>c01</code>
            <id>2</id>
        </references>
        <subItem>
            <subItemId>001
            </subItemId>
        </subItem>
        <subItem>
            <subItemId>002
            </subItemId>
        </subItem>
        <subItem>
            <subItemId>003
            </subItemId>
        </subItem>
    </items>
    <items>
        <itemId>2</itemId>
        <references>
            <code>c01</code>
            <id>3</id>
        </references>
        <references>
            <code>c01</code>
            <id>4</id>
        </references>
        <references>
            <code>c01</code>
            <id>5</id>
        </references>
        <subItem>
            <subItemId>001
            </subItemId>
        </subItem>
        <subItem>
            <subItemId>002
            </subItemId>
        </subItem>
    </items>
</Root>

and I want to map the each of the  'reference' node multuple times, the times equals the size of the subitem in source node.

Below are my expected target structure:

<Root>
    <id>123</id>
    <targetSubitem>
        <itemId>1</itemId>
        <references>
            <code>c01</code>
            <id>1</id>
        </references>
        <references>
            <code>c01</code>
            <id>2</id>
        </references>
    </targetSubitem>
    <targetSubitem>
        <itemId>2</itemId>
        <references>
            <code>c01</code>
            <id>1</id>
        </references>
        <references>
            <code>c01</code>
            <id>2</id>
        </references>
    </targetSubitem>
    <targetSubitem>
        <itemId>3</itemId>
        <references>
            <code>c01</code>
            <id>1</id>
        </references>
        <references>
            <code>c01</code>
            <id>2</id>
        </references
    </targetSubitem>
    <targetSubitem>
        <itemId>4</itemId>
        <references>
            <code>c01</code>
            <id>3</id>
        </references>
        <references>
            <code>c01</code>
            <id>4</id>
        </references>
        <references>
            <code>c01</code>
            <id>5</id>
        </references>
    </targetSubitem>
    <targetSubitem>
        <itemId>5</itemId>
        <references>
            <code>c01</code>
            <id>3</id>
        </references>
        <references>
            <code>c01</code>
            <id>4</id>
        </references>
        <references>
            <code>c01</code>
            <id>5</id>
        </references>
    </targetSubitem>
</Root>

Is there a way to do it with standard mapping funcion? Or must write  UDF?

Thanks a lot in advance

 

 

 

 

sivaramaraju_danthuluri
Product and Topic Expert
Product and Topic Expert
0 Kudos
HI Ryad,Can you try this code import com.sap.gateway.ip.core.customdev.util.Message; import groovy.xml.*; def Message processData(Message message) { // Get the XML body as a string def xmlBody = message.getBody(String.class); // Parse the XML using XmlParser to work with mutable XML structure def parser = new XmlParser() def xml = parser.parseText(xmlBody) // Create a new root element def newRoot = new Node(null, 'Root') new Node(newRoot, 'id', '123') // Initialize itemId for targetSubitem int targetItemId = 1 // Iterate over the original XML's items xml.items.each { item -> item.subItem.each { subItem -> // Create a new targetSubitem element def targetSubitem = new Node(newRoot, 'targetSubitem') // Add the generated itemId element new Node(targetSubitem, 'itemId', targetItemId.toString()) // Increment the itemId for the next targetSubitem targetItemId++ // Iterate over the references and add them to the targetSubitem item.references.each { ref -> def reference = new Node(targetSubitem, 'references') new Node(reference, 'code', ref.code.text()) new Node(reference, 'id', ref.id.text()) } } } // Convert the transformed XML back to a string def writer = new StringWriter() def xmlNodePrinter = new XmlNodePrinter(new PrintWriter(writer)) xmlNodePrinter.preserveWhitespace = true xmlNodePrinter.print(newRoot) def transformedXml = writer.toString() // Set the transformed XML as the new message body message.setBody(transformedXml) return message; }
Ryan-Crosby
Active Contributor
0 Kudos

Given the source/target structures I think this would be pretty easy using IA.

rayd
Associate
Associate
0 Kudos
Hi Ryan, Could you tell me what exactally does 'IA' mean, I am somehow new to CPI, Thanks!
Ryan-Crosby
Active Contributor
0 Kudos
Integration Advisor

Accepted Solutions (0)

Answers (0)