on 07-11-2016 8:42 PM
Hello Experts,
We have a requirement wherein PI should read and parse a file containing multipart data (XML + PDF or word or excel). Please let me know how this can be achieved. A file sender adapter is being used to read these files. We are using PI 7.3 SP07 dual stack.
The format of the file is as below -
<?xml version="1.0" encoding="UTF-8"?><DataResponses>------=_Part_2127_1899305384.1468004618403
content-type:text/xml;charset=UTF-8
content-length:5379
content-id:<1468004618403.1561744870@app252.snv.ariba.com>
<cXML>
*****Data here****
</cXML>
------=_Part_2127_1899305384.1468004618403
content-type:application/pdf
content-length:44519
content-id:<574015246.1468004531063@cxml.org>
content-disposition:attachment;filename="Test Attachement DOc.pdf"
%PDF-1.5
%����
1 0 obj
<</Type/Catalog/Pages 2 0 R/Lang(en-US) /StructTreeRoot 13 0 R/MarkInfo<</Marked true>>>>
endobj
2 0 obj
<</Type/Pages/Count 1/Kids[ 3 0 R] >>
endobj
3 0 obj
<</Type/Page/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 7 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/MediaBox[ 0 0 612 792] /Contents 4 0 R/Group<</Type/Group/S/Transparency/CS/DeviceRGB>>/Tabs/S/StructParents 0>>
endobj
4 0 obj
<</Filter/FlateDecode/Length 878>>
stream .......................................................
Hi Suraj,
You can write a java map to parse the file and create multiple outputs of this data(same as multi-mapping). But that will depend on how you want to process the parsed content in receiver side. If you can provide more information on what your requirement is on the receiver end it will be better easy to provide a more detailed solution.
Regards,
Sanjeev.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks Sanjeev!
The XML tags of parsed content need to be mapped to target XML tags (this is already in place except for the pdf content) and the pdf needs to be mapped as a base64binary format in the same target XML in another tag. Please let me know how this can be achieved using Java mapping. Also provide sample code or some links if possible.
Thanks
Suraj,
You can use the below code to convert the attachment-PDF to Base64binary
String Content = "";
byte[] bt;
String AttachmentID ="";
GlobalContainer globalContainer = container.getGlobalContainer();
InputAttachments inputAttachments = globalContainer.getInputAttachments();
if(inputAttachments.areAttachmentsAvailable())
{
Collection<String> CollectionIDs = inputAttachments.getAllContentIds(true);
Object[] arrayObj = CollectionIDs.toArray();
int attachmentCount = arrayObj.length;
for(int i =0;i<attachmentCount;i++)
{
AttachmentID =(String) arrayObj[i];
Attachment attachments =inputAttachments.getAttachment(AttachmentID);
Content = Content + attachments.getBase64EncodedContent();
}
}
return Content;
And make sure u have marked Read attachment in OM.
Br,
Manoj
Hi Suarj,
Here is sample code I could create in between my work:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
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 parseMultiPartData extends AbstractTransformation{
/**
* @param args
*/
public void transform(TransformationInput arg0, TransformationOutput arg1) throws StreamTransformationException {
// TODO Auto-generated method stub
this.execute(arg0.getInputPayload().getInputStream(), arg1.getOutputPayload().getOutputStream());
}
public void execute(InputStream arg0, OutputStream arg1)
throws StreamTransformationException {
try {
String output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
// InputStream in = arg0;//.getInputPayload().getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(arg0));
StringBuilder out = new StringBuilder();
String line = reader.readLine();
while(line != null)
{
out.append(line + "\n");
line = reader.readLine();
}
String fileContent = "";
fileContent = out.toString();
int fileLength = fileContent.length();
if(fileLength > 0)
{
int XMLStartIndex = fileContent.indexOf("<cXML>");
int XMLEndIndex = fileContent.indexOf("</cXML>");
String multipartContent = fileContent.substring(fileContent.indexOf("<DataResponses>")+15,fileContent.indexOf("content-type:text/xml;charset=UTF-8")-1);
output += fileContent.substring(XMLStartIndex, XMLEndIndex);
int SecondMultiPart = fileContent.lastIndexOf(multipartContent);
// System.out.println(fileContent.substring(SecondMultiPart + multipartContent.length(), fileContent.length()));
output += "<newTag>" + fileContent.substring(SecondMultiPart + multipartContent.length(), fileContent.length()) + "</newTag>";
}
output += "</cXML>";
arg1.write(output.getBytes());
}
catch(Exception e){
throw new StreamTransformationException(e.toString());
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
InputStream in = new FileInputStream(new File("C:\\Users\\Desktop\\Input.txt"));
OutputStream out = new FileOutputStream(new File("C:\\Users\\Desktop\\output.xml"));
parseMultiPartData myMapping = new parseMultiPartData();
myMapping.execute(in , out);
} catch (Exception e) {
e.printStackTrace();
}
}
}
It will read the content that you provided above and find the cXML content and add a new tag (newTag) in the cXML and then output the data as a single message.
Sample output is below:
<?xml version="1.0" encoding="UTF-8"?><cXML>
*****Data here****
<newTag>
content-type:application/pdf
content-length:44519
content-id:<574015246.1468004531063@cxml.org>
content-disposition:attachment;filename="Test Attachement DOc.pdf"
%PDF-1.5
%����
1 0 obj
<</Type/Catalog/Pages 2 0 R/Lang(en-US) /StructTreeRoot 13 0 R/MarkInfo<</Marked true>>>>
endobj
2 0 obj
<</Type/Pages/Count 1/Kids[ 3 0 R] >>
endobj
3 0 obj
<</Type/Page/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 7 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/MediaBox[ 0 0 612 792] /Contents 4 0 R/Group<</Type/Group/S/Transparency/CS/DeviceRGB>>/Tabs/S/StructParents 0>>
endobj
4 0 obj
<</Filter/FlateDecode/Length 878>>
stream .......................................................
</newTag></cXML>
Please note, it's not an optimized code and you will need to perform some more work to get the PDF content etc.
Hope this helps.
Regards,
Sanjeev.
Thanks Sanjeev!
I am new to Java, so did not understand if I have to add anything more or this code should work as it is? Also will this code work for multiple parts if more than one documents are being attached to the cXML? Does it also convert the attachments part to base64binary format?
Thanks for your help!
Hi Suraj,
I had written code looking at the sample that you had provided. If the data is going to be in same file but with multiple content parts, then you will need to modify the above logic accordingly.
Regarding the conversion to base64binary format, you can use the code from here:
http://javarevisited.blogspot.com.au/2012/02/how-to-encode-decode-string-in-java.html
You will need to import the jars though.
Else, if there are going to be more than 1 file (1 for XML, 1 for pdf etc..), you will have to read those files as additional file in sender channel and then parse the data as per the code provided by Manoj.
BTW, logic that I have used above is to get the index of the elements from where I would need the data from and then got the content from that point onward.
Regards,
Sanjeev.
What about
?
/k
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
86 | |
10 | |
10 | |
9 | |
7 | |
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.