Altova MapForce 2024 Basic Edition

Wenn ein Node in einer XML-Komponente Child-Nodes hat, können sowohl der Name als auch der Wert jedes einzelnen Child-Node direkt im Mapping abgerufen werden. Diese Methode wird als "dynamische Node-Namen" bezeichnet. "Dynamisch" bezieht sich darauf, dass die Verarbeitung "on-the-fly" zur Mapping-Laufzeit und nicht auf Basis statischer noch vor Ausführung des Mappings bekannter Schemainformationen erfolgt. In diesem Kapitel wird näher erläutert, wie Sie dynamischen Zugriff auf Node-Namen erhalten und was Sie damit erreichen können.

 

Wenn Daten aus einer Quelldatei ausgelesen werden, bedeutet "dynamische Node-Namen", dass Folgendes möglich ist:

 

Abrufen einer Liste aller Child-Nodes (oder Attribute) eines Node als Sequenz. Eine "Sequenz" in MapForce ist eine Liste von null oder mehr Datenelementen, die mit einer Zielkomponente verbunden werden können, sodass in der Zielkomponente dieselbe Anzahl an Datenelementen wie in der Quelldatei erstellt werden kann. Wenn z.B. ein Node fünf Attribute in der Quelldatei hat, so könnten in der Zieldatei fünf neue Elemente, eines für jedes Attribut, erstellt werden.

Lesen nicht nur der Child-Node-Werte (wie bei einem Standard-Mapping), sondern auch der Namen dieser Nodes.

 

Wenn Daten in eine Zieldatei geschrieben werden sollen, bedeutet "dynamische Node-Namen", dass Folgendes möglich ist:

 

Erstellung neuer Nodes anhand von Namen aus dem Mapping (so genannter "dynamischer" Namen) anstelle von Namen, die von den Komponenteneinstellungen bereitgestellt werden (so genannte "statische" Namen).

 

Zur Veranschaulichung dynamischer Node-Namen wird in diesem Kapitel das folgende XML-Schema verwendet: <Dokumente>\Altova\MapForce2024\MapForceExamples\Products.xsd. Das Beispielinstanzdokument zu diesem Schema ist Products.xml. Um Schema und Instanzdatei zum Mapping-Bereich hinzuzufügen, wählen Sie den Befehl Einfügen | XML-Schema/Datei und navigieren Sie zum Ordner <Dokumente>\Altova\MapForce2024\MapForceExamples\Products.xml. Wenn Sie aufgefordert werden, ein Root-Element auszuwählen, klicken Sie auf products.

 

Um dynamische Node-Namen für den Node product zu aktivieren, klicken Sie mit der rechten Maustaste darauf und wählen Sie einen der folgenden Kontextmenübefehle:

 

Attribute mit dynamischem Namen anzeigen, wenn Sie Zugriff auf die Attribute des Node benötigen

Child-Elemente mit dynamischem Namen anzeigen, wenn Sie Zugriff auf die Child-Elemente des Node benötigen

mf_dynamic_node_names_01

Abb. 1        Aktivieren dynamischer Node-Namen (für Child-Elemente)

Anmerkung:Die oben beschriebenen Befehle stehen nur für Nodes zur Verfügung, die Child-Nodes haben. Außerdem stehen die Befehle auch nicht für Root-Nodes zur Verfügung.

 

Wenn Sie bei einem Node in den dynamischen Modus wechseln, wird ein Dialogfeld wie das unten gezeigte, angezeigt. Wählen Sie für das Beispiel in diesem Kapitel die unten gezeigten Optionen aus; eine nähere Beschreibung zu diesen Optionen finden Sie unter Zugriff auf Nodes eines bestimmten Typs.

mf_dynamic_node_names_02

Abb. 2        Dialogfeld  "Einstellungen für dynamisch benannte Child-Elemente"

In Abb. 3 sehen Sie, wie die Komponente aussieht, wenn dynamische Node-Namen für den product Node aktiviert sind. Beachten Sie, wie sehr sich das Aussehen der Komponente jetzt geändert hat.

 

mf_generic_child_elements

Abb.3 Aktivieren dynamischer Node-Namen (für Elemente)

Um die Komponente wieder zurück in den Standardmodus zu schalten, klicken Sie mit der rechten Maustaste auf den Node product und deaktivieren Sie die Option Child-Elemente mit dynamischem Namen anzeigen im Kontextmenü.

 

In der Abbildung unten sehen Sie, wie dieselbe Komponente aussieht, wenn der dynamische Zugriff auf Attribute eines Node aktiviert ist. Die Komponente wurde durch Rechtsklick auf das Element product und Auswahl des Kontextmenübefehls Attribute mit dynamischem Namen anzeigen definiert.

mf_dynamic_attributes

Abb. 4 Dynamische Node-Namen (für Attribute) sind aktiviert

Um die Komponente wieder zurück in den Standardmodus zu schalten, klicken Sie mit der rechten Maustaste auf den Node product und deaktivieren Sie die Option Attribute mit dynamischem Namen anzeigen im Kontextmenü.

 

Wie Sie in Abbildung 3 und 4 sehen, ändert sich das Aussehen der Komponente, wenn ein Node (in diesem Fall product) in den Modus "dynamischer Node-Name" wechselt. In diesem Modus ist nun Folgendes möglich:

 

Lesen oder Schreiben einer Liste alle Child-Elemente oder -Attribute eines Node. Diese werden vom Datenelement element() bzw. attribute() bereitgestellt.

Lesen oder Schreiben der Namen der einzelnen Child-Elemente oder -Attribute. Der Name wird von den Datenelementen node-name() und local-name() bereitgestellt.

Lesen oder Schreiben des Werts von einzelnen Child-Elementen (bei Elementen) als spezifischer Datentyp. Dieser Wert wird vom Typkonvertierungs-Node (in diesem Fall dem Datenelement text()) bereitgestellt. Beachten Sie, dass nur Elemente Typkonvertierungs-Nodes haben. Attribute werden immer als "String"-Typ behandelt.

Gruppieren oder Filtern generischer Child-Elemente nach Namen.

 

 

Im Folgenden finden Sie eine Beschreibung der Node-Typen, mit denen Sie im Modus "dynamischer Node-Name" arbeiten können.

 

element()

Dieser Node weist in einer Quellkomponente ein anderes Verhalten als in einer Zielkomponente auf. Er stellt in der Quellkomponente die Child-Elemente des Node als Sequenz bereit. In Abb.3 stellt element() eine Liste (Sequenz) aller Child-Elemente von product bereit. Die anhand des folgenden XML-Fragments erstellte Sequenz würde z.B. drei Datenelemente enthalten (da product drei Child-Elemente hat):

 

  <product>

    <id>1</id>

    <color>red</color>

    <size>10</size>

  </product>

 

Beachten Sie, dass der tatsächliche Name und Typ der einzelnen Datenelemente in der Sequenz vom Node node-name() bzw. dem Typkonvertierungs-Node bereitgestellt wird (Beschreibung siehe unten). Um dies zu veranschaulichen, stellen Sie sich vor, Sie müssen Daten folgendermaßen aus einer XML-Quelldatei in eine XML-Zieldatei transformieren:

mff_genericnodes_01

Abb. 6 Mappen von XML-Elementnamen auf Attributwerte (Aufgabe)

Das Mapping, mit dem Sie dies erreichen, sieht folgendermaßen aus:

mf_map_ConvertProducts_04

Abb. 7 Mappen von XML-Elementnamen auf Attributwerte (in MapForce)

Die Rolle von element() ist es hier, die Sequenz von Child-Elementen von product, bereitzustellen, während node-name() und text() den tatsächlichen Namen und Wert der einzelnen Datenelemente in der Sequenz bereitstellen. Zu diesem Mapping gibt es ein Tutorial-Beispiel, das unter Beispiel: Mappen von Elementnamen auf Attributwerte näher beschrieben ist.

 

element() selbst erstellt nichts in der Zielkomponente. Dies stellt eine Ausnahme der Grundregel "Erstelle für jedes Datenelement in der Quellkomponente ein Datenelement in der Zielkomponente" dar. Die eigentlichen Elemente werden (unter Verwendung des Werts von node-name()) durch die Typkonvertierungs- und (unter Verwendung der eigenen Namen) durch die Namensüberprüfungs-Nodes erstellt.

 

attribute()

Wie Sie in Abb. 4 sehen, ermöglicht dieses Datenelement zur Mapping-Laufzeit den Zugriff auf alle Attribute des Node. Es stellt in einer Quellkomponente die Attribute des damit verbundenen Quell-Node als Sequenz bereit. So würde die Sequenz im folgenden XML-Fragment etwas zwei Datenelemente enthalten (da product zwei Attribute hat):

 

  <product id="1" color="red" />

 

Beachten Sie, dass der attribute()-Node nur den Wert der einzelnen Attribute in der Sequenz, und zwar immer als String-Typ, bereitstellt. Der Name der einzelnen Attribute wird vom Node node-name() bereitgestellt.

 

In einer Zielkomponente wird über diesen Node eine verbundene Sequenz verarbeitet und für jedes Datenelement in der Sequenz wird ein Attributwert erstellt. Der Attributname wird vom Node node-name() bereitgestellt. Angenommen, Sie möchten Daten aus einer XML-Quelldatei folgendermaßen in eine XML-Zieldatei transformieren:

mff_genericnodes_02

Abb. 8 Mappen von Attributwerten auf Attributnamen (Aufgabe)

Das Mapping, mit dem Sie dies erreichen, sieht folgendermaßen aus:

mff_genericnodes_02c

Abb. 9 Mappen von Attributwerten auf Attributnamen (in MapForce)

 

Anmerkung:Diese Transformation lässt sich auch ohne Aktivierung des dynamischen Zugriffs auf die Attribute eines Node bewerkstelligen. Hier wird nur gezeigt, wie attribute() in einer Zielkomponente funktioniert.

 

Wenn Sie dieses Mapping nachstellen möchten, verwenden Sie dazu dieselben XML-Komponenten wie im Mapping ConvertProducts.mfd aus dem Ordner <Dokumente>\Altova\MapForce2024\MapForceExamples\. Der einzige Unterschied besteht darin, dass die Zieldatei nun als Quelldatei und die Quelldatei als Zieldatei verwendet wird. Sie benötigen als Input-Daten für die Quellkomponente eine XML-Instanz, die tatsächlich Attribute-Werte enthält, wie z.B.:

 

<?xml version="1.0" encoding="UTF-8"?>
<products>
  <product>
    <attribute name="id" value="1"/>
    <attribute name="color" value="red"/>
    <attribute name="size" value="big"/>
  </product>
</products>

 

Beachten Sie, dass die Namespace- und die Schema-Deklaration im obigen Codefragment aus Gründen der Einfachheit weggelassen wurden.

 

node-name()

In einer Quellkomponente stellt node-name() die Namen der einzelnen Child-Elemente von element() bzw. die Namen der einzelnen Child-Attribute von attribute() bereit. Standardmäßig hat der bereitgestellte Name den Typ xs:QName. Um den Namen als String zu erhalten, verwenden Sie den Node local-name() (siehe Abb. 3).

 

In einer Zielkomponente schreibt node-name() die Namen der einzelnen in element() oder attribute() enthaltenen Elemente bzw. Attribute.

 

local-name()

Dieser Node funktioniert auf dieselbe Art wie node-name() mit dem Unterschied, dass der Typ ist xs:string anstelle von xs:QName.

 

Typkonvertierungs-Node

Der Typkonvertierungs-Node in einer Quellkomponente stellt den Wert der einzelnen in element() enthaltenen Child-Elemente bereit. Der Name und die Struktur dieses Node hängen von dem im Dialogfeld "Einstellungen für dynamisch benannte Child-Elemente" ausgewählten Typ ab (Abb. 2).

 

Um den Typ des Node zu ändern, klicken Sie auf die Schaltfläche Auswahl ändern ( mf_ic_change_selection ) und wählen Sie einen Typ aus der Liste der verfügbaren Typen (darunter auch eine Schema Wildcard (xs:any)) aus. Nähere Informationen dazu finden Sie unter Zugriff auf Nodes eines bestimmten Typs.

 

In einer Zielkomponente wird über den Typkonvertierungs-Node der Wert der einzelnen in element() enthaltenen Child-Elemente als spezifischer Datentyp geschrieben. Der gewünschte Datentyp kann auch hier über die Schaltfläche Auswahl ändern ( mf_ic_change_selection ) ausgewählt werden.

 

Namensüberprüfungs-Nodes

Namensüberprüfiungs-Nodes bieten in einer Quellkomponente eine Möglichkeit, Child-Elemente aus einer Quellinstanz nach Namen zu filtern. Child-Elemente müssen eventuell nach Namen gefiltert werden, um sicherzustellen, dass das Mapping den korrekten Typ verwendet, um auf die Instanzdaten zuzugreifen (siehe Zugriff auf Nodes eines bestimmten Typs).

 

Im Allgemeinen funktionieren Namensüberprüfungs-Nodes beim Lesen und Schreiben von Werten und hierarchisch untergeordneten Strukturen fast wie normale Element-Nodes. Da sich die Mapping-Semantik aber unterscheidet, wenn der dynamische Zugriff aktiviert ist, gibt es einige Einschränkungen. So können Sie etwa die Werte von zwei Namensüberprüfungs-Nodes nicht miteinander verknüpfen.

 

In der Zielkomponente werden für Namensüberprüfungs-Nodes in der Ausgabe so viele Elemente erstellt, wie Datenelemente in der verbundenen Quellsequenz vorhanden sind. Ihr Name setzt den auf node-name() gemappten Wert außer Kraft.

 

Falls erforderlich, können Sie die Namensüberprüfungs-Nodes aus der Komponente ausblenden. Klicken Sie dazu auf die Schaltfläche Auswahl ändern ( mf_ic_change_selection ) neben dem element()-Node. Deaktivieren Sie anschließend im Dialogfeld "Einstellungen für dynamisch benannte Child-Elemente" (Abb. 2) das Kontrollkästchen Name-Test-Nodes ...anzeigen".

© 2017-2023 Altova GmbH