Skip to Content

Generate intercalated nodes using graphical mapping

Hello experts,

I've a scenario where I have to map the information of one node (Item) to two different and sequencial nodes(ItemA and ItemB).

The source and target structures are shown below:

Source Message example:

<Root>
	<Items>
		<Item>
			<Field1>A1</Field1>
			<Field2>B2</Field2>
			<Field3>C3</Field3>
		</Item>
		<Item>
			<Field1>D1</Field1>
			<Field2>E2</Field2>
			<Field3>F3</Field3>
		</Item>
		<Item>
			<Field1>G1</Field1>
			<Field2>H2</Field2>
			<Field3>I3</Field3>
		</Item>
	</Items>
</Root>

Target Message:

<Root>
	<ItemA>
		<Field1>A1</Field1>
	</ItemA>
	<ItemB>
		<Field2>B2</Field2>
		<Field3>C3</Field3>
	</ItemB>
	<ItemA>
		<Field1>D1</Field1>
	</ItemA>
	<ItemB>
		<Field2>E2</Field2>
		<Field3>F3</Field3>
	</ItemB>
	<ItemA>
		<Field1>G1</Field1>
	</ItemA>
	<ItemB>
		<Field2>H2</Field2>
		<Field3>I3</Field3>
	</ItemB>
</Root>

The main problem here is that I was unable to map the source message to the target message following the sequence of ItemA/ItemB/...

Doing the regular graphical map, I only got this result:

<Root>
	<ItemA>
		<Field1>A1</Field1>
	</ItemA>
	<ItemA>
		<Field1>D1</Field1>
	</ItemA>
	<ItemA>
		<Field1>G1</Field1>
	</ItemA>
	<ItemB>
		<Field2>B2</Field2>
		<Field3>C3</Field3>
	</ItemB>
	<ItemB>
		<Field2>E2</Field2>
		<Field3>F3</Field3>
	</ItemB>
	<ItemB>
		<Field2>H2</Field2>
		<Field3>I3</Field3>
	</ItemB>
</Root>

Is there a way to do this kind of mapping graphically?

Thanks in advance,

José Nunes

Add a comment
10|10000 characters needed characters exceeded

Related questions

6 Answers

  • Best Answer
    author's profile photo Former Member
    Former Member
    Posted on Jul 15, 2011 at 04:05 AM

    Hi,

    Try to create your target structure as

    <Root>

    <Record>

    <ItemA>

    <Field1>A1</Field1>

    </ItemA>

    <ItemB>

    <Field2>B2</Field2>

    <Field3>C3</Field3>

    </ItemB>

    </Record>

    </Root>

    Map Item to Record

    This should resolve the issue

    Add a comment
    10|10000 characters needed characters exceeded

  • Posted on Jul 15, 2011 at 05:25 AM

    Hi,

    In graphical mapping you can achieve this by creating ItemA and itemB under Recordset node. So recordset node repeats on the basis of Item from input and you can have the same sequence of itemA and itemB.

    Regards,

    Harish

    Add a comment
    10|10000 characters needed characters exceeded

  • author's profile photo Former Member
    Former Member
    Posted on Jul 15, 2011 at 06:29 AM

    Hi,

    Follow the Chandra & Harish Suggestions. if you don't want to change the structure then go for JAVA Mapping.

    Regards,

    Naga.

    Add a comment
    10|10000 characters needed characters exceeded

  • Posted on Jul 15, 2011 at 06:47 AM

    Hi Jose,

    U have to create ur structure as below

    Record Element 0....unbounded

    <ItemA> Element 0..1

    fields1 xsd:string 1

    </ItemA>

    <itemB> Element 0...1

    field2 xsd:string 1

    field3 xsd:string 1

    </ITEMB>

    U can map Item A and ItemB record nodes with Constant space. Then u will get ur desired output.

    Thanks,

    Enivass

    Add a comment
    10|10000 characters needed characters exceeded

  • author's profile photo Former Member
    Former Member
    Posted on Jul 15, 2011 at 07:33 AM

    Hi

    check this Screenshot...

    http://postimage.org/image/2esx1q4lg/

    Map Recorset (o.unbounded) to item (0 to unbounded)

    Regards,

    XA

    Add a comment
    10|10000 characters needed characters exceeded

  • Posted on Jul 15, 2011 at 11:54 AM

    Hi Jose Nunes,

    This is the java mapping program required to meet your requirements. I have written it for PI 7.0. Please make necessary changes for PI 7.1 .

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.Map;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    import com.sap.aii.mapping.api.StreamTransformation;
    import com.sap.aii.mapping.api.StreamTransformationException;
    
    public class DOMParser2 implements StreamTransformation{
    
    
    
    
    public void execute(InputStream in, OutputStream out)
    throws StreamTransformationException {
    
    
    try
    {
    	DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
    	DocumentBuilder builderel=factory.newDocumentBuilder();
    	/*input document in form of XML*/
    	Document docIn=builderel.parse(in);
    	/*document after parsing*/
    	Document docOut=builderel.newDocument();
    	TransformerFactory tf=TransformerFactory.newInstance();
    	Transformer transform=tf.newTransformer();
    	Element root,child=null,child1=null;
    	Node textChild;
    	
    	
    	NodeList l;
    	int mm,n1;
    	boolean b1=false;
    	root=docOut.createElement("Root");
    	//root.setAttribute("xmlns","urn:bp:xi:hr:edm:test:100");
    	l=docIn.getElementsByTagName("Item");
    	
    	
    	n1=l.getLength();
    	
    	for(mm=0;mm<n1;++mm)
    	{
    		Node temp;
    		for(temp=l.item(mm).getFirstChild();temp!=null;temp=temp.getNextSibling())
    		{
    			if(temp.getNodeType()== Node.ELEMENT_NODE)
    			{
    				if(temp.getNodeName().equals("Field1"))
    				{
    					Node c=temp.getFirstChild();
    					child=docOut.createElement("ItemA");
    					b1=false;
    					if(c!=null)
    					{
    						child1=docOut.createElement("Field1");
    						textChild=docOut.createTextNode(c.getNodeValue());
    						child1.appendChild(textChild);
    						child.appendChild(child1);
    						
    					}	
    					root.appendChild(child);
    					
    				}
    				else if(temp.getNodeName().equals("Field2"))
    				{
    					Node c=temp.getFirstChild();
    					child=docOut.createElement("ItemB");
    					b1=true;
    					if(c!=null)
    					{
    						child1=docOut.createElement("Field2");
    						textChild=docOut.createTextNode(c.getNodeValue());
    						child1.appendChild(textChild);
    						child.appendChild(child1);
    					}
    					
    				}
    				else if(temp.getNodeName().equals("Field3"))
    				{
    					Node c=temp.getFirstChild();
    					if(b1==false)
    					{
    						child=docOut.createElement("ItemB");
    					}	
    					if(c!=null)
    					{
    						child1=docOut.createElement("Field3");
    						textChild=docOut.createTextNode(c.getNodeValue());
    						child1.appendChild(textChild);
    						child.appendChild(child1);
    					}
    					root.appendChild(child);
    				}
    			}
    		}	
    	}
     
    	
    	
    	docOut.appendChild(root);
    	transform.transform(new DOMSource(docOut), new StreamResult(out)); 
    }
    catch(Exception e)
    {
    	e.printStackTrace();
    }
    
    
    }
    
    public void setParameter(Map arg0) {
    
    
    }
    
    public static void main(String[] args) {
    try{
    DOMParser2 genFormat=new DOMParser2();
    FileInputStream in=new FileInputStream("C:\\Apps\\my folder\\sdn\\input.xml");
    FileOutputStream out=new FileOutputStream("C:\\Apps\\my folder\\sdn\\output.xml");
    genFormat.execute(in,out);
    }
    catch(Exception e)
    {
    e.printStackTrace();
    }
    }
    
    
    }
    
    
    

    input.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <Root><ItemA><Field1>A1</Field1></ItemA><ItemB><Field2>B2</Field2><Field3>C3</Field3></ItemB><ItemA><Field1>D1</Field1></ItemA><ItemB><Field2>E2</Field2><Field3>F3</Field3></ItemB><ItemA><Field1>G1</Field1></ItemA><ItemB><Field2>H2</Field2><Field3>I3</Field3></ItemB></Root>
    

    Output.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <Root><ItemA><Field1>A1</Field1></ItemA><ItemB><Field2>B2</Field2><Field3>C3</Field3></ItemB><ItemA><Field1>D1</Field1></ItemA><ItemB><Field2>E2</Field2><Field3>F3</Field3></ItemB><ItemA><Field1>G1</Field1></ItemA><ItemB><Field2>H2</Field2><Field3>I3</Field3></ItemB></Root>
    

    When I view Output.xml in browser I get this

     <?xml version="1.0" encoding="UTF-8" ?> 
    - <Root>
    - <ItemA>
      <Field1>A1</Field1> 
      </ItemA>
    - <ItemB>
      <Field2>B2</Field2> 
      <Field3>C3</Field3> 
      </ItemB>
    - <ItemA>
      <Field1>D1</Field1> 
      </ItemA>
    - <ItemB>
      <Field2>E2</Field2> 
      <Field3>F3</Field3> 
      </ItemB>
    - <ItemA>
      <Field1>G1</Field1> 
      </ItemA>
    - <ItemB>
      <Field2>H2</Field2> 
      <Field3>I3</Field3> 
      </ItemB>
      </Root>
    

    Regards

    Anupam

    Add a comment
    10|10000 characters needed characters exceeded

    • Thanks everyone for your valuable input.

      I have two constrains that doesn't allow me to do it using Java Mapping or changing the xml structure.

      - The customer restrict the use of Java Mapping just in exceptional cases.

      - This interface is a RFC to FILE and the FILE will be generated using FCC, so I cannot use a complex XML structure with more than 2 nested nodes.

      Despite of the fact that it may not be the best solution, I'm considering to create a xml structure as follow in order to get the expected result.

      <Root>
      <Recordset>
      <Row>
      <ItemA>A1</ItemA>
      <ItemB>B2C3</ItemB>
      </Row>
      <Row>
      <ItemA>D1</ItemA>
      <ItemB>E2F3</ItemB>
      </Row>
      <Row>
      <ItemA>G1</ItemA>
      <ItemB>H2I3</ItemB>
      </Row>
      </Recordset>
      </Root>

      And set in the communication channel the FCC property Row.fieldSeparator = 'nl'

      Best Regards,

      José Nunes

Before answering

You should only submit an answer when you are proposing a solution to the poster's problem. If you want the poster to clarify the question or provide more information, please leave a comment instead, requesting additional details. When answering, please include specifics, such as step-by-step instructions, context for the solution, and links to useful resources. Also, please make sure that you answer complies with our Rules of Engagement.
You must be Logged in to submit an answer.

Up to 10 attachments (including images) can be used with a maximum of 1.0 MB each and 10.5 MB total.