Here is some data.


Jack & Jill went up < the hill.



A program which comply with W3C standard will produce below XML.


<root>
  <who>Jack &amp; Jill</who>
  <where>went up &lt; the hill.</where>
</root>



Why & and < are represented as &amp; and &lt;?

     If they are not represented that way (escaped), then it is difficult (if not impossible) to write a generic program logic to parse the XML or convert XML back to text. W3C has reserved < > & ‘ “ as Predefined Entities. These characters needs to be escaped in a well-formed XML.

Let’s say a program does not obey this rule. It produces


<root>
  <who>Jack & Jill</who>
  <where>went up < the hill.</where>
</root>



     This is not a well-formed XML. It will fail in message mapping with error “Character reference “&xxxxx” is an invalid XML character”. Common issue on SCN, “handling special character in XML in message mapping”. Graphical message mapping, XSLT, DOM, SAX can’t handle this XML.

It is highly recommended to request the sender system, to fix the code and generate well-formed XML.

     In most cases, & is not escaped. If < is not escaped, it is very default to handle. Java mapping can be used to produce well-formed XML. Note: Generic program logic is difficult, as & is Predefined Entity. Tailor below solution as needed.

Solution:-

Download the payload and save it with .txt extension. Open the payload with foxe or notepad++. Check the element where mapping threw error message. Determine the XML is not well-formed.

Implement below Java mapping before message mapping. i.e., select below Java mapping and then your message mapping in operational mapping.


package com.javaMapping;
import java.io.*;
import com.sap.aii.mapping.api.*;
public class WellformedXML_JavaMapping extends AbstractTransformation {
    @Override
    public void transform(TransformationInput transformationInput, TransformationOutput transformationOutput) throws StreamTransformationException {
        try {
            InputStream inputstream = transformationInput.getInputPayload().getInputStream();
            OutputStream outputstream = transformationOutput.getOutputPayload().getOutputStream();
            // a) Copy Input content to String
            byte[] b = new byte[inputstream.available()];
            inputstream.read(b);
            String inputContent = new String(b);
            // b) Replace all & with &amp; Use this when every & in input is not escaped as &amp;
            inputContent = inputContent.replaceAll("&", "&amp;");
            // Use this when a few & are escaped as &amp; and a few & are not escaped. This logic will avoid &amp; to become &amp;amp;
            //inputContent = inputContent.replaceAll("&amp;", "____someTEXT_____").replaceAll("&", "&amp;").replaceAll("____someTEXT_____", "&amp;");
        
            outputstream.write(inputContent.getBytes());
        } catch (Exception exception) {
            getTrace().addDebugMessage(exception.getMessage());
            throw new StreamTransformationException(exception.toString());
        }
    }
}


FYI. If there is no codepage value for a character, encoding program will represent them in HTML-code. Example, € will be represented as € and š will be represented as š in ISO8859-1. This is valid representation and will not fail in message map. If there are stray & which needs to be replaced, please try below logic.

inputContent = inputContent.replaceAll(“&#”, “____someTEXT_____”).replaceAll(“&”, “&amp;”).replaceAll(“____someTEXT_____”, “&#”);

To report this post you need to login first.

8 Comments

You must be Logged on to comment or reply to a post.

  1. Yvonne Jean Martinez

    We  had an issue like this in my previous project. We also ended up using java mapping to replace the special characters which were from another language. Thanks for this post.

    (0) 
  2. Manoj K

    Hi Raghu,

    I tried using ‘&’ and ‘<‘ using in my message mapping and it was successfully executed without any error.(PI 7.31-dual stack)

    Capture.PNG

    Just want to know if in case if you get any error why do we need to go for Java mapping , we can just simply handle this by simple UDF to replace.

    and one more thing if you write java mapping for replacing ‘<‘ then it may cause error also because

    inputContent = inputContent.replaceAll(“<“, “&lt”);    will replace  XML tags too if i am not wrong.


    like <fname> will be replaced by &ltfname&lt.



    It may be a dumb question also , as i am newbie to PI and Java mapping  got these doubt’s, so need some clarification.


    Br,

    Manoj

    (0) 
    1. Raghu Vamseedhar Reddy KadipiReddy Post author

      Ambuj,

      If source system sends ‘not well-formed XML’ to PI, it has to be handled in Java Mapping. We have to manipulate that XML in Java Mapping and use it in next step (graphical mapping OR sending it to target system). If required, we can add CDATA in Java Mapping, but it will be difficult to handle it in next step.

      (0) 
      1. Anoop Rai

        Hi Raghu, I have a problem, when we are trying to send ‘not well-formed XML’ to PI via SOAPUI, it can’t able to reach till PI. I tried Java Mapping for File-to-File Scenario, its working perfectly, but in case of SOAP-to-File its not work at all. Can you please suggest some solution for it?

        (0) 

Leave a Reply