1

I am deserializing a JSON file, and trying to find the correct way of dealing with boolean values. I began by trying to map the JSON/XML boolean directly to the native ABAP element but that raised an exception. I then tried to check for true and map the specific value "X" (in various ways) but none of those worked. Looking for ideas / suggestions.

My Sample Program

REPORT z_json_abap2.

CLASS demo DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS main.
ENDCLASS.

CLASS demo IMPLEMENTATION.
  METHOD main.

    TYPES: BEGIN OF ty_s_line,
             posnr  TYPE posnr,
             return TYPE xsdboolean,   "xsdboolean
             reason TYPE char3,
           END OF ty_s_line.

    TYPES: BEGIN OF ty_s_header,
             order_id TYPE vbeln,
             items    TYPE TABLE OF ty_s_line WITH DEFAULT KEY,
           END OF ty_s_header.

    DATA: lt_order TYPE ty_s_header.


    DATA(lv_json) = cl_abap_codepage=>convert_to(
   `{` &&
  ` "order_id": "51324", ` &&
  ` "items": [ ` &&
  ` { ` &&
  `   "line": "01", ` &&
  `   "return": true, ` &&
  `   "order_reason": "ABC" ` &&
  `   }, ` &&
  `   { ` &&
  `   "line": "02", ` &&
  `   "return": true ` &&
  `   }, ` &&
  `   { ` &&
  `   "line": "03", ` &&
  `   "return": false, ` &&
  `   "order_reason": null ` &&
  `   } ` &&
  `  ] ` &&
  `  } `  ).

    TRY.
        CALL TRANSFORMATION zst_order_test SOURCE XML lv_json RESULT root = lt_order.
      CATCH cx_transformation_error INTO DATA(exc).
        cl_demo_output=>display( exc->get_text( ) ).
        RETURN.
    ENDTRY.

  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.
  demo=>main( ).

I check that the element has the value "true" - and if it does I want to return the appropriate value for an ABAP_BOOLEAN . I have tried many options. It this latest version it raises an exception that the value "X" was expected.

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates" xmlns:ddic="http://www.sap.com/abapxml/types/dictionary" xmlns:def="http://www.sap.com/abapxml/types/defined">
  <tt:root name="ROOT" type="?"/>
  <tt:variable name="RETURN"/>
  <tt:variable length="1" name="ABAP_TRUE" type="C" val="'X'"/>
  <tt:template>
    <object>
      <str name="order_id">
        <tt:value option="noError" ref="ROOT.order_id"/>
      </str>
      <array>
        <tt:loop ref="ROOT.items">
          <object>
            <str name="line">
              <tt:value ref="$ref.posnr"/>
            </str>
            <bool name="return">
<!--              <tt:read type="C" var="RETURN"/>-->
<!--              <tt:cond-var check="RETURN='true'">-->
                <tt:value option="noError" ref="$ref.return"/>
<!--              </tt:cond-var>-->
<!--              <tt:cond-var check="RETURN!='true'"/>-->
<!--              <tt:skip/>-->
            </bool>
            <tt:cond>
              <str name="order_reason">
                <tt:value option="noError" ref="$ref.reason"/>
              </str>
            </tt:cond>
            <tt:cond>
              <null name="order_reason">
                <tt:value option="noError" ref="$ref.reason"/>
              </null>
            </tt:cond>
          </object>
        </tt:loop>
      </array>
    </object>
  </tt:template>
</tt:transform>

I think this should be easy - but stuck again :-). Thanks for any inputs suggestions.

Suncatcher
  • 10,355
  • 10
  • 52
  • 90

1 Answers1

1

Thanks to a tip from Sandra this is now solved. For those who are interested here is the solution (the key point being to use XSDBOOLEAN - which I thought I had tried but apparently not in the right combination with everything else).

REPORT z_json_abap2.

CLASS demo DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS main.
ENDCLASS.

CLASS demo IMPLEMENTATION.
  METHOD main.

    TYPES: BEGIN OF ty_s_line,
             posnr  TYPE posnr,
             return TYPE xsdboolean,
             reason TYPE char3,
           END OF ty_s_line.

    TYPES: BEGIN OF ty_s_header,
             order_id TYPE vbeln,
             items    TYPE TABLE OF ty_s_line WITH DEFAULT KEY,
           END OF ty_s_header.

    DATA: lt_order TYPE ty_s_header.


    DATA(lv_json) = cl_abap_codepage=>convert_to(
   `{` &&
  ` "order_id": "51324", ` &&
  ` "items": [ ` &&
  ` { ` &&
  `   "line": "01", ` &&
  `   "return": true, ` &&
  `   "order_reason": "ABC" ` &&
  `   }, ` &&
  `   { ` &&
  `   "line": "02", ` &&
  `   "return": true ` &&
  `   }, ` &&
  `   { ` &&
  `   "line": "03", ` &&
  `   "return": false, ` &&
  `   "order_reason": null ` &&
  `   } ` &&
  `  ] ` &&
  `  } `  ).

    TRY.
        CALL TRANSFORMATION zst_order_test SOURCE XML lv_json RESULT root = lt_order.
      CATCH cx_transformation_error INTO DATA(exc).
        cl_demo_output=>display( exc->get_text( ) ).
        RETURN.
    ENDTRY.

  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.
  demo=>main( ).

Working Transformation

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates" xmlns:ddic="http://www.sap.com/abapxml/types/dictionary" xmlns:def="http://www.sap.com/abapxml/types/defined">
  <tt:root name="ROOT" type="?"/>
  <tt:template>
    <object>
      <str name="order_id">
        <tt:value option="noError" ref="ROOT.order_id"/>
      </str>
      <array>
        <tt:loop ref="ROOT.items">
          <object>
            <str name="line">
              <tt:value ref="$ref.posnr"/>
            </str>
            <bool name="return">
                <tt:value option="noError" ref="$ref.return"/>
            </bool>
            <tt:cond>
              <str name="order_reason">
                <tt:value option="noError" ref="$ref.reason"/>
              </str>
            </tt:cond>
            <tt:cond>
              <null name="order_reason">
                <tt:value option="noError" ref="$ref.reason"/>
              </null>
            </tt:cond>
          </object>
        </tt:loop>
      </array>
    </object>
  </tt:template>
</tt:transform>

As easy as that ... once you know how

Mike
  • 14,010
  • 29
  • 101
  • 161