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.