Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
自定义CL_SXML_STRING_WRITER创建的JSON_Json_Abap_Json Serialization - Fatal编程技术网

自定义CL_SXML_STRING_WRITER创建的JSON

自定义CL_SXML_STRING_WRITER创建的JSON,json,abap,json-serialization,Json,Abap,Json Serialization,我创建这样的JSON来提取运行时随机决定的任何表名,其名称在变量iv_table_name中: 有没有办法避开周围的字典,得到这样的结果 [ {"MANDT":"220","AUFNR":"0000012", ...}, {"MANDT":"220","AUFNR":"0000013", ...}, ... ] 背景: 我用了这个: sub_json = /ui2/cl_json=>serialize( data = <lt_result> prett

我创建这样的JSON来提取运行时随机决定的任何表名,其名称在变量iv_table_name中:

有没有办法避开周围的字典,得到这样的结果

 [
   {"MANDT":"220","AUFNR":"0000012", ...},
   {"MANDT":"220","AUFNR":"0000013", ...},
   ...
  ]
背景: 我用了这个:

sub_json = /ui2/cl_json=>serialize( data = <lt_result> pretty_name = /ui2/cl_json=>pretty_mode-low_case ).

但是/ui2/cl_json=>serialize的性能并不好。

我没有得到关于是否可以在完整的sXML中省略初始结果标记的答案,但我的意见是否定的

现在,解决方案是:

还有另一种书写速度稍微慢一些:

sub_json = replace( val = sub_json regex = '^\{"RESULT":|\}$' with = `` occ = 0 ).
关于绩效的附录:

我测量到,对于一个880K字符的字符串,下面的代码(包含删除10个前导字符和1个尾随字符的确切位置数)比regex的速度快6倍,这可能取决于ABAP内核的版本,但与程序的其余部分相比,它可能并不明显:

SHIFT sub_json LEFT BY 10 PLACES CIRCULAR.
REPLACE SECTION OFFSET strlen( sub_json ) - 11 OF sub_json WITH ``.

如果您真的想将它用作提取表记录的工具,那么您可以在STRANS中编写自己的ID转换。它可能是这样的,让我们将其命名为Z_JSON_TABLE_CONTENTS使用XSLT类型创建它:

那你就可以这样用了

REPORT ZZZ.

FIELD-SYMBOLS <itab> TYPE STANDARD TABLE.
DATA ref_itab TYPE REF TO data.

DATA(iv_table_name) = 'SCARR'.
CREATE DATA ref_itab TYPE STANDARD TABLE OF (iv_table_name).
ASSIGN ref_itab->* TO <itab>.

SELECT *
  INTO TABLE <itab>
  FROM (iv_table_name).

DATA results_json TYPE TABLE OF string.
DATA sub_json TYPE string.

DATA g_string TYPE string.
DATA(g_document) = cl_ixml=>create( )->create_document( ).
DATA(g_ref_stream_factory) = cl_ixml=>create( )->create_stream_factory( ).
DATA(g_ostream) = g_ref_stream_factory->create_ostream_cstring( g_string ).

CALL TRANSFORMATION Z_JSON_TABLE_CONTENTS
        SOURCE result = <itab>
        RESULT XML g_ostream.

DATA(g_json_parser) = new /ui5/cl_json_parser( ).
g_json_parser->parse( g_string ).
若您使用ID调用转换,那个么默认情况下,您在该节点的转换中给出的任何节点都将被添加。我们不能跳过此项,但您可以通过以下方式删除

Replace:将Regex或Direct word与Replace First-Occurrence语句和next-last右括号}一起使用。就像你做的那样

查找:您可以简单地使用下面的语句
在sub_json子匹配sub_json中找到正则表达式“\[.*]”。

只需一点手工工作,瞧

DATA(writer) = CAST if_sxml_writer( cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ) ).

DATA(components) =
CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_name( iv_table_name ) )->components.

writer->open_element( name = 'object' ).
LOOP AT <itab> ASSIGNING FIELD-SYMBOL(<line>).
 LOOP AT components ASSIGNING FIELD-SYMBOL(<fs_comp>).
  ASSIGN COMPONENT <fs_comp>-name OF STRUCTURE <line> TO FIELD-SYMBOL(<fs_val>).
  writer->open_element( name = 'str' ).
  writer->write_attribute( name = 'name' value = CONV string( <fs_comp>-name ) ).
  writer->write_value( CONV string( <fs_val> ) ).
  writer->close_element( ).
 ENDLOOP.
ENDLOOP.
writer->close_element( ).

DATA(xml_json) = CAST cl_sxml_string_writer( writer )->get_output(  ).  
sub_json = cl_abap_codepage=>convert_from( source = xml_json codepage = `UTF-8` ).

没有周围的列表和字典。如果你想把每一行都放在单独的字典中,那么它很容易调整。

可能只需要另一个转换。当我有更多时间的时候,我会发布我的建议。你可以通过删除开始和结束部分的方式来完成。通常,你的FIND语句相当于这个赋值,带有match函数:sub_json=match val=sub_json regex='\[.\]'。
SHIFT sub_json LEFT BY 10 PLACES CIRCULAR.
REPLACE SECTION OFFSET strlen( sub_json ) - 11 OF sub_json WITH ``.
<xsl:transform version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:sap="http://www.sap.com/sapxsl"
>

<xsl:output method="text" encoding="UTF-8" />

<xsl:strip-space elements="*"/>

<xsl:template match="RESULT">
  [
    <xsl:for-each select="*">
      {
      <xsl:for-each select="*">
        &quot;<xsl:value-of select="local-name()" />&quot;: &quot;<xsl:value-of select="text()" />&quot;<xsl:if test="position() != last()">,</xsl:if>
      </xsl:for-each>
      }<xsl:if test="position() != last()">,</xsl:if>
    </xsl:for-each>
  ]
</xsl:template>

</xsl:transform>
REPORT ZZZ.

FIELD-SYMBOLS <itab> TYPE STANDARD TABLE.
DATA ref_itab TYPE REF TO data.

DATA(iv_table_name) = 'SCARR'.
CREATE DATA ref_itab TYPE STANDARD TABLE OF (iv_table_name).
ASSIGN ref_itab->* TO <itab>.

SELECT *
  INTO TABLE <itab>
  FROM (iv_table_name).

DATA results_json TYPE TABLE OF string.
DATA sub_json TYPE string.

DATA g_string TYPE string.
DATA(g_document) = cl_ixml=>create( )->create_document( ).
DATA(g_ref_stream_factory) = cl_ixml=>create( )->create_stream_factory( ).
DATA(g_ostream) = g_ref_stream_factory->create_ostream_cstring( g_string ).

CALL TRANSFORMATION Z_JSON_TABLE_CONTENTS
        SOURCE result = <itab>
        RESULT XML g_ostream.

DATA(g_json_parser) = new /ui5/cl_json_parser( ).
g_json_parser->parse( g_string ).
DATA(writer) = CAST if_sxml_writer( cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ) ).

DATA(components) =
CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_name( iv_table_name ) )->components.

writer->open_element( name = 'object' ).
LOOP AT <itab> ASSIGNING FIELD-SYMBOL(<line>).
 LOOP AT components ASSIGNING FIELD-SYMBOL(<fs_comp>).
  ASSIGN COMPONENT <fs_comp>-name OF STRUCTURE <line> TO FIELD-SYMBOL(<fs_val>).
  writer->open_element( name = 'str' ).
  writer->write_attribute( name = 'name' value = CONV string( <fs_comp>-name ) ).
  writer->write_value( CONV string( <fs_val> ) ).
  writer->close_element( ).
 ENDLOOP.
ENDLOOP.
writer->close_element( ).

DATA(xml_json) = CAST cl_sxml_string_writer( writer )->get_output(  ).  
sub_json = cl_abap_codepage=>convert_from( source = xml_json codepage = `UTF-8` ).