Skip to Content
Technical Articles
Author's profile photo Alexander Bundschuh

PI REST Adapter – JSON to XML conversion

This blog is part of a collection of blog entries that shows architectural concepts and configuration of the SAP PI REST Adapter. We also added some sample scenarios to make it easier for you to understand how your scenario can be implemented using the PI REST Adapter.

If you haven’t done so far, best is to start with the very first blog PI Rest Adapter – Don’t be afraid within the blog series covering the concepts of the REST adapter. A complete list of all blog entries can be accessed from here PI REST Adapter – Blog Overview.

The current blog shows you along a sample scenario how to convert JSON to XML format and vice versa.

Scenario

A travel agency likes to gather flight details from an airline calling the remote function module BAPI_FLIGHT_GETDETAIL, and expose this interface as RESTful service. The format of the RESTful service should be JSON and hence needs to be converted into XML format before mapped to the BAPI structure.

In the SAP Process Integration Designer perspective of the NetWeaver Developer Studio (NWDS), I have defined an Integration Flow with a REST sender channel, an operation mapping that maps the outbound XML format into the BAPI structure, and an RFC receiver adapter. The conversion from JSON to XML is done within the REST sender adapter.

01_01 Integration Flow.png

In the following, let’s focus on how the sender adapter needs to be configured.

Configuring the REST sender adapter

Double-click on the sender channel of type REST, and switch to the General tab below the Adapter-Specific tab. As data format of the input message choose JSON from the drop down menu. Within PI, the format of the payload needs to be XML, so select the Convert to XML check-box.

A sample JSON input message looks as follows:

{

    “Agency”: “110”,

    “FlightDetails”: {

          “AirlineID”: “LH”,

          “ConnID”: “0400”,

          “Date”: “2014-09-13”

    },

}

The two JSON elements Agency and FlightDetails are both on the very first level of hierarchy which is allowed for JSON however not for XML. XML messages can have one root element only. If the JSON payload is converted into XML, this would not comply with the XML specification. So, we need to add a wrapper root element to the converted XML structure. As Element Name and Element Namespace we enter the name and namespace of the message type of our outbound service interface, here flight_query with namespace http://demo/hh/rest/flights.

The scenario runs synchronously, so select Best Effort from the drop down menu of the Quality of Service.

The response of the BAPI call is in XML format within PI, the agency however expects the response being in JSON format. So, we choose JSON as data format of the output message, and select the check box Convert XML Payload to JSON. Furthermore we select the Strip Outer Element check box to remove the message type element from the XML payload.

01_02 General.png

Switch to tab Channel Selection, and select the Specify Endpoint check box. As custom static endpoint enter /demo/flight.

01_03 Channel Selection.png

Switch to the REST Resources tab. Here, we stick to a static endpoint URL, so we just enter / as pattern.

01_04 REST Resources.png

Running the scenario

For testing the scenario you can use the Advanced REST Client Application in the Google Chrome browser. The endpoint URL of your RESTful service starts with http://<host>:<port>/RESTAdapter with host and port of the SAP PI system, followed by what you have defined in the sender channel, here /demo/flight.

Enter a sample JSON payload like the one above, and select the Send button.

01_05 Browser Request.png

The response of the service call provides the flight details such as destinations and schedule in JSON format.

01_06 Browser Response.png

In message monitoring, you can download the payload of the request and response assuming that you have switched on logging. You can see that for the request message the wrapper element, i.e., the message type element has been added.

01_07 XML Request.png

The response in XML format also contains the message type as root element which is then removed when converted into JSON.

01_08 XML Response.png

Further XML/JSON conversion rules

From release 7.31 SP17 / 7.4 SP13 / 7.5 SP01 onwards, further XML to JSON conversion rules are supported, see Converting XML/JSON – Advanced Adapter Engine – SAP Library. You can define so called custom XML/JSON conversion rules to overrule the automatic conversion in cases where the result is not as expected, such as forcing an arraytype although an item occurs only once, or changing the data type of an element.

In our specific case, we like to change the message format of the response as follows:

  • We like to keep the outer root element, and add a prefix to the same
  • The flight element should always be of type array even if it occurs only once
  • The connection ID should be of type integer (as you can see above it is interpreted as string)
  • The arrival time should be of type decimal; if the conversion fails, a default value should be set
  • The duration should be of type string (as you can see above it is interpreted as integer)

So, in the channel configuration, we add the following rules:

  • Select the Enable Namespace Mapping check box, and add a new rule. Here, as XML Namespace set http://demo/hh/rest/flights, and as value we simply enter the term Prefix.
  • In the Custom XML/JSON Conversion Rules section, add a new rule to define the flight root element as array in any case. Maintain namespace and prefix as seen above in the xml schema, as name set the element name flight, and as array type choose yes. Alternatively, you can also choose 1 or true.
  • Add another rule with name ConnID and type integer
  • Add another rule with name arrivalTime and type decimal, as default set 12.00 (note, this doesn’t make any sense but I just like to showcase you the default option)
  • Add another rule with name duration and type string

 

01 Config of response.png

 

If you run the scenario again, the response looks as follows. The respective configuration settings and their impact on the response are highlighted in the corresponding color.

02 Chrome.png

I hope this blog was helpful to understand the JSON conversion capabilities of the SAP PI REST adapter. If you like to learn more, check out the other blogs in the series, accessible from the main blog PI REST Adapter – Blog Overview.

Assigned Tags

      24 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo ZiYu Ruan
      ZiYu Ruan

      Hi,

      We use REST Receiver and convert XML payload to JSON on data format.
      If the data has more than 2 records, the data format would be as the following,
      {"data":[{"id":"s123","types":11},{"id":"s456","types":22}]}

      If the data has only one record, the data format would be as the following,
      {"data":{"id":"s123","types":11}}

      But our customer's inbound system has to receive the data format, when the data has only one record, as the following,
      {"data":[{"id":"s123","types":11}]}
      To compare with current format, the array sign, [], is need.

      Please help.Thanks.

      Author's profile photo Former Member
      Former Member

      Hi ZiYu,

      I am facing the same issue for single record and unable to find any info to add Array sign in REST receiver adapter. were you able to resolve the same?

      Kindly let me know.

      Author's profile photo Former Member
      Former Member

      Hi both,

       

      There’s a solution to this now: enhanced XML/JSON conversion, also mentioned in the update of this blog above under Further XML/JSON conversion rules. And also see here: https://blogs.sap.com/2016/01/13/rest-adapter-in-sap-pipo-enhanced-xmljson-conversion/

       

      Philippe

      Author's profile photo Former Member
      Former Member

      Alex, this is amazing !

      Author's profile photo Former Member
      Former Member

      We struggle 2 problem from customer. When REST adapter convert XML to JSON format , it should refer XSD definition about xml element occurrence, for example above ZiYu 's sample  {"data":[{"id":"s123","types":"11"}]}, element "data" we define to 1..unbounded , so "data" element have to convert [ ] for array , no matter there is the single array or multiple value of array. So the result will be the following JSON format :

      {"data":[{"id":"s123","types":"11"}]}

      And REST adapter has the other issue ,for example the above JSON, if we had define "types" element to xsd:string , cause REST wo't refer XSD definition , so the result convert to integer , {"data":{"id":"s123","types":11}}

      That's we found the 2 issues.

      Author's profile photo Former Member
      Former Member

      Hi Gwendolyn.

      We also saw the "11"--->11 convertion problem. Do you know if there is already a solution for that?

      Author's profile photo Former Member
      Former Member

      Hi,

      I am facing same issue of conversion String as Number just because only numbers or decimal in string. Some clues?

      Author's profile photo Former Member
      Former Member

      Nop. We decided to replace the calls to REST services that had input parameters, with java apps exposed as web services.

      Author's profile photo Khaja Sk
      Khaja Sk

      hello,

      for converting XML like this  ...

      <CalculationBaseQuantity unitCode="KG">1</CalculationBaseQuantity>

      how should be my source JSON format?


      Author's profile photo Former Member
      Former Member

      Hello Alex
      Thanks for writing such descriptive blog, i was able to do my conversion using this and tested several scenarios.
      I am facing an issue with a scenario where target system is expecting content type as application/json but Receiver REST adapter with data format as JSON always send the content type as text/plain.

      I tried using custom modules but found no way to deactivate the conversion in REST adapter.

      To overcome this issue one of the following 2 options should work:

      1) To deactivate Data Format conversion ; pls. confirm if I can do this
      2) Change the content type of payload via REST adapter ; pls. confirm if I can do this

      I am on PI 7.4 SP 14

      Thanks
      Lalit

      Author's profile photo Jürgen Döbbeler
      Jürgen Döbbeler

      Thanks for this great blog. We've got rid of all problems except the custom Rules for mapping. We have 7.40 SP13 but there is no table to maintain the custom mapping rules. Do we have to configure something in addition?

      Author's profile photo Alexander Bundschuh
      Alexander Bundschuh
      Blog Post Author

      Best guess is that you missed to upload the adapter metadata.

      Alex

      Author's profile photo Former Member
      Former Member

      HI Alexander,

       

      I am having issue with my Sender REST adapter. My requirement is i will be getting a HTTP GET request with 3 variables in the calling URL.

      I have defined the REST Resources tab with URL Pattern as '/' and setting the custom attribute using the GET variable.

      I am getting issues in retreiving the Dynamic attributes . I cannot see the values in the Runtime as well.

      Below are the configuration and JAVA UDF.

      Displaying image001.png

      JAVA code of UDF

      Displaying image002.png

      The Dynamic attributes do not show the custom attributes i have defined

      Displaying image003.png

       

      Would appreciate if you could help me .

      Thanks

      Husain

      Author's profile photo chuhao zhu
      chuhao zhu

      HI Alexander,

      I'm having issue with data format in receiver REST adapter which convert XML data to JSON to the external system.It is a string element "remark" valued "abc\ndef" in the payload,but it turned to "adb\\ndef" when the target system gets it. How can i avoid the escape character and just regard '\n' as a pure string?

      Would appreciate if you could help me.

      Thanks.

      Author's profile photo Former Member
      Former Member

      Hi All,

      I have a scenario (REST–>PI–>REST) wherein PI will receive the data from sender in JSON format. Data format accepted by receiver is also a JSON format.

      The input payload to PI looks like:

      [{
      “ClassCode”: “”,
      “FSAC”: “”,
      “TrainId”: “”,
      “UserId”: “”,
      “Equipment”: [{
      “EquipmentInitials”: “”,
      “EquipmentNumber”: “”,
      “EquipmentDisplayType”: ” “,
      “SourceId”: “”,
      “SourceType”: “”
      }, {
      “EquipmentInitials”: “”,
      “EquipmentNumber”: “”,
      “EquipmentDisplayType”: ” “,
      “SourceId”: “”,
      “SourceType”: “”
      }]

      }]

      When this input is passed to receiver Rest Adapter, I see that PI append root to it which is not acceptable by REST Service.

      JSON at receiver adapter looks like below:

      {
      “root”: [{
      “ClassCode”: “”,
      “FSAC”: “”,
      “TrainId”: “”,
      “UserId”: “”,
      “Equipment”: [{
      “EquipmentInitials”: “”,
      “EquipmentNumber”: “”,
      “EquipmentDisplayType”: ” “,
      “SourceId”: “”,
      “SourceType”: “”
      }, {
      “EquipmentInitials”: “”,
      “EquipmentNumber”: “”,
      “EquipmentDisplayType”: ” “,
      “SourceId”: “”,
      “SourceType”: “”
      }]

      }]
      }

      How to ignore this root element and add outer Array[], similar to the input payload.

      Thanks in advance!!

      Best Regards,

      Sachin Jangir

       

       

       

       

      Author's profile photo Former Member
      Former Member

      Hi Sachin,

      I have the same problem. How do you solve this issue?

      Thanks in advance!

      Best Regards,

      Daniel Lafuente

       

      Author's profile photo Former Member
      Former Member

      have you guys slove this? I have the same problem now.

      Author's profile photo Neil Chan
      Neil Chan

      I have achived it.

      please check:

      REST remove root JSON tag in receiver channel

      https://answers.sap.com/questions/454329/rest-remove-root-json-tag-in-receiver-channel.html?childToView=456034&answerPublished=true

      Author's profile photo Marcus Hussong
      Marcus Hussong

      Hi,

       

      have the same problem. Have you solved this?

      Author's profile photo KARUNAKAR ADAPA
      KARUNAKAR ADAPA

      Hi Alexander,

      i am doing REST adapter Synchronous (REST<–>PI<–>RFC) my scenario working fine. But am facing one issue in chrome i am getting below Waring/error, but response populating correct.

      Thanks in Advance for your help.

      Best Regards,

      Karunakar A

      Author's profile photo KARUNAKAR ADAPA
      KARUNAKAR ADAPA

      Hi Expert,

      I am REST adapter synchronous scenario I am getting csv format response from the target system.

      Please guide me how I can receive csv format data in synchronous call using REST adapter.

      Thanks in Advance for your help.

       

      Author's profile photo Charles Clinton Tan
      Charles Clinton Tan

      Hi,

      I would like to know how can I define the Data Type in SAP PO ESR to accept incoming JSON file having Array as top level object. I will use REST sender adapter for this. What I know is that if there's an element above this Array, REST adapter can easily read that element will have multiple occurrences.

      [
      {
      "shipment_number": "473747834", // String
      "completedsuccessfully": true, // Boolean
      "ProcessingEndtime": "2021-01-29T09:52:14.616Z" // UTC timestamp
      },
      {
      "shipment_number": "798798797", // String
      "completedsuccessfully": false, // Boolean
      "ProcessingEndtime": "2021-01-29T09:52:14.616Z" // UTC timestamp
      }
      ]

       

      Author's profile photo Alexander Bundschuh
      Alexander Bundschuh
      Blog Post Author

      Hi Charles,

      actually you need to create a data type with root element and when converting the incoming JSON to XML add the root element, this can be configured in the REST sender channel

      Alex

      Author's profile photo Jens Schwendemann
      Jens Schwendemann

      Hi Alex,

      I seem to be a little late for the REST / JSON party as this blog now is now entering primary school age 🙂

      Anyways I recently had some requirements to consume various REST APIs from SAP Backend via PI / PO (7.50 SP13 in our case).

      While it is understandable that "Enable Namespace Mapping" using dot "." a separator for prefix (Prefix.flight :... in your example) by default, is there also a parameter / setting so to change this, say to ":" or completely omit it?

      Searched a whole lot in the community and within notes but could not find an easy solution for this.

       

      Thanks / Cheers

      Jens