使用正则表达式反序列化JSON数据

时间:2019-09-05 11:01:33

标签: json regex abap

如果JSON包含\&“,则在使用正则表达式从数据中获取键和值时遇到问题。

{
   "KeyOne":"Value One",
   "KeyTwo": "Value \\ two",
   "KeyThree": "Value \" Three",
   "KeyFour": "ValueFour\\"
} 

这是示例数据,我要从中读取值是键。我该如何使用正则表达式。

注意:我正在服务器端(SAP ABAP)反序列化此JSON数据。

2 个答案:

答案 0 :(得分:2)

正如@mrzasa和@joanis在评论中所说:请勿使用RegEx解析JSON!

对于小型物体或不考虑性能的情况,可以使用/ui2/cl_json

TYPES:
  BEGIN OF lty_foo_bar,
    KeyOne TYPE string,
    KeyTwo Type string,
    KeyThree TYPE string,
    KeyFour Type string,
  END OF lty_foo_bar.

DATA:
    lv_json_string TYPE string,
    ls_data TYPE lty_foo_bar.

 lv_json_string = |\{| &&
   |"KeyOne":"Value One",| &&
   |"KeyTwo": "Value \\\\ two", | &&
   |"KeyThree": "Value \\" Three", | &&
   |"KeyFour": "ValueFour\\\\" | &&
   |\}|.

/ui2/cl_json=>deserialize(
  EXPORTING
     json = lv_json_string
  CHANGING
     data = ls_data ).

ls_data-KeyOne包含'Value One',依此类推。

对于更大的对象和/或更好的性能,请在下面的@phil soadys answer中检查lxml。无论如何,正确处理大小写字母仍然会导致ABAP头痛。

答案 1 :(得分:2)

在小于7.2(从内存中)的早期版本中,可以使用类/ui2/cl_json

如果在7.3或更高版本上,请使用支持JSON的内核IXML writer。 它比/ ui2 / cl_json

快几个数量级

您可以使用已知源结构已知的身份转换方法 并且您可以在abap中创建该结构,或者已经定义了abap等效项。否则,只需遍历JSON文档。 示例字符串很容易解析

编辑:添加示例代码

REPORT zjsondemo.

CLASS lcl DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS json_stru_known.
    METHODS json_stru_traverse.

ENDCLASS.

CLASS lcl IMPLEMENTATION.

  METHOD json_stru_known.
    DATA l_src_json TYPE string.
    DATA l_mara TYPE mara.

    WRITE: / 'DEMO 1 Known structure Identity transformation '.

    l_src_json = `{"MARA":{"MATNR":"012345678", "MATKL": "DUMMY" }}`.
    WRITE: / 'Conver to MARA -> ', l_src_json.

    CALL TRANSFORMATION id SOURCE XML l_src_json
          RESULT mara = l_mara.  "

    WRITE: / 'MARA -  MATNR', l_mara-matnr,
           / '        MATKL', l_mara-matkl.

TYPES:
  BEGIN OF lty_foo_bar,
    KeyOne TYPE string,
    KeyTwo Type string,
    KeyThree TYPE string,
    KeyFour Type string,
  END OF lty_foo_bar.

DATA:
    lv_json_string TYPE string,
    ls_data TYPE lty_foo_bar.
 " in this example we use upper case attribute names 
  "because we map to SAP target 
  " structure which has upper case names.   
  " if you need lowercase variables then you can not map straight to an
  " SAP type.  Then you need to use the traverse technique. See example 2
 lv_json_string = |\{| &&
   |"KEYONE":"Value One",| &&
   |"KEYTWO": "Value \\\\ two", | &&
   |"KEYTHREE": "Value \\" Three", | &&
   |"KEYFOUR": "ValueFour\\\\" | &&
   |\}|.

   lv_json_string = `{"JUNK":` && lv_json_string && `}`.


CALL TRANSFORMATION id SOURCE XML lv_json_string
          RESULT junk = ls_data.  "


Write: / ls_data-keyone,ls_data-keytwo, ls_data-keythree , ls_data-keyfour.




  ENDMETHOD.

  METHOD json_stru_traverse.
    DATA l_src_json TYPE string.
    DATA: lo_node TYPE REF TO if_sxml_node.
    DATA: lif_element       TYPE REF TO if_sxml_open_element,
          lif_element_close TYPE REF TO if_sxml_close_element,
          lif_value_node    TYPE REF TO if_sxml_value,
          l_val             TYPE string,
          l_attr            TYPE if_sxml_attribute=>attributes,
          l_att_val         TYPE string.
    FIELD-SYMBOLS: <attr> LIKE LINE OF l_attr.


    WRITE: / 'DEMO 2 Traverse any json  document'.

    l_src_json = `{"MATNR":"012345678", "MATKL": "DUMMY", "SOMENODE": "With this value" }`.

    WRITE: / 'Parse as JSON with 3 nodes -> ', l_src_json.


    DATA(reader) = cl_sxml_string_reader=>create( cl_abap_codepage=>convert_to(  l_src_json ) ).


    lo_node = reader->read_next_node( ).   " {
    IF lo_node IS INITIAL.
      EXIT.
    ENDIF.

    DO 3 TIMES.


      lif_element ?= reader->read_next_node( ).
      l_attr =  lif_element->get_attributes( ).
      LOOP AT l_attr ASSIGNING <attr>.
        l_att_val =  <attr>->get_value( ).
        WRITE: / 'Attribute:', l_att_val.
      ENDLOOP.

      lif_value_node ?= reader->read_next_node( ).
      l_val = lif_value_node->get_value( ).
      WRITE: '=>',  l_val.

      lif_element_close ?= reader->read_next_node( ).


    ENDDO.

  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.
  DATA lo_lcl TYPE REF TO lcl.
  CREATE OBJECT lo_lcl.
  lo_lcl->json_stru_known( ).
  lo_lcl->json_stru_traverse( ).

SAP系统随附许多示例程序。 搜索demo*json

SAP docu on json parsing

相关问题