Zum Inhalt

Datendefinitionsmodell - Fortgeschrittene Elemente

Dieses Dokument behandelt fortgeschrittene Funktionen und Elemente in den Datendefinitionsmodellen von DATAMIMIC. Stelle sicher, dass Du mit den Kern-Elementen der Datendefinition vertraut bist, bevor Du in diese fortgeschrittenen Funktionen eintauchst.

Komplexe Datenstrukturen

<nestedKey>

Das <nestedKey>-Element definiert verschachtelte Schlüsselfelder und deren Generierungsmethoden innerhalb einer Datengenerierungsaufgabe. Es ermöglicht Dir, komplexe Daten in einem hierarchischen Format zu strukturieren, wie Wörterbücher (dict) oder Listen (list), und deren Inhalt dynamisch zu steuern.

Siehe die detaillierte nestedKey Referenz.

<reference>

Das <reference>-Element ermöglicht das Referenzieren anderer generierter Daten.

Attribute

  • name: Gibt den Namen der Referenz an.
  • source: Gibt die Quelle der Referenz an.
  • sourceType: Gibt den Typ der Quelle an.
  • sourceKey: Gibt den Schlüssel der Quelle an.
  • unique: Stellt sicher, dass die Referenz einzigartig ist.

<list>

Das <list>-Element definiert eine Sammlung von Datenelementen, wobei jedes Element seine eigenen Attribute, Schlüssel und Arrays enthalten kann. Listen sind nützlich, um strukturierte Daten darzustellen, wie Zeilen in einer Tabelle oder Sammlungen von Objekten mit gemeinsamen Attributen. Das <list> kann mehrere <item>-Elemente enthalten, die einzelne Einträge darstellen.

Siehe die detaillierte Listenelement-Referenz.

<item>

Siehe die detaillierte Item-Element-Referenz.

<array>

Das <array>-Element definiert Arrays von Datenelementen, die entweder statisch definiert oder dynamisch mit Skripten generiert werden können. Arrays sind unerlässlich, wenn Du mehrere Elemente desselben Datentyps generieren musst, wie Listen von Werten, und können mit anderen Elementen wie <list>, <key> und <nestedKey> kombiniert werden, um komplexe Datenstrukturen zu erstellen.

Siehe die detaillierte Array-Element-Referenz.

Steuerelemente

<condition>

Das <condition>-Element wird verwendet, um eine Reihe von untergeordneten Tags (<if>, <else-if> und <else>) basierend auf spezifischen logischen Bedingungen auszuführen. Es bietet eine Möglichkeit, den Datengenerierungsprozess zu steuern, indem Bedingungen angewendet werden, die bestimmen, welche Elemente in der Ausgabe enthalten sein werden.

Struktur

  • Das <if>-Tag ist immer das erste Kind eines <condition>-Elements und definiert die primäre Bedingung.
  • Null oder mehr <else-if>-Tags können auf das <if> folgen, wobei jedes zusätzliche Bedingungen angibt, die ausgewertet werden, wenn die vorherigen Bedingungen nicht erfüllt sind.
  • Das <else>-Tag ist optional und bietet eine Ausweichaktion, wenn keine der vorherigen Bedingungen erfüllt sind.

Regeln

  • Ein <condition>-Element muss ein <if>-Tag haben.
  • Es kann null oder mehr <else-if>-Tags geben.
  • Nur ein <else>-Tag ist erlaubt und es muss als letztes Kind des <condition>-Elements erscheinen.

Kindelemente

  • if: Definiert die primäre Bedingung zur Auswertung.
  • else-if: Definiert zusätzliche Bedingungen zur Überprüfung, wenn die vorherigen Bedingungen falsch sind.
  • else: Ausweichaktion, wenn keine der Bedingungen erfüllt ist.

Attribute

  • condition: Ein Python-ähnlicher Ausdruck, der zu True oder False ausgewertet wird. Das Ergebnis bestimmt, ob der Inhalt innerhalb des entsprechenden Tags ausgeführt wird.

Beispiel 1: Einfache Bedingung mit If-Else-Logik

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<condition>
    <if condition="category_id == 'DRNK/ALCO'">
        <echo>Kategorie: DRNK/ALCO</echo>
    </if>
    <else-if condition="category_id == 'FOOD/CONF'">
        <echo>Kategorie: FOOD/CONF</echo>
    </else-if>
    <else>
        <echo>Kategorie nicht gefunden</echo>
    </else>
</condition>

In diesem Beispiel wird basierend auf dem Wert von category_id die entsprechende Nachricht gedruckt.

  • Wenn category_id 'DRNK/ALCO' ist, wird der erste <if>-Block ausgeführt.
  • Wenn category_id 'FOOD/CONF' ist, wird der <else-if>-Block ausgeführt.
  • Wenn keine Bedingung erfüllt ist, wird der <else>-Block ausgeführt.

Beispiel 2: Komplexe Bedingung mit verschachtelten Schlüsseln und Standardwerten

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<setup>
    <generate name="group_name_not_override" count="10">
        <variable name="ifVar" generator="BooleanGenerator"/>
        <variable name="elseIfVar" generator="BooleanGenerator"/>

        <condition>
            <if condition="ifVar">
                <key name="if_true" constant="true"/> <!-- Generiert, wenn ifVar = True -->
            </if>
            <else-if condition="elseIfVar">
                <key name="else_if_true" constant="true"/> <!-- Generiert, wenn ifVar = False und elseIfVar = True -->
            </else-if>
            <else>
                <key name="else_true" constant="true"/> <!-- Generiert, wenn ifVar = False und elseIfVar = False -->
            </else>
        </condition>
    </generate>
</setup>

In diesem Beispiel werden zwei Variablen (ifVar und elseIfVar) mit einem Boolean-Generator generiert, und abhängig von ihren Werten wird eines der <key>-Elemente (if_true, else_if_true oder else_true) generiert.

  • Wenn ifVar True ist, wird if_true generiert.
  • Wenn ifVar False und elseIfVar True ist, wird else_if_true generiert.
  • Wenn beide Bedingungen False sind, wird else_true generiert.

Beispiel 3: Bedingungen mit verschachtelten Strukturen

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<setup>
    <generate name="bike" count="10">
        <key name="id" type="int" generator="IncrementGenerator"/>
        <key name="year" type="int" values="1970, 2023"/>

        <!-- Bedingte verschachtelte Schlüsselgenerierung -->
        <nestedKey name="condition_true" type="dict" condition="True">
            <key name="serial" type="int" condition="id % 2 == 1"/>
            <key name="count" type="int" generator="IncrementGenerator"/>
        </nestedKey>

        <condition>
            <if condition="True">
                <nestedKey name="if_true" type="dict">
                    <key name="id" type="int"/>
                </nestedKey>
            </if>
            <else-if condition="False">
                <nestedKey name="if_false" type="dict">
                    <key name="id" type="int"/>
                </nestedKey>
            </else-if>
        </condition>
    </generate>
</setup>

In diesem Beispiel:

  • Der condition_true verschachtelte Schlüsselblock wird immer ausgeführt, weil seine Bedingung True ist.
  • Der bedingte Block innerhalb von <condition> führt den <if>-Block aus, weil seine Bedingung True ist, während der <else-if> ignoriert wird, da er False auswertet.

Beispiel 4: Bedingungen mit Standardwerten

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<setup>
    <generate name="condition" count="10">
        <key name="id" generator="IncrementGenerator"/>

        <condition>
            <if condition="id == 1">
                <echo>Bedingung erfüllt: id ist 1</echo>
                <key name="if_true" constant="1"/>
            </if>
            <else-if condition="id == 3">
                <echo>Bedingung erfüllt: id ist 3</echo>
                <key name="else_if_3_true" constant="3"/>
            </else-if>
            <else-if condition="id == 4">
                <echo>Bedingung erfüllt: id ist 4</echo>
                <key name="else_if_4_true" constant="4"/>
            </else-if>
            <else>
                <echo>Bedingung nicht erfüllt, Fortsetzung mit Standardwerten</echo>
                <key name="else_true" constant="else_value"/>
            </else>
        </condition>
    </generate>
</setup>

Hier überprüft die bedingte Logik den Wert von id:

  • Wenn id 1 ist, wird der Schlüssel if_true generiert.
  • Wenn id 3 oder 4 ist, wird der entsprechende else_if-Block ausgeführt.
  • Wenn keine Bedingungen übereinstimmen, wird der Schlüssel else_true mit einem Fallback-Wert generiert.

Beispiel 5: Bedingte Entfernung von Elementen

1
2
3
4
5
<setup>
    <generate name="group_name_not_override" count="10">
        <key name="removeElement" script="" defaultValue="{}" condition="False"/>
    </generate>
</setup>

In diesem Fall wird der Schlüssel removeElement nicht generiert, weil die condition auf False gesetzt ist.

Beispiel 6: Verwendung von Standardwerten in bedingten NestedKeys

1
2
3
4
5
6
7
<setup>
    <generate name="bike" count="10">
        <nestedKey name="condition_false" type="dict" condition="False" defaultValue="None">
            <key name="serial" type="int" condition="id % 2 == 1"/>
        </nestedKey>
    </generate>
</setup>
  • Da die condition False ist, nimmt der verschachtelte Schlüssel condition_false den defaultValue von None.

Beste Praktiken für die Verwendung von <condition>

  1. Verwende Bedingungen zur Steuerung der Ausgabe: Bedingungen sind eine hervorragende Möglichkeit, die Generierung von Datenelementen dynamisch auf der Grundlage des aktuellen Zustands von Variablen zu steuern.

  2. Fallbacks mit Standardwerten: Verwende Standardwerte, wenn Du einen Fallback bereitstellen möchtest, falls eine Bedingung zu False ausgewertet wird.

  3. Kombiniere mit verschachtelten Strukturen: Du kannst Bedingungen mit verschachtelten Schlüsseln, Listen und Arrays verwenden, um komplexe, logikgesteuerte Datenmodelle zu erstellen.

  4. Verwende else-if für mehrere Bedingungen: Um mehrere mögliche Zustände zu behandeln, verwende eine Kombination aus <if>, <else-if> und <else>, um alle Szenarien abzudecken.

<echo>

Das <echo>-Element gibt Text, Variablen oder Ausdrücke für Protokollierung, Debugging oder Überwachungszwecke aus. Dies kann hilfreich sein, um den Fortschritt der Datengenerierung zu verfolgen oder die Werte von Variablen während der Laufzeit zu inspizieren. Es akzeptiert dynamische Inhalte, einschließlich Variablen und Ausdrücke, die in {} eingeschlossen sind.

Attribute

  • text: Der statische oder dynamische Inhalt, der gedruckt werden soll. Dynamische Werte sind in {} eingefasst, was es Dir ermöglicht, Variablen, Ausdrücke oder Ergebnisse von Funktionen während der Ausführung auszugeben.

Verwendung

  • Verwende <echo>, um die Werte von Variablen auszudrucken oder den Ablauf des Setup-Prozesses zu verfolgen.
  • Es kann Text auf die Konsole oder in Logdateien ausgeben, abhängig vom Ziel, das im Setup definiert ist.

Beispiel 1: Grundlegende Verwendung für Debugging

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<setup>
    <variable name="user" source="dbPostgres" cyclic="False"
              selector="SELECT id, text FROM public.db_postgres_test_query_setup_context_variable"
              distribution="ordered"/>

    <variable name="all_users" source="dbPostgres" cyclic="False"
              iterationSelector="SELECT id, text FROM public.db_postgres_test_query_setup_context_variable"/>

    <echo>user ist ein DotableDict: {user}</echo>
    <echo>all_users ist eine Liste von Dicts: {all_users}</echo>
</setup>

In diesem Beispiel:

  • Das <echo>-Tag druckt den aktuellen Wert der Variable user, die ein DotableDict ist.
  • Es druckt auch die Variable all_users, die eine Liste von Wörterbüchern ist, die aus der Datenbank abgerufen wurden.

Beispiel 2: Verwendung von Echo zum Debuggen von skriptgesteuerten Variablen

1
2
3
4
5
6
7
<setup>
    <variable name="random_number" generator="RandomNumberGenerator(min=1, max=100)"/>
    <echo>Generierte Zufallszahl: {random_number}</echo>

    <key name="status" script="random_number > 50 ? 'High' : 'Low'"/>
    <echo>Der Status basierend auf random_number ist: {status}</echo>
</setup>

In diesem Beispiel:

  • Eine Zufallszahl wird generiert und zum Debuggen ausgegeben.
  • Der Status wird dann basierend auf der Zufallszahl berechnet, und das Ergebnis wird mit <echo> gedruckt.

Beste Praktiken für die Verwendung von <echo>

  1. Debugge komplexe Logik: Verwende <echo>, um Variablen und komplexe Ausdrücke zu debuggen, insbesondere wenn Du Skripte oder Datenbankquellen verwendest, um Daten dynamisch zu generieren.
  2. Überwache die Datengenerierung: Verfolge den Fortschritt Deiner Datengenerierung, indem Du Werte an Schlüsselpunkten in Deinem Setup ausgibst.
  3. Kombiniere mit Variablen: Du kannst Variablen und Ausdrücke innerhalb des Textes von <echo> verwenden, um dynamische Inhalte während des Generierungsprozesses auszugeben.

<generator>

Das <generator>-Element gibt benutzerdefinierte Generatoren für die Datengenerierung an.

Attribute

  • name: Gibt den Namen des Generators an.
  • generator: Gibt Deinen benutzerdefinierten Generator an.

Beispiel

1
2
3
4
5
6
7
8
<setup>
    <generator name="my_custom_date_gen" generator="DateTimeGenerator(min='2010-08-01', max='2020-08-31', input_format='%Y-%m-%d')"/>
    <generate name="product">
        <key name="product_name" type="string"/>
        <key name="import_date" generator="my_custom_date_gen"/>
        <key name="export_date" generator="my_custom_date_gen"/>
    </generate>
</setup>

<element>

Das <element>-Element gibt untergeordnete Elemente innerhalb eines XML-Knotens an, was es nützlich macht, um verschachtelte XML-Strukturen zu generieren. Der Name des <element>-Tags wird zu einem XML-Attribut, und der generierte Inhalt wird zum Wert des Attributs.

Attribute

  • name: Gibt den Namen des untergeordneten XML-Elements oder Attributs an. Dies ist obligatorisch.
  • script: Gibt ein Skript an, um den Wert des Elements dynamisch zu generieren.
  • constant: Ein konstanter Wert für das Element, falls keine dynamische Generierung erforderlich ist.
  • values: Eine Liste möglicher Werte, aus denen zufällig ausgewählt werden kann, falls zutreffend.

Beispiel 1: Einfache XML-Generierung

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<setup>
    <generate name="generate_xml" count="2" target="XML">
        <variable name="person" entity="Person"/>
        <key name="author" script="None">
            <element name="name" script="person.name"/>
            <element name="gender" script="person.gender"/>
            <element name="birthdate" script="person.birthdate"/>
        </key>
    </generate>
</setup>

In diesem Beispiel:

  • Der Schlüssel author erstellt einen XML-Knoten, und jedes <element> darin definiert Attribute (wie name, gender, birthdate), die mit den Werten der person-Entität gefüllt werden.

Beispiel 2: NestedKey mit Elementen und Attributen

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<setup>
    <generate name="part_list" count="1" target="XML">
        <nestedKey name="book" type="list" count="4">
            <element name="title" values="'Book 1', 'Book 2', 'Book 3', 'Book 4'"/>
            <element name="language" values="'de', 'en'"/>
            <element name="pages" generator="IntegerGenerator(min=100,max=800)"/>
            <element name="release_date" generator="DateTimeGenerator(min='2020-01-01', max='2023-12-31', input_format='%Y-%m-%d')"/>
        </nestedKey>
    </generate>
</setup>

Hier:

  • Die book Liste erzeugt mehrere XML-Elemente (title, language, pages, release_date), jedes mit Attributen für verschiedene Bücher.
  • Der Inhalt für jedes Element wird dynamisch basierend auf Werten oder Generatoren erzeugt.

Beispiel 3: Generierung von XML mit verschachtelten Listen und Wörterbüchern

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<setup>
    <generate name="part_dict" count="1" target="XML">
        <nestedKey name="book" type="dict">
            <key name="title" values="'Book 1', 'Book 2'">
                <element name="language" values="'de', 'en'"/>
            </key>
            <key name="pages" generator="IntegerGenerator(min=100,max=800)"/>
            <key name="release_date" generator="DateTimeGenerator(min='2020-01-01', max='2023-12-31', input_format='%Y-%m-%d')"/>
        </nestedKey>
        <nestedKey name="magazine" type="dict">
            <key name="title" values="'Magazine #1', 'Magazine #2'"/>
            <key name="language" values="'de', 'en'"/>
            <key name="pages" generator="IntegerGenerator(min=30,max=70)"/>
        </nestedKey>
    </generate>
</setup>

In diesem Fall:

  • Sowohl Bücher als auch Magazine werden als XML-Elemente mit dynamisch generierten Attributen wie language, pages und release_date erzeugt.

Beispiel 4: Generierung von XML mit Arrays und Listen

1
2
3
4
5
6
<setup>
    <generate name="array_xml" count="2" target="XML">
        <array name="random_string" type="string" count="3"/>
        <array name="random_number" type="int" count="3"/>
    </generate>
</setup>

In diesem Beispiel:

  • Zwei Arrays (random_string und random_number) werden als XML-Elemente generiert, wobei jedes Array 3 Elemente enthält.
  • Dies demonstriert, wie Arrays in den XML-Generierungsprozess integriert werden können.

Beispiel 5: Komplexes XML mit Listen und NestedKeys

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<setup>
    <generate name="list_xml" count="1" target="XML">
        <list name="detail">
            <item>
                <key name="number" type="int" constant="2"/>
            </item>
            <item>
                <key name="text" type="string"/>
            </item>
            <item>
                <nestedKey name="employees" type="list" count="2">
                    <key name="code" type="string"/>
                    <key name="age" values="25, 30, 28, 45"/>
                </nestedKey>
            </item>
        </list>
    </generate>
</setup>

Dieses Beispiel zeigt, wie man eine Liste von Elementen generiert, wobei jedes Element zusätzliche verschachtelte Schlüssel und Unterelemente enthalten kann, was eine hierarchische Struktur in XML demonstriert.

Beispiel 6: Generierung von XML aus einer Vorlage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<setup>
    <generate name="product" source="data/user.template.xml" target="ConsoleExporter, XML">
        <nestedKey name="xga:dgu.gewerbemeldung.0230">
            <element name="new_key" constant="new_key_value"/>
            <nestedKey name="bn-g2g:nachrichtenkopf.g2g">
                <element name="new_key2" constant="new_key_value2"/>
                <key name="bn-g2g:identifikation.nachricht" constant="abc"/>
            </nestedKey>
        </nestedKey>
        <key name="additionalTag" constant="extra">
            <element name="new_key" constant="new_key_value"/>
            <element name="new_key1" constant="new_key_value1"/>
        </key>
        <list name="array">
            <item>
                <key name="additionalTag" constant="extra">
                    <element name="new_key" constant="new_key_value"/>
                </key>
            </item>
        </list>
    </generate>
</setup>

In diesem Fall:

  • Die XML-Generierung basiert auf einer vordefinierten Vorlage (data/user.template.xml), und die Struktur wird dynamisch erweitert mit nestedKey, key und list Elementen.
  • Dies demonstriert, wie man bestehende XML-Strukturen mit neuen Elementen und Attributen erweitern kann.

Best Practices für die Verwendung von <element>

  1. Verwende <element>, um strukturiertes XML zu erstellen: Das <element>-Tag ist eine flexible Möglichkeit, strukturierte XML-Dokumente zu bauen, bei denen jedes Element und seine Attribute dynamisch generiert oder statisch definiert werden können.
  2. Kombiniere <element> mit anderen Elementen: Verwende das <element>-Tag in Kombination mit <list>, <array> und <nestedKey>, um komplexe XML-Strukturen zu erstellen.
  3. Nutze dynamische Skripte: Nutze das script-Attribut, um Werte für die Elemente dynamisch zu generieren, basierend auf komplexer Logik oder externen Variablen.
  4. Verwende constant für feste Werte: In Fällen, in denen der Wert eines Elements nicht ändern soll, verwende das constant-Attribut.