Komplexe DDIC-Strukturen als XML ausgeben
Sind Sie auch schon an die Grenzen der Bordmittel von SAP gestoßen, wenn Sie versucht haben komplexe DDIC-Strukturen als XML auszugeben? In diesem Beitrag erklären wir Ihnen, wie Sie die rekursiver Programmierung als flexiblere Lösung nutzen können.
Insbesondere durch ZUGFeRD hat das Thema rasant an Fahrt aufgenommen und wird zunächst für Unternehmen, die öffentliche Einrichtungen zu ihren Kunden zählen, unvermeidbar. Grundlage einer jeden elektronischen Rechnung ist dabei ein maschinenlesbares Format wie zum Beispiel XML. Welchen Ansatz ich verfolgt habe, komplexe DDIC-Strukturen als XML auszugeben, möchte ich Ihnen im folgenden Artikel ein wenig näher bringen.
SAP-Bordmittel zur Ausgabe von XML
Natürlich ist auch in SAP inzwischen der XML-Standard angekommen und zunächst ist der Standard der erste Anhaltspunkt für die Umsetzung. So gibt es unter anderem folgende zwei Möglichkeiten eine Struktur aus dem ABAP-Dictionary als XML auszugeben, die Ihnen vielleicht auch schon geläufig sind:
- Simple Transformation / XSLT-Transformation (XSLT_TOOL)
- IXML-Framework
Auf die jeweiligen Details möchte an dieser Stelle gar nicht tiefer eingehen. Es gibt eine Menge ausführliche Anleitung zu den beiden Stichwörtern. Ein gutes und kurzes Tutorial zur 1. Variante finden Sie beispielsweise hier. Grundsätzlich wird dabei mit einer XSLT-Datei ein Mapping zwischen Feldern in ABAP und der XML hergestellt. Dabei ist jedoch viel manuelle Arbeit notwendig und die Erzeugung stößt bei sehr vielen Ebenen auch leider technisch an ihre Grenzen. Für ZUGFeRD mit Hunderten von Knoten und etlichen Ebenen Tiefe kam dies also nicht in Frage.
Mittels des Interfaces if_ixml (Paket SIXML) lassen sich zwar auch komplexere und tiefe Strukturen abbilden und fehlerfrei ausgeben, jedoch muss auch hier jeder Knoten manuell erzeugt und die Verknüpfung zum gewünschten Felder der Struktur im ABAP-Code hergestellt werden. Folgendes Beispiel würde den ersten Knoten eines ZUGFeRD-Dokumentes erzeugen.
DATA: lo_ixml TYPE REF TO if_ixml, lo_document TYPE REF TO if_ixml_document, lo_cid TYPE REF TO if_ixml_element, lo_streamfactory TYPE REF TO if_ixml_stream_factory, lo_ostream TYPE REF TO if_ixml_ostream, lo_renderer TYPE REF TO if_ixml_renderer. lo_ixml = cl_ixml=>create( ). lo_document = lo_ixml->create_document( ). lo_cid = lo_document->create_simple_element_ns(name = 'CrossIndustryDocument' prefix = 'rsm' parent = lo_document ). lo_streamfactory = lo_ixml->create_stream_factory( ). lo_ostream = lo_streamfactory->create_ostream_xstring( string = rv_xml ). lo_renderer = lo_ixml->create_renderer( ostream = lo_ostream document = lo_document ). lo_renderer->render( ).
Beide Varianten kommen also für ZUGFeRD nicht ohne erheblichen Aufwand in Frage. Außerdem besteht so keine Möglichkeit flexibel auf Änderungen oder neue Standards zu reagieren. Es muss also einen besseren Weg geben, um DDIC-Strukturen als XML zu exportieren.
Rekursive Programmierung als flexiblere Lösung
Um die oben aufgetauchten Probleme zu umgehen kommt nur ein dynamischer rekursiver Algorithmus infrage. Dabei ist jedoch zu beachten, dass beim Erstellen der Struktur ein passender Grundaufbau eingehalten wird. Es muss jeweils klar sein, was eine Komponente/Feld einer Struktur darstellt: einen weiteren XML-Knoten, den Wert des aktuellen Knotens oder Attribute des aktuellen Knotens.
Der grundsätzliche Ablauf ist dabei wie folgt:
- Über RunTime Type Identification den Namen und die Komponenten der zu verarbeitenden Struktur ermitteln
- XML-Knoten erzeugen
- Schleife über alle Felder/Komponenten der Struktur
- Ermitteln, um was es sich bei dem Feld handelt:
- Wert -> Wert des XML-Knoten setzen
- Attribute -> Als Attribut an aktuellen Knoten anfügen
- neuer Knoten -> rekursiver Aufruf (Beginn bei 1. mit erneuter RTTI)
- Knoten an den Vorgänger als Kind anhängen (Beim ersten Element ist dies einfach das Dokument)
- Im letzten Durchlauf den XML-String ausgeben.
Selbstverständlich gibt es dabei noch diverse Feinheiten zu beachten. Beispielsweise das Einbinden verschiedener Datentypen für Wertfelder oder die Abbildung von Tabellenfeldern. Außerdem ist zu klären, wie Informationen zu Namen und Namensräumen der Knoten abgelegt werden. Ich habe dieses Problem durch eine zusätzliche Mapping-Tabelle zwischen Namen des DDIC-Elements und Namen der XML-Knoten gelöst, da im Falle von ZUGFeRD die Bezeichner oft über 30 Zeichen lang sind und somit die einfache Verwendung des Namens aus SAP nicht möglich ist. Außerdem kann so auch case-sensitiv gearbeitet werden.
Mit Runtime Type Services DDIC-Strukturen als XML ausgeben
Grundlage für das dynamische Arbeiten mit DDIC-Strukturen sind die Runtime Type Services (RTTS) bzw. genauer gesagt die RTTI (RunTime Type Identification), welche dazu genutzt werden kann Metadaten über ein Element abzufragen. Dazu ein kleines Beispiel, welches zuerst den Namen der übergebenen Struktur und anschließend den Namen aller Komponenten/Felder dieser Struktur ausgeben würde.
DATA: lo_struct TYPE REF TO cl_abap_structdescr, TRY. lo_struct ?= cl_abap_typedescr=>describe_by_data( p_data = is_structure ). WRITE lo_struct->absolute_name. LOOP AT lo_struct->components ASSIGNING FIELD-SYMBOL(<ls_comp>). WRITE <ls-comp>-name. CATCH cx_sy_move_cast_error. " Hier werden Down-Cast-Error abgefangen, " so werden Elemente rausgefiltert die keine Knoten mehr sind. ENDTRY.
Fazit / Ausblick
Wie Sie sehen konnten, stoßen die eingebauten Funktionen von SAP bei so stark verschachtelten und umfangreichen Strukturen wie zum Beispiel ZUGFeRD, schnell an ihre Grenzen. Durch dynamische und flexible Programmabläufe kann dennoch eine hochperformante und universell einsetzbare Lösung gefunden werden. Hatten Sie schon einmal die Anforderung dynamisch verschiedene DDIC-Strukturen als XML auszugeben? Wenn ja, wie haben Sie das Problem gelöst? Ich freue mich auf Ihre Anregungen und stehe Ihnen bei Fragen gerne zur Verfügung. Suchen Sie nach einem Partner mit dem Sie das Thema ZUGFeRD sorgenfrei in Ihren Workflow einbinden können, dann könnte unsere All in One-Lösung das Richtige für Sie sein!
In meinem nächsten Beitrag werde ich Ihnen zeigen, welche Konzepte Sie nutzen können, um aus einer XML-Schema-Datei (XSD) voll automatisch selbst umfangreiche Strukturen in SAP automatisiert erstellen zu lassen und so schnell auf neue Standards und Anforderungen reagieren zu können.