cancel
Showing results for 
Search instead for 
Did you mean: 

XML to JSON - force Square brackets via SAP PI

vipinkumar_kanchan
Participant
0 Kudos

Hi,

One of the 3rd party systems that we integrate to needs some JSON objects to be array objects irrespective of whether one or more values are passed to it. Does SAP PI REST Adapter support this? If so how? Are there any tweaks that can be done to achieve this?

{

  "Items": [

    {

      "KDS": [

        {

          "DimRole": "Prod",

          "DimLvl": "PROD_DES",

          "DimVal": "XXOOIIRP Fibre"

        }

      ],

      "Tag": "amendments"

}

]

}

In the above Json, the object KDS is needed by the target system as an array. SAP PI by default looks at the number of KDS that are passed and if there are only 1 set, then it puts only {} around the value for the object. The target system requires that SAP PI always puts the {} as well as the [] for the value of the object.

SAP PI correctly puts both the {} and the [] around the values in case more than one KDS sets are passed and this is processed correctly by the target application.

Please help with a solution for this.

Accepted Solutions (0)

Answers (3)

Answers (3)

Former Member
0 Kudos

Hello Vipin,

In the XSD part of XML in Data Type, kindly increase the maximum occurrence of the one time occurring field beyond 1.

Note : In reality that field might occur once, however, on increasing the maximum occurrence, JSON will treat it as multiple occurrence, and hence will put [].

Please try this and let me know.

Kind Regards,

Souvik

maheswarareddykonda
Active Contributor
0 Kudos

Hi Souvik,

even i thought like you create field or subnode creates with unbounded occurrence, but current version PI 7.4 SP10 REST adapter is not able to convert as we expected...also i had contacted SAP long back..they were saying that feature and few more bugs are fixing in SP13 which is releasing in coming November.

BR,

Maheswarareddy

vipinkumar_kanchan
Participant
0 Kudos

Hi Souvik,

The occurrence in the DT is already 0 to unbounded. The issue is not about multiple items for that object, since that works perfectly. The issue is more of when a single value is passed for that object and where the 3rd party REST design is based on the principle that all objects will behave like arrays and hence they expect even single values to be encased in {} and [].

I had a discussion with Alex about this and Alex had said that this was a feature which is in the pipeline and may be released by the end of this year.

Regards,

Vipin

Former Member
0 Kudos

Hi Vipin,

Did you solve this problem already?

I'm having the exact same problem here.

Regards.

vipinkumar_kanchan
Participant
0 Kudos

Hi Caio,

We had developed a java program for an adapter module for this requirement, but that was with open source json jars. Since our customer did not want to use Open source jars we are refactoring the code based on Standard SAP json jars. This is still under dev and test so cannot say that it is working.

Basically, we are taking the output stream from the PI mapping conversion to the module and reading the objects that we need, putting them into arrays and assigning them back into the output stream. You could also try developing based on this.

If we complete our dev and test successfully, will let you know the coding that worked.

Regards,

Vipin

Former Member
0 Kudos

Hi Vipin,

We have the same issue for several REST receiver calls.

For sure we could write an AM that finds the JSON elements in question and turn them into arrays, but in the module chain all the XML to JSON conversion happens only in the RESTAdapterBean as far as I know. As this module is the adapter call itself, we cannot execute any AM behind it. If we execute before the RESTAdapterBean, we still only have the XML as payload.

How did you resolve the problem?

vipinkumar_kanchan
Participant
0 Kudos

Hi Christian,

We have not yet resolved the problem, we only had the code sample working in local NWDS for REST payloads without deploying on the server. Since SAP had said that this feature is in the pipeline and would be released later this year, we have put this on the backburner until that time.

Regards,

Vipin

Former Member
0 Kudos

Hi Vipin,

Thank you for your reply!

Too bad, that there doesn't seem to be a fix available yet. As we probably won't be able to wait for the update to be released, I am going to use the from and add the logic handle the JSON arrays there in a static way. As I saw from the comments, you were also thinking into the same direction. 🙂

vipinkumar_kanchan
Participant
0 Kudos

Hi Christian,

That way should work. We had thought of going that way, but our Customer wants to have minimum custom code and wants to utilize standard functionality only wherever possible. Hence we did not go ahead with this development.

All the Best for your development...

Do post the modified code to the community in case it will help someone else...  A Blog on the same would be interesting to read...

Regards,

Vipin

engswee
Active Contributor
0 Kudos

Yes, Christian, as mentioned by Vipin, please do share the code or blog if you have achieved it successfully. It is quite a common requirement for JSON conversion, unfortunately I haven't had time to look into enhancing my module logic for it.

All the best!

Former Member
0 Kudos

As we probably won't use this solution for too long (given that we need it for the REST adapter), I have only implemented a quick fix using jackson and static variables. This means that you have to provide the names of the elements that are to be converted in the AM parameters.

In the XML2JSONConverter.java I have added two classes. The fixJson is invoked by providing a JSON String and an object which should be replaced by an array:


    private String fixJson(String element, String toFix) throws IOException {

        ObjectMapper mapper = new ObjectMapper();

        JsonNode rootNode = mapper.readTree(element);

        change(rootNode, toFix);

    return rootNode.toString();

    }

    private void change(JsonNode parent, String fieldName) {

        if (parent.has(fieldName) && !parent.get(fieldName).isArray()) {

             JsonNode old = parent.get(fieldName);

            ((ObjectNode) parent).putArray(fieldName).add(old);

        }

        // Now, recursively invoke this method on all properties

        for (JsonNode child : parent) {

            change(child, fieldName);

        }

    }

In the generateOutput I am calling these methods after the the JSON conversion. The targetElements is a coma seperated list of elements that should be checked and converted to an array (if not already one):


if(targetElements != null){

  String[] tokens = null;

  tokens = targetElements.split(",", -1);

  for (String token:tokens){

  output = (fixJson(output,token));

  }

}

venkatagiri_gongadi
Participant
0 Kudos

Hi,

I am facing the same issue,please let me know if it is worked for you.

Thanks,

Giri

Former Member
0 Kudos

Hi Giri,

Using the method above is working fine for us. But I think meanwhile the newest SP that recently became available should include a fix for this problem as well.

former_member188791
Participant
0 Kudos

Hi Christian,

I am also facing same above issue, can you please tell me which SP version having included the above solution, if not SP update could you also please how I can use your above code and how to pass static variable.

vipinkumar_kanchan
Participant
0 Kudos

Hi Rajiv,

As per Alex, the latest support patch for PI 7.4 and 7.31 contains the standard enhancement for this issue. SP17 for 7.31 and SP13 for 7.4. Check note 2215626 for this.

former_member188791
Participant
0 Kudos

HI Vipin,

Thank you for your reply, I checked this note it seems this is applicable for PI7.3 version, mine is 7.4, could you please let me know note number for PO7.4

vipinkumar_kanchan
Participant
0 Kudos

check if Note 2240919 is released.. it should contain the details..

Else check PAM..

former_member188791
Participant
0 Kudos

Hi Vipin,

Without Support Pack is there any alternative for this issue, we have some difficulty on updating SP,

vipinkumar_kanchan
Participant
0 Kudos

without SP, you would need custom code.

check the code snippet given by Christian above.. you would need to use Eng Swee's json transform bean also...

iaki_vila
Active Contributor
0 Kudos

Hi Vipin,

I think SAP PI Rest adapter doesn't support array tags in top level, check 's answer in this thread

You can try with Eng's adapter.

Regards.

vipinkumar_kanchan
Participant
0 Kudos

Hi Inaki,

Thanks for your response. My issue is not about having array at top level. Item is the top level and KDS is a level below that. The issue is that if only one value is passed to the KDS object, then PI only puts {} and does not add a [] to the payload whereas if 2 values are passed in KDS object, then PI adds both brackets to the json payload. Due to the missing square bracket in the case of the single value the integration fails..

Not sure whether  Eng Swee Yeoh's adapter resolves it.

The 3rd party developers have gone for a REST design where all objects are treated as arrays for consistency and hence it expects the square brackets for each object.

Message was edited by: Vipin Kanchan