Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

JSON to ABAP transformation issue

johnm16
Participant
0 Kudos

Hi Folks,

after having problems with the serialize/deserialize methods, I took Sandra Rossi's advice and created some simple JSON-ABAP-JSON transformations. My first ABAP to JSON transformation worked perfectly.

However, I'm having an issue with a very simple JSON to ABAP transformation: it takes a very basic JSON string (3 fields) and converts them to an ABAP flat structure, or tries to.

Here is the JSON string:

{<br>"access_token":"67118f6bfaa1efedba09c90f9b2bc578e70f8468",<br>"expires_in":21600,<br>"token_type":"bearer"<br>}

Here is the target ABAP structure ZSTY_IN_JSON_TOKEN_RESPONSE:

ACCESS_TOKEN     Type ZDE_ACCESS_TOKEN  STRING	0<br>EXPIRES_IN       Type ZDE_EXPIRES_IN    STRING	0<br>TOKEN_TYPE       Type ZDE_TOKEN_TYPE    STRING	0

Here is the transformation:

  <tt:root name="ACCESS_RESPONSE" type="ddic:ZSTY_IN_JSON_TOKEN_RESPONSE"/><br>  <tt:template><br>    <object><br>      <str name="access_token"><br>        <tt:value ref="access_response.access_token"/><br>      </str><br>      <str name="expires_in"><br>        <tt:value ref="access_response.expires_in"/><br>      </str><br>      <str name="token_type"><br>        <tt:value ref="access_response.token_type"/><br>      </str><br>    </object><br>  </tt:template>

And here's the transformation call (lr_reader TYPE REF TO if_sxml_reader):

      CALL TRANSFORMATION zca_in_json_token_response<br>               SOURCE XML lr_reader<br>                   RESULT access_response = ls_response.

Now here's the thing: when I call the transformation, the first field ("access_token") is initialised in the ABAP structure perfectly. The second field ("expires_in") fails every time with the exception CX_ST_MATCH_ELEMENT. The exception error message is "System expected element 'str'".

Maybe it's because the incoming JSON value is numeric, and my structure has a string field as the target? But I have also tried NUMC type (my original choice), integer, decimal and character text for the "expires_in" field. All options fail with the same error.

I suspect the problem lies in this part of the transformation:

      <str name="expires_in"><br>        <tt:value ref="access_response.expires_in"/><br>      </str>

The debugger catches the exception at the first of these three lines, so I expect there's something wrong with it; but I've no idea what.

Thank you for reading, all advice gratefully received.

Cheers

John Moulding.

5 REPLIES 5

johnm16
Participant
0 Kudos

PS Please ignore the attachment!

Sandra_Rossi
Active Contributor
0 Kudos

Press menu Actions > Edit and delete your attachment (cross button in the attachment).

All your codes have <br> inside them.

To paste code without <br>, use Ctrl+Shift+V (unformatted paste).

Here is the JSON string:

{
"access_token":"67118f6bfaa1efedba09c90f9b2bc578e70f8468",
"expires_in":21600,
"token_type":"bearer"
}

Here is the target ABAP structure ZSTY_IN_JSON_TOKEN_RESPONSE:

ACCESS_TOKEN   Type ZDE_ACCESS_TOKEN  STRING
EXPIRES_IN     Type ZDE_EXPIRES_IN    STRING
TOKEN_TYPE     Type ZDE_TOKEN_TYPE    STRING

Here is the transformation:

  <tt:root name="ACCESS_RESPONSE" type="ddic:ZSTY_IN_JSON_TOKEN_RESPONSE"/>
  <tt:template>
    <object>
      <str name="access_token">
        <tt:value ref="access_response.access_token"/>
      </str>
      <str name="expires_in">
        <tt:value ref="access_response.expires_in"/>
      </str>
      <str name="token_type">
        <tt:value ref="access_response.token_type"/>
      </str>
    </object>
  </tt:template>

And here's the transformation call (lr_reader TYPE REF TO if_sxml_reader):

      CALL TRANSFORMATION zca_in_json_token_response
               SOURCE XML lr_reader
               RESULT access_response = ls_response.

johnm16
Participant
0 Kudos

Thank you Sandra!

Any ideas for a solution?

JM

Sandra_Rossi
Active Contributor

You need to understand how SAP converts JSON into JSON XML before it's passed to the XML transformation.

{
"access_token":"67118f6bfaa1efedba09c90f9b2bc578e70f8468",
"expires_in":21600,
"token_type":"bearer"
}

is automatically converted into:

<object>
  <str name="access_token">67118f6bfaa1efedba09c90f9b2bc578e70f8468</str>
  <num name="expires_in">21600</num>
  <str name="token_type">bearer</str>
</object>

THE PROBLEM: your transformation fails because it expects <str name="expires_in"> --- In your below code, use <num ...> instead of <str ...>:

      <num name="expires_in">
        <tt:value ref="access_response.expires_in"/>
      </num>

In case it's not obvious, you may ask ABAP to obtain JSON-XML automatically with this kind of code (ASSERT is just present to show what is obtained):

call transformation id source xml `{"a":1}` result xml data(json_xml) options xml_header = 'no'.
assert cl_abap_codepage=>convert_from( json_xml ) = `<object><num name="a">1</num></object>`.

Thank you very much!

Cheers

John