我想将任意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_result
是iXML
格式的ABAP数据的JSON-XML
DOM表示(根据需要)。是否有可能以更直接的方式获得它?
注意:我对sXML
系列的结果对象不感兴趣,因为我想使用常规的XML DOM方法来操作/扩展生成的JSON-XML
文档,对于sXML
编写器对象来说这是不可能的(sXML
编写器是如此简单,它们只能将其拥有的所有内容写入输出对象,但不允许编辑它们已经包含的部分对象)
答案 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>