首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >定制由CL_SXML_STRING_WRITER创建的JSON

定制由CL_SXML_STRING_WRITER创建的JSON
EN

Stack Overflow用户
提问于 2019-03-29 21:32:12
回答 3查看 1.2K关注 0票数 2

我像这样创建JSON来提取任何表(在运行时决定的名称是“随机”的,它的名称在变量iv_table_name中):

代码语言:javascript
复制
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(lo_json_writer) = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).

CALL TRANSFORMATION id
        SOURCE result = <itab>
        RESULT XML lo_json_writer.

cl_abap_conv_in_ce=>create( )->convert( 
        EXPORTING
          input = lo_json_writer->get_output( )
        IMPORTING
          data = sub_json ).

结果变量sub_json如下所示:

代码语言:javascript
复制
{"RESULT":
 [
   {"MANDT":"220","AUFNR":"0000012", ...},
   {"MANDT":"220","AUFNR":"0000013", ...},
   ...
  ]
}

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

代码语言:javascript
复制
 [
   {"MANDT":"220","AUFNR":"0000012", ...},
   {"MANDT":"220","AUFNR":"0000013", ...},
   ...
  ]

背景:

我使用了这个:

代码语言:javascript
复制
sub_json = /ui2/cl_json=>serialize( data = <lt_result> pretty_name = /ui2/cl_json=>pretty_mode-low_case ).

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-03-30 22:10:13

我不知道是否可以在完整的结果中省略初始的“sXML”标签,但我的意见是不可以。

现在,这里有一个使用KISS principle的解决方案:

代码语言:javascript
复制
REPLACE ALL OCCURRENCES OF REGEX '^\{"RESULT":|\}$' IN sub_json WITH ``.

还有另一种编写方式(稍微慢一点):

代码语言:javascript
复制
sub_json = replace( val = sub_json regex = '^\{"RESULT":|\}$' with = `` occ = 0 ).

关于性能的附录:

我测量了一下,对于一个880K字符的字符串,下面的代码带有要删除的确切位置数(10个前导字符和1个尾随字符)比regex快6倍(可能会因ABAP内核的版本而异),但与程序的其余部分相比,它可能不会很明显:

代码语言:javascript
复制
SHIFT sub_json LEFT BY 10 PLACES CIRCULAR.
REPLACE SECTION OFFSET strlen( sub_json ) - 11 OF sub_json WITH ``.
票数 1
EN

Stack Overflow用户

发布于 2019-04-01 02:43:49

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

代码语言:javascript
复制
<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>

然后你可以像那样使用它。

代码语言:javascript
复制
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 ).
票数 2
EN

Stack Overflow用户

发布于 2019-05-29 20:15:11

只需要一点手工工作,瞧!

代码语言:javascript
复制
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` ).

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55418586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档