XML-Import

Das Modul tl-xio liefert einen konfigurierbaren XML-Import. Über eine XML-Deklaration lässt sich eine Übersetzung einer XML-Datei in ein TopLogic-Modell konfigurieren. Die Import-Definition ist dabei eine typisierte Konfiguration für Implementierungen des Interface com.top_logic.xio.importer.handlers.Handler. Ein solcher Handler ließt einen XML-Strom aus einem XMLStreamReader und erzeugt dabei Objekte in einem TopLogic Modell und verknüpft sie untereinander. Für verschiedene Bereiche der XML-Importdatei sind unterschiedliche Handler-Implementierungen zuständig. Ihre Interaktion wird duch die Import-Definitionsdatei gesteuert.

Dispatch

Die zentrale Steuerung übernimmt der <dispatch>-Handler. Er enthält eine Unterkonfiguration für jedes im aktuellen Kontext zu erwartende Tag. Je nachdem welches Tag er im Eingabestrom sieht, leitet er an den im Kontext dieses Tags definierten Handler weiter.

Der folgende Handler kann zwischen den Tags <foo> und <bar> unterscheiden. Der Inhalt eines <foo> Tags würde von dem Hander verarbeitet, der im Inhalt von <tag name="foo"> definiert wäre. Entsprechend würde der Inhalt eines <bar> Tags von dem Handler verarbeitet werden, der im Inhalt von <tag name="bar"> definiert wäre.

<dispatch>
  <tag name="foo">
    ...
  </tag>
  <tag name="bar">
    ...
  </tag>
</dispatch>

Objekt-Anlage

Es gibt Handler für die Anlage von Fachobjekten. Diese greifen nicht auf die XML-Eingabe zu, sondern werden im Kontext von anderen Handlern (z.B. dem Dispatch) aufgerufen.

Der <object>-Handler legt ein Fachobjekt von einem bestimmter Modell-Typ an. Das Füllen von Eigenschaften und die Verknüpfung mit anderen Fachobjekten übernehmen Handler, die im Kontext des <object>-Handlers definiert sind.

<object model-type="my.module:MyType">
   ...
</object>

Das neu angelegte Objekt wird dabei auf einen Stack gelegt und steht allen Handlern, die im Kontext des <object>-Handlers definiert sind, als Kontext-Objekt zur Verfügung.

Siehe: Konfiguration.

Zuweisen von Werten

Ein eigener Handler übernimmt die Übersetzung von XML-Inhalt in Attributwerte eines angelegeten Objekts. Mit dem <property>-Handler lässt sich ein XML-Attribut in eine Objekt-Eigneschaft des Kontext-Objektes zuweisen. Wenn die Objekt-Eigenschaft nicht string-wertig ist, kann optional ein Format angegeben werden, das die Umrechnung des XML-Attributs in den Fachobjektwert übernimmt.

<property name="myProp" xml-attribute="my-attr" />

Siehe: Konfiguration.

Ganz ähnlich funktioniert der <text-content>-Handler. Statt den Wert aus einem XML-Attribut zu nehmen, ließt dieser Handler den textuellen Inhalt des aktuellen XML-Tags und weißt diesen der Objekteigenschaft zu. Auch hier kann optional ein Format angegeben werden

<text-content name="myProp"/>

In beiden Fällen können keine Handler im Kontext der Zusweisungshandler spezifiziert werden.

Siehe: Konfiguration.

Verknüpfung von Objekten

Objekte, die während des Imports angelegt werden, können gesteuert durch die XML-Eingabe untereinander verknüpft werden. Hierdurch werden Referenzen, die in der XML-Eingabe durch Identifier realisiert sind, in echte Modell-Verknüpfungen übersetzt.

<linking>
  <list-linking name="my.module:MyType#myListRef"/>
</linking>

Die Objekt-Verknüpfung realisiert der <linking>-Handler. Standardmäßig verknüpft er die zwei obersten Objekte im Kontext-Stack. Wie die Verknüpfung konkret ausgeführt wird, bestimmen sog. Linkings, die in seinem Kontext definiert werden können. Sind mehrere Linkings definiert, wird das erste Linking ausgeführt, das zu den zu verknüpfenden Objekten passt. Das <list-linking> fügt das Kontext-Objekt zu der angegebenen Multi-Referenz seines Kontext-Objektes hinzu. Das Linking wird nur ausgeführt, wenn das Objekt, dessen Referenz modifiziert oder gesetzt werden soll von einem zu der spezifizierten Referenz passenden Typ ist. Eine Alternative zum <list-linking> ist das <ref-linking> für die Zuweisung von Zu-Eins-Referenzen.

Siehe: Konfiguration und Linkings.

Rekursion

Rekursive Strukturen können über den Aufruf von im Kontext definierten Handlern realisiert werden. Hierbei wird der Handler, der z.B. im Kontext eines gelesenen Tags ausgeführt werden soll nicht explizit in der Import-Definition hingeschrieben, sondern referenziert. Wenn hierbei ein Handler referenziert wird, der selbst im Kontext definiert ist, findet eine Rekursion statt und es können beliebig tiefe Strukturen verarbeitet werden.

<dispatch id="tree">
  <tag name="node">
    <object model-type="test.tree:Node">
      <property name="name" xml-attribute="name"/>
      <linking>
        <list-linking name="test.tree:Node#children"/>
      </linking>
      <ref handler-id="tree"/>
    </object>
  </tag>
</dispatch>

In obiger Definition ist dem äußersten Handler die ID tree zugewiesen. Der innerste Handler ruft diesen Handler wieder auf und kann so dieselbe Struktur im Kontext des gelesenen Objektes wieder einlesen. Auf diese Art kann der so konfigurierte Importer Strukturen wie die folgende in einen Baum von Objekten übersetzen:

<node name="A">
  <node name="A.1"/>
  <node name="A.2">
    <node name="A.2.1"/>
  </node>
</node>

Siehe: Konfiguration.

Weitere Handler

Weitere Handler und deren Konfiguration findet man in der API-Dokumentation.