on 12-13-2011 9:00 AM
PI File adapter has a processing option u2018Empty-Message Handlingu2019 to ignore or Write Empty Files. In case there is no data created after mapping on target side then this option determines whether to write an empty file or not. But there is a catch to this option when it comes to using it with File Content Conversion which is described in SAP Note u2018821267u2019. It states following:
I configure the receiver channel with File content conversion mode and I set the 'Empty Message Handling' option to ignore. Input payload to the receiver channel is generated out of mapping and it does not have any record sets. However, this payload has a root element. Why does file receiver create empty output file with zero byte size in the target directory? Example of such a payload generated from mapping is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<ns1:test xmlns:ns1="http://abcd.com/ab"></ns1:test>
solution :
If the message payload is empty (i.e., zero bytes in size), then File adapter's empty message handling feature does NOT write files into the target directory. On the other hand, if the payload is a valid XML document (as shown in example) that is generated from mapping with just a root element in it, the File Adapter does not treat it as an empty message and accordingly it writes to the target directory. To achieve your objective of not writing files (that have just a single root element) into the target directory, following could be done:
Using a Java or ABAP Mapping in order to restrict the creation of node itself during mapping. (This cannot be achieved via Message Mapping)
Using standard adapter modules to do content conversion first and then write file.
can someone help with java mapping that can be used in this case?
Hi,
>>>> if the payload is a valid XML document (as shown in example) that is generated from mapping with just a root element in it, the File Adapter does not treat it as an empty message and accordingly it writes to the target directory
In your message mapping itself check if there is no source payload then do not create the root element i.e. <ns1:test>. If the payload exists then only create root.
>> to restrict the creation of node itself during mapping. (This cannot be achieved via Message Mapping)
If you're trying to restrict the creation of root node (If I'm not wrong) , you can restrict the creation of target messagetype in the messagemeppiang only by changing its minimum occurrence to zero.
Regards,
Priyanka
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
You have not mentioned the version of PI you are working in. In case you are working with PI 7.1 or above then here is the java mapping code you need to add after message mapping in the same interface mapping
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 com.sap.aii.mapping.api.AbstractTransformation;
import com.sap.aii.mapping.api.StreamTransformationException;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;
public class RemoveRootNode extends AbstractTransformation{
public void execute(InputStream in, OutputStream out)
throws StreamTransformationException {
// TODO Auto-generated method stub
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();
if(docIn.getDocumentElement().hasChildNodes())
{
docOut.appendChild(docOut.importNode(docIn.getDocumentElement(),true));
transform.transform(new DOMSource(docOut), new StreamResult(out));
}
else
{
out.write(null);
}
}
catch(Exception e)
{
}
}
public void setParameter(Map arg0) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
RemoveRootNode genFormat=new RemoveRootNode();
FileInputStream in=new FileInputStream("C:\\apps\\sdn\\rootNode.xml");
FileOutputStream out=new FileOutputStream("C:\\apps\\sdn\\rootNode1.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());
}
}
In case you are working in PI 7.0 you can use this code
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 com.sap.aii.mapping.api.StreamTransformation;
import com.sap.aii.mapping.api.StreamTransformationException;
public class RemoveRootNode implements StreamTransformation{
public void execute(InputStream in, OutputStream out)
throws StreamTransformationException {
// TODO Auto-generated method stub
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();
if(docIn.getDocumentElement().hasChildNodes())
{
docOut.appendChild(docOut.importNode(docIn.getDocumentElement(),true));
transform.transform(new DOMSource(docOut), new StreamResult(out));
}
else
{
out.write(null);
}
}
catch(Exception e)
{
}
}
public void setParameter(Map arg0) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
RemoveRootNode genFormat=new RemoveRootNode();
FileInputStream in=new FileInputStream("C:\\apps\\sdn\\rootNode.xml");
FileOutputStream out=new FileOutputStream("C:\\apps\\sdn\\rootNode1.xml");
genFormat.execute(in,out);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
The code for PI 7.0 should also work for PI 7.1 provided you use the right jar files for compilation, but vice-versa is not true.
Could you please let us know if this code was useful to you or not?
Regards
Anupam
Edited by: anupamsap on Dec 15, 2011 9:43 AM
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
What is root element of your source message?
Regards
Ramesh
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
The note already says it is not possible to achieve via Message Mapping
My suggestion:
1. Create a Java Mapping
Logic for your java mapping would be, search for root element,
if found generate XML as source message only
if root element is not found then return empty output
2. Then create your normal mapping (message mapping)
In this case, you will have to maintain multi level mapping for the same source and target message types
Regards
Ramesh
User | Count |
---|---|
92 | |
11 | |
10 | |
9 | |
9 | |
7 | |
6 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.