cancel
Showing results for 
Search instead for 
Did you mean: 

splitting in to XML tags

former_member188791
Participant
0 Kudos

Hi Group,

We have scenario where we are getting whole XML message as SOAP request( in one row),we need to read this and change some XML tag names,can any body suggest.

Regards,

Rajiv

Accepted Solutions (0)

Answers (1)

Answers (1)

Shabarish_Nair
Active Contributor
0 Kudos

if it is only about changing the tag names, shouldnt a normal replaceAll string function help?

former_member188791
Participant
0 Kudos

Hi Shabarish,

Thank you for your reply,its not all of the tags change only few,also needs to change (like removing space/adding zeroes ) etc..

Regards,

Rajiv

anupam_ghosh2
Active Contributor
0 Kudos

Hi Rajiv,

Java mappping using DOM parser is the solution to your problem. For more details on DOM parser please refer this link

http://wiki.sdn.sap.com/wiki/display/XI/BeginnersguidetoJavamappingusingDOMparserinSAPXI

Forum members would require further information to assist you further on this issue.

1. What is the vesrion of PI you are working?

2. what is the complete source and target xml structure?

With DOM parser you can reach exact tags, alter the tags name, their values and again put them in target.

regards

Anupam

former_member188791
Participant
0 Kudos

Hi Anupam,

Thank you for your response.

1. I am using PI7.1

Source Message:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
- <!--  Inbound Message 
  --> 
- <MT_sq1 xmlns="http://swtest.com/ws" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <XMLMessage xmlns=""><IntData><tag1>Dist</tag1> <Status>E</Status> <Date>20081021</Date> <Class>A</Class></IntData></XMLMessage> 
  </MT_sq1>

Target Message

<?xml version="1.0" encoding="UTF-8"?>
<ns0:MT_sq1 xmlns:ns0="http://swtest.com/ws">
<XMLMessage>
<IntData>
<des>Dist</des> 
<Status>E</Status> 
<Date>20081021</Date> 
<Class>A</Class>
</IntData>
</XMLMessage> 
</MT_sq1>

anupam_ghosh2
Active Contributor
0 Kudos

Hi Rajiv,

From your source and target XML structures , I find this can be done using XSLT mapping only. I expected a lot of changes in source XML therefore I suggested use of java mapping earlier. Please try the following XSLT mapping.


<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>
 <xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
		<ns0:MT_sq1 xmlns:ns0="http://swtest.com/ws">
			<XMLMessage>
				<IntData>
					<xsl:for-each select="//IntData">
						<des><xsl:value-of select="tag1"></xsl:value-of></des>
						<Status><xsl:value-of select="Status"/></Status>
						<Date><xsl:value-of select="Date"/></Date> 
						<Class><xsl:value-of select="Class"/></Class> 
					</xsl:for-each>
				</IntData>
			</XMLMessage>
		</ns0:MT_sq1>		
	</xsl:template>	
</xsl:stylesheet>

This code will produce the required target XML.

regards

Anupam

former_member188791
Participant
0 Kudos

Hi Anupam,

This just for exmpale I have given XML structure as simple,but there are couple of transformation rules also I need to apply,can you suggest with DOM how I can I extract XML tags and do the trnsformation.

regards,

Rajiv

anupam_ghosh2
Active Contributor
0 Kudos

Hi Rajiv,

This is the java mapping code using DOM Parser for the same changes as per your requirement.

I have provided explanation as far as possible within the code. For more on DOM parser use, please refer to the link I posted earlier.



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.AbstractTransformation;
import com.sap.aii.mapping.api.StreamTransformation;
import com.sap.aii.mapping.api.StreamTransformationException;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;


public class AlterTagWithDOM extends AbstractTransformation{

	public void execute(InputStream in, OutputStream out)
			throws StreamTransformationException {
		try{
			
				
				// TODO Auto-generated method stub
				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();
				//creating output xml
				Element MainRoot=docOut.createElement("ns0:MT_sq1");
				MainRoot.setAttribute("xmlns:ns0","http://swtest.com/ws");
				Element child=docOut.createElement("XMLMessage");
				NodeList l=docIn.getElementsByTagName("IntData");
				int i,len=l.getLength();
				Element child1,child2=null;
				Node text;
				NodeList t;
				int j=0,jlen;
				for(i=0;i<len;++i)
				{
				  
				  child1=docOut.createElement("IntData");
				  t=l.item(i).getChildNodes();
				  jlen=t.getLength();
				  for(j=0;j<jlen;++j)
				  {
					  if(t.item(j).getNodeType()==Node.ELEMENT_NODE)
					  {
						  if(t.item(j).getNodeName().equals("tag1"))
						  {
							  //change the XML tag in target XML
							  child2=docOut.createElement("des");
						  }
						  else
						  {
							  // copy other tags as it is
							  child2=docOut.createElement(t.item(j).getNodeName());
						  }
						  //get values from each tag
						  text=docOut.createTextNode(t.item(j).getFirstChild().getNodeValue());  
						  child2.appendChild(text);
						  //add nodes to "IntData"
						  child1.appendChild(child2);
					  }
				  }
				//add "IntData" to "XMLMessage" tag
				  child.appendChild(child1);
				}
				//add  "XMLMessage" to "MT_sq1" tag
				MainRoot.appendChild(child);
				//finally write all to docOut
				docOut.appendChild(MainRoot);
				//write DOM tree to output file
				transform.transform(new DOMSource(docOut), new StreamResult(out));
				
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	public void setParameter(Map arg0) {
		// TODO Auto-generated method stub
		
	}
	public static void main(String[] args) {
		try{
		AlterTagWithDOM genFormat=new AlterTagWithDOM();
		FileInputStream in=new FileInputStream("C:\\Apps\\my folder\\sdn\\split.xml");
		FileOutputStream out=new FileOutputStream("C:\\Apps\\my folder\\sdn\\split_dom.xml");
		genFormat.execute(in,out);
		}
		catch(Exception e)
		{
		e.printStackTrace();
		}
		}

	public void transform(TransformationInput arg0, TransformationOutput arg1)
	throws StreamTransformationException {
// TODO Auto-generated method stub
		this.execute(arg0.getInputPayload().getInputStream(), arg1.getOutputPayload().getOutputStream());
}
}

regards

Anupam

former_member188791
Participant
0 Kudos

Hi Anupam,

Thanks for your code.

Regards,

Rajiv

former_member188791
Participant
0 Kudos

Hi Anupam,

Your code is not working when the incoming tags are blank/empty.

for example:

In the below src message tag1 is coming as blank then it is throwing error,

In my requirements couple of src tags coming as blank in the mapping i am filling the values for ex: in tag1 I will map it to

datatime stamp.

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
- <!--  Inbound Message 
  --> 
- <MT_sq1 xmlns="http://swtest.com/ws" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <XMLMessage xmlns=""><IntData><tag1></tag1> <Status>E</Status> <Date>20081021</Date> <Class>A</Class></IntData></XMLMessage> 
  </MT_sq1>

Can you please help me.

Regards,

Rajiv

anupam_ghosh2
Active Contributor
0 Kudos

Hi Rajiv,

I wrote above code because i thought elements are mandatory. I should have been more careful while writing the code. Extremely sorry, because of my carelessness, you faced troubles in running the code.

Here is the code you can try which takes care of empty node values.


 
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.AbstractTransformation;
import com.sap.aii.mapping.api.StreamTransformation;
import com.sap.aii.mapping.api.StreamTransformationException;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;


public class AlterTagWithDOM extends AbstractTransformation{

	public void execute(InputStream in, OutputStream out)
			throws StreamTransformationException {
		try{
			
				
				// TODO Auto-generated method stub
				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();
				//creating output xml
				Element MainRoot=docOut.createElement("ns0:MT_sq1");
				MainRoot.setAttribute("xmlns:ns0","http://swtest.com/ws");
				Element child=docOut.createElement("XMLMessage");
				NodeList l=docIn.getElementsByTagName("IntData");
				int i,len=l.getLength();
				Element child1,child2=null;
				Node text;
				NodeList t;
				int j=0,jlen;
				for(i=0;i<len;++i)
				{
				  
				  child1=docOut.createElement("IntData");
				  t=l.item(i).getChildNodes();
				  jlen=t.getLength();
				  for(j=0;j<jlen;++j)
				  {
					  if(t.item(j).getNodeType()==Node.ELEMENT_NODE)
					  {
						  if(t.item(j).getNodeName().equals("tag1"))
						  {
							  //change the XML tag in target XML
							  child2=docOut.createElement("des");
						  }
						  else
						  {
							  // copy other tags as it is
							  child2=docOut.createElement(t.item(j).getNodeName());
						  }
						  //get values from each tag
						  if(t.item(j).hasChildNodes())
						  {
							  text=docOut.createTextNode(t.item(j).getFirstChild().getNodeValue());  
							  child2.appendChild(text);
						  }	  
						  //add nodes to "IntData"
						  child1.appendChild(child2);
					  }
				  }
				//add "IntData" to "XMLMessage" tag
				  child.appendChild(child1);
				}
				//add  "XMLMessage" to "MT_sq1" tag
				MainRoot.appendChild(child);
				//finally write all to docOut
				docOut.appendChild(MainRoot);
				//write DOM tree to output file
				transform.transform(new DOMSource(docOut), new StreamResult(out));
				
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	public void setParameter(Map arg0) {
		// TODO Auto-generated method stub
		
	}
	public static void main(String[] args) {
		try{
		AlterTagWithDOM genFormat=new AlterTagWithDOM();
		FileInputStream in=new FileInputStream("C:\\Apps\\test\\split.xml");
		FileOutputStream out=new FileOutputStream("C:\\Apps\\test\\split1.xml");
		genFormat.execute(in,out);
		}
		catch(Exception e)
		{
		e.printStackTrace();
		}
		}

	public void transform(TransformationInput arg0, TransformationOutput arg1)
	throws StreamTransformationException {
// TODO Auto-generated method stub
		this.execute(arg0.getInputPayload().getInputStream(), arg1.getOutputPayload().getOutputStream());
}
}

Input xml structure split.xml


<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
 <MT_sq1 xmlns="http://swtest.com/ws" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <XMLMessage xmlns=""><IntData><tag1></tag1> <Status>E</Status> <Date>20081021</Date> <Class>A</Class></IntData></XMLMessage> 
  </MT_sq1>

Output structure split1.xml


<?xml version="1.0" encoding="UTF-8"?><ns0:MT_sq1 xmlns:ns0="http://swtest.com/ws"><XMLMessage><IntData><des/><Status>E</Status><Date>20081021</Date><Class>A</Class></IntData></XMLMessage></ns0:MT_sq1>

regards

Anupam

former_member188791
Participant
0 Kudos

Hi Anupam,

Thank you for your cdoe!its working now.

One more query,in my source file tag1 coming as blank,I need to set this to time stamp (des node) in the target.I tried with setTextContent but its not working,how I can change any particular node value .

Regards,

Rajiv

anupam_ghosh2
Active Contributor
0 Kudos

Hi Rajiv,

In this code i have added the feature that if "tag1" node is blank then I am putting current timestamp in the "des" node in the target XML. You can follow this approach and reset any value as per your choice.Java mapping can solve any mapping problem however complicated it seems.


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Timestamp;
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.AbstractTransformation;
import com.sap.aii.mapping.api.StreamTransformation;
import com.sap.aii.mapping.api.StreamTransformationException;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;


public class AlterTagWithDOM extends AbstractTransformation{

	public void execute(InputStream in, OutputStream out)
			throws StreamTransformationException {
		try{
			
				
				// TODO Auto-generated method stub
				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();
				//creating output xml
				Element MainRoot=docOut.createElement("ns0:MT_sq1");
				MainRoot.setAttribute("xmlns:ns0","http://swtest.com/ws");
				Element child=docOut.createElement("XMLMessage");
				NodeList l=docIn.getElementsByTagName("IntData");
				int i,len=l.getLength();
				Element child1,child2=null;
				Node text;
				NodeList t;
				int j=0,jlen;
				for(i=0;i<len;++i)
				{
				  
				  child1=docOut.createElement("IntData");
				  t=l.item(i).getChildNodes();
				  jlen=t.getLength();
				  for(j=0;j<jlen;++j)
				  {
					  if(t.item(j).getNodeType()==Node.ELEMENT_NODE)
					  {
						  if(t.item(j).getNodeName().equals("tag1"))
						  {
							  //change the XML tag in target XML
							  child2=docOut.createElement("des");
							  
						  }
						  else
						  {
							  // copy other tags as it is
							  child2=docOut.createElement(t.item(j).getNodeName());
						  }
						  //get values from each tag
						  if(t.item(j).hasChildNodes())
						  {
							  text=docOut.createTextNode(t.item(j).getFirstChild().getNodeValue());  
							  child2.appendChild(text);
						  }
						  else
						  {
							  if(t.item(j).getNodeName().equals("tag1"))
							  {
								  //getting current time in case of blank values
								  String s=new Timestamp(new java.util.Date().getTime()).toString();
								  text=docOut.createTextNode(s);  
								  child2.appendChild(text);
							  }
						  }
						  //add nodes to "IntData"
						  child1.appendChild(child2);
					  }
				  }
				//add "IntData" to "XMLMessage" tag
				  child.appendChild(child1);
				}
				//add  "XMLMessage" to "MT_sq1" tag
				MainRoot.appendChild(child);
				//finally write all to docOut
				docOut.appendChild(MainRoot);
				//write DOM tree to output file
				transform.transform(new DOMSource(docOut), new StreamResult(out));
				
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	public void setParameter(Map arg0) {
		// TODO Auto-generated method stub
		
	}
	public static void main(String[] args) {
		try{
		AlterTagWithDOM genFormat=new AlterTagWithDOM();
		FileInputStream in=new FileInputStream("C:\\Apps\\test\\split.xml");
		FileOutputStream out=new FileOutputStream("C:\\Apps\\test\\split1.xml");
		genFormat.execute(in,out);
		}
		catch(Exception e)
		{
		e.printStackTrace();
		}
		}

	public void transform(TransformationInput arg0, TransformationOutput arg1)
	throws StreamTransformationException {
// TODO Auto-generated method stub
		this.execute(arg0.getInputPayload().getInputStream(), arg1.getOutputPayload().getOutputStream());
}
}

output xml


<?xml version="1.0" encoding="UTF-8"?><ns0:MT_sq1 xmlns:ns0="http://swtest.com/ws"><XMLMessage><IntData><des>2011-10-17 10:57:11.584</des><Status>E</Status><Date>20081021</Date><Class>A</Class></IntData></XMLMessage></ns0:MT_sq1>

Regards

Anupam