Diesen Artikel habe ich ursprünglich im SAP Community Network veröffentlicht.

Ich verwende asXML seit einigen Jahren als bequeme Möglichkeit, beliebige ABAP-Datenstrukturen zu serialisieren und zu deserialisieren. Vor einiger Zeit habe ich von IF_SERIALIZABLE_OBJECT und seiner Verwendung zum [Einfügen von Klasseninstanzen (auch Objekte genannt) in eine asXML-Darstellung Darstellung] (http://help.sap.com/abapdocu_740/en/abenasxml_class_instances.htm) erfahren. Vor ein paar Tagen beschloss ich, diese Technik in einem aktuellen Entwicklungsprojekt zu verwenden. Gleichzeitig versuchte ich, CL_DEMO_OUTPUT_STREAM anstelle von klassischen Listen zu verwenden [wie in der Online-Dokumentation vorgeschlagen] (http://help.sap.com/abapdocu_740/en/abenabap_dynpro_list.htm). Da ich mit den Grundlagen der Verwendung von Transformationen vertraut war, konzentrierte ich mich eher auf die Verwendung dieser neuen Ausgabetechnologie. Ich habe ein kleines Demoprogramm wie dieses hier zusammengeworfen:

REPORT z_test_serialize.

CLASS lcl_serializable_thingy DEFINITION CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_serializable_object.
    METHODS constructor
      IMPORTING
        i_foo TYPE string.
    METHODS get_foo
      RETURNING
        VALUE(r_foo) TYPE string.
  PRIVATE SECTION.
    DATA g_foo TYPE string.
ENDCLASS.

CLASS lcl_serializable_thingy IMPLEMENTATION.
  METHOD constructor.
    g_foo = i_foo.
  ENDMETHOD.
  METHOD get_foo.
    r_foo = g_foo.
  ENDMETHOD.
ENDCLASS.

CLASS lcl_main DEFINITION CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS run.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD run.
    DATA: lr_stream        TYPE REF TO cl_demo_output_stream,
          l_foo_in         TYPE string,
          lr_first_thingy  TYPE REF TO lcl_serializable_thingy,
          l_xml_data       TYPE string,
          lr_second_thingy TYPE REF TO lcl_serializable_thingy,
          l_foo_out        TYPE string.
    lr_stream = cl_demo_output_stream=>open( ).
    SET HANDLER cl_demo_output_html=>handle_output FOR lr_stream.
    lr_stream->write_text( iv_text = 'XML Serialization of ABAP Objects Instances'
                           iv_format = if_demo_output_formats=>heading
                           iv_level  = 1 ).
    l_foo_in = |Hello, this is Foo Bar calling from { sy-sysid } client { sy-mandt }.|.
    lr_stream->write_data( iv_name  = 'Input Data'
                           ia_value  = l_foo_in
                           iv_format = if_demo_output_formats=>nonprop ).
    CREATE OBJECT lr_first_thingy
      EXPORTING
        i_foo = l_foo_in.
    CALL TRANSFORMATION id
      SOURCE instance = lr_first_thingy
      RESULT xml      = l_xml_data.
    lr_stream->write_data( iv_name  = 'XML Serialization'
                           ia_value  = l_xml_data
                           iv_format = if_demo_output_formats=>nonprop ).
    CALL TRANSFORMATION id
      SOURCE xml      = l_xml_data
      RESULT instance = lr_second_thingy.
    l_foo_out = lr_second_thingy->get_foo( ).
    lr_stream->write_data( iv_name  = 'Output Data'
                           ia_value  = l_foo_out
                           iv_format = if_demo_output_formats=>nonprop ).
    lr_stream->close( ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  lcl_main=>run( ).

Anstelle des erwarteten Ergebnisses (ein Text, eine XML-Darstellung der Instanz und derselbe Text noch einmal) erhielt ich einen Kurzdump. Die Referenz lr_second_thingy wurde nach der zweiten Transformation nicht gesetzt – die Deserialisierung muss also irgendwie defekt sein, oder? Der Debugger zeigte schnell, dass die String-Variable, die die serialisierte Instanz enthalten sollte, leer war – also muss die Serialisierung defekt sein und nicht die Deserialisierung? Nun, in gewisser Weise sind es beide. Um direkt zum Punkt zu kommen, hier ist der fehlerhafte Code:

    CALL TRANSFORMATION id
      SOURCE instance = lr_first_thingy
      RESULT xml      = l_xml_data.
    lr_stream->write_data( iv_name  = 'XML Serialization'
                           ia_value  = l_xml_data
                           iv_format = if_demo_output_formats=>nonprop ).
    CALL TRANSFORMATION id
      SOURCE xml      = l_xml_data
      RESULT instance = lr_second_thingy.</pre>

Und hier die korrigierte Fassung:

    CALL TRANSFORMATION id
      SOURCE instance = lr_first_thingy
      RESULT XML        l_xml_data.
    lr_stream->write_data( iv_name  = 'XML Serialization'
                           ia_value  = l_xml_data
                           iv_format = if_demo_output_formats=>nonprop ).
    CALL TRANSFORMATION id
      SOURCE XML        l_xml_data
      RESULT instance = lr_second_thingy.</pre>

Jepp, der Unterschied besteht in einem einzelnen Zeichen – oder in diesem Fall in zwei Zeichen. Ohne das Gleichheitszeichen wird XML als Schlüsselwort behandelt, das eine Variable bezeichnet, die die XML-Rohdaten enthält. Mit dem Gleichheitszeichen passiert etwas anderes, für das ich noch keine sinnvolle und praktische Verwendung gefunden habe – zumindest nicht in Verbindung mit der Identitätstransformation. Sie können dieses Problem erkennen, wenn Sie den Pretty Printer verwenden, um die Schlüsselwörter in Großbuchstaben umzuwandeln – und wenn Sie den winzigen Unterschied zwischen xml und XML bemerken.