将ABAP数据转换为以JSON-XML格式表示的iXML对象

时间:2019-04-24 09:38:08

标签: json xml abap

我想将任意ABAP数据读取到包含这些数据的iXML表示形式的JSON-XML文档对象中。

我看到的唯一方法是id转换的双重应用,效率不高:

data(lo_aux1) = cl_sxml_string_writer=>create( if_sxml=>co_xt_json ).
call transformation id
  source data = ls_some_abap_data
  result xml lo_aux1.
data(lv_aux2) = lo_aux1->get_output( ).
data(lo_result) = cl_ixml=>create( )->create_document( ).
call transformation id
  source xml lv_aux2
  result xml lo_result. 

现在,lo_resultiXML格式的ABAP数据的JSON-XML DOM表示(根据需要)。是否有可能以更直接的方式获得它?

注意:我对sXML系列的结果对象不感兴趣,因为我想使用常规的XML DOM方法来操作/扩展生成的JSON-XML文档,对于sXML编写器对象来说这是不可能的(sXML编写器是如此简单,它们只能将其拥有的所有内容写入输出对象,但不允许编辑它们已经包含的部分对象)

1 个答案:

答案 0 :(得分:1)

  

我正坐在代理服务器上,想要在将传入的JSON有效负载传递给端点之前,通过一些ABAP数据对其进行充实。策略:将传入的JSON解析为JSON-XML文档,将(复杂的)ABAP数据读取为第二个XML文档,然后将第二个的XML子树添加到第一个XML子树中,最后从第一个JSON-XML文档中生成结果JSON < / p>

我根本不了解iXML的需求。在这里,将复杂的ABAP结构转换为XML以与JSON合并是多余的。假设您从Web服务收到了一些JSON数据:

{  
   "main":{  
      "PASSENGERS":[  
         {  
            "NAME":"Horst",
            "TITLE":"Herr",
            "AGE":30
         },
         {  
            "NAME":"Jutta",
            "TITLE":"Frau",
            "AGE":35
         },
         {  
            "NAME":"Ingo",
            "TITLE":"Herr",
            "AGE":31
         }
      ]
   }
}

您想用SFLIGHT表中的航班数据充实每个乘客数据。您可以使用cl_sxml_string_writer来操作节点和属性,如下所示:

DATA(lv_json) = CONV string( '{"main": {"PASSENGERS":[ {"NAME":"Horst","TITLE":"Herr","AGE":30}, {"NAME":"Jutta","TITLE":"Frau","AGE":35}, {"NAME":"Ingo","TITLE":"Herr","AGE":31} ]}}' ).

DATA open_element TYPE REF TO if_sxml_open_element.
DATA value TYPE REF TO if_sxml_value_node.

DATA(o_json) = cl_abap_codepage=>convert_to( lv_json ).
DATA(reader) = cl_sxml_string_reader=>create( o_json ).

SELECT DISTINCT connid, fldate, planetype FROM sflight INTO TABLE @DATA(lt_flight).

DATA(xml) = cl_abap_codepage=>convert_to( lv_json ).

DATA(out) = cl_demo_output=>new( )->begin_section( 'Original JSON' )->write_xml( xml ).

DATA(writer) = CAST if_sxml_writer( cl_sxml_string_writer=>create( ) ).
open_element = writer->new_open_element( name = 'flights' nsuri = reader->nsuri ).
writer->write_node( open_element ).
DATA(i) = 1.
DO.
  DATA(node) = reader->read_next_node( ).
  IF node IS INITIAL.
    EXIT.
  ENDIF.
  IF node IS INSTANCE OF if_sxml_value_node.
    DATA(value_node) = CAST if_sxml_value_node( node ).
    value_node->set_value( to_upper( value_node->get_value( ) ) ).
  ENDIF.
  writer->write_node( node ).
  IF node->type = if_sxml_node=>co_nt_element_open.
    DATA(op) = CAST if_sxml_open_element( node ).
    CHECK op->qname-name = 'object' AND op->get_attributes( ) IS INITIAL.
    open_element = writer->new_open_element( name = 'flight' nsuri = reader->nsuri ).
    open_element->set_attribute( name = 'FLIGHT_DATE'
                                 value = | { lt_flight[ i ]-fldate } | ).
    open_element->set_attribute( name = 'PLANE_TYPE'
                                 value = | { lt_flight[ i ]-planetype } | ).
    writer->write_node( open_element ).
    value = writer->new_value( ).
    value->set_value( | { lt_flight[ i ]-connid } | ).
    writer->write_node( value ).
    writer->write_node( writer->new_close_element( ) ).
    i = i + 1.
  ENDIF.
ENDDO.
writer->write_node( writer->new_close_element( ) ).
out->next_section( 'Modified JSON'
  )->write_xml(
    CAST cl_sxml_string_writer( writer )->get_output( )
  )->display( ).

DATA(result_json) = CAST cl_sxml_string_writer( writer )->get_output(  ).

结果JSON将被转储到result_json变量中,您可以将其进一步推送到任意位置。

这是生成的JSON,带有大写的乘客值并通过flight节点扩展,该节点包含航班号,并具有数据和飞机类型:

<flights>
 <object>
  <flight FLIGHT_DATE=" 20160610 " PLANE_TYPE=" A380‑800 "> 0002 </flight>
  <object name="main">
   <array name="PASSENGERS">
    <object>
     <flight FLIGHT_DATE=" 20160712 " PLANE_TYPE=" A380‑800 "> 0002 </flight>
     <str name="NAME">HORST</str>
     <str name="TITLE">HERR</str>
     <num name="AGE">30</num>
    </object>
    <object>
     <flight FLIGHT_DATE=" 20160813 " PLANE_TYPE=" A380‑800 "> 0002 </flight>
     <str name="NAME">JUTTA</str>
     <str name="TITLE">FRAU</str>
     <num name="AGE">35</num>
    </object>
    <object>
     <flight FLIGHT_DATE=" 20160914 " PLANE_TYPE=" A380‑800 "> 0002 </flight>
     <str name="NAME">INGO</str>
     <str name="TITLE">HERR</str>
     <num name="AGE">31</num>
    </object>
   </array>
  </object>
 </object>
</flights>