
Die Funktion useOneAsMany() brauchen Sie immer dann, wenn ein Feld mit einfacher Häufigkeit so oft repliziert werden soll, wie ein weiteres Feld in der Ausgangs-Message auftritt, so dass die Felder paarweise als Record in die Zielstruktur geschrieben werden können.
In der folgenden Test-Instanz, in der Bestellungen verschickt werden, gibt es zwei Beispiele für die Verwendung von useOneAsMany() :

Die Bestellungen (Strukturknoten order ) in der Message werden zunächst nach ihrem Typ ( external oder internal ) unterschieden. Das Feld type darf nur ein Mal in der order -Struktur auftreten. Danach kann es mehrere itemGroup -Unterstrukturen geben, in der verschiedene Items über deren Namen (Feld name ) aufgelistet werden, die alle zu einer Kategorie gehören. In der Zielstruktur soll der Bestelltyp und der Name des Items allerdings paarweise abgelegt werden ( <external, Fender Strat V1>, <external, Ovation Light>, <external, Sticks (Standard)> ).
Zugleich kann es innerhalb einer itemGroup nur eine Kategorie (Feld category ), aber mehrere benannte Items (Feld name ) geben. Die Kategorie soll ebenfalls in den gleichen Rec ord geschrieben werden wie der Wert der Felder name und type ( <external, Guitars, Fender Strat V1>, <external, Guitars, Ovation Light>, <external, Percussion, Sticks (Standard)> ).
Die Struktur der Ausgangs- und Ziel-Message sind über folgende XSD-Definitionen beschrieben:
Ausgangs- und Zielstruktur
|
Feldname |
Häufigkeit |
Feldname |
Häufigkeit |
|
OrdersByType |
1..1 |
OrdersByRecords |
1..1 |
|
order |
0..unbounded |
record |
0..unbounded |
|
type |
1..1 |
orderType |
1..1 |
|
itemGroup |
1..unbounded |
itemCategory |
1..1 |
|
category |
1..1 |
itemName |
1..1 |
|
name |
1..unbounded |
Bevor wir uns die Verwendung von useOneAsMany() genauer ansehen, werfen wir einen Blick auf das gesamte Message-Mapping:
Message-Mapping mit useOneAsMany()
|
Zielfeld-Mapping (und Erläuterung) |
|
/OrdersByRecords/record= /OrdersByType/order/itemGroup/ name[context=/OrdersByType] (Es soll für jedes Auftreten von name ein Record in der Zielstruktur entstehen) |
|
/OrdersByRecords/record/orderType= SplitByValue ([type=Each value] useOneAsMany ( /OrdersByType/order/type , /OrdersByType/order/itemGroup/ name[context=order] , /OrdersByType/order/itemGroup/name)) (siehe unten) |
|
/ OrdersByRecords/record/itemCategory= SplitByValue ([type=Each value] useOneAsMany ( / OrdersByType/order/itemGroup/category , /OrdersByType/order/itemGroup/name , /OrdersByType/order/itemGroup/name)) (siehe unten) |
|
/ OrdersByRecords/record/itemName= SplitByValue ([type=E ach value] /OrdersByType/order/itemGroup/name) (n der Ausgangsstruktur können noch mehrere Werte von name in einem Kontext stehen). In der Zielstruktur soll an jeden record-Kontext ein Wert übergeben werden. Mit SplitByValue() können Sie daher zusätzliche Kontextwechsel einfügen. |
Beispiel-Testfall
|
Ausgangs-Instanz |
Ergebnis |
|
<?xml version="1.0" encoding="UTF-8"?> <ns0:OrdersByType xmlns:ns0="http://com.sap/b"> <order> <type>external</type> <itemGroup> <category>Guitars</category> <name>Fender Strat V1</name> < name>Ovation Light</name> </itemGroup> <itemGroup> <category>Percussion</category> <name>Sticks (Standard)</name> </itemGroup> </order> <order> <type>internal</type> <itemGroup> <category>Harps</category> <name> Hohner Cross Harp D-Dur </name> <name> Hohner Pro Harp F-Dur </name> </itemGroup> </order> <order> <type>external</type> <itemGroup> <category>Harps</category> <name> Hohner Riverboat C-Dur </name> </itemGroup> </order> </ns0:OrdersByType> |
<?xml version="1.0" encoding="UTF-8"?> <ns0:OrdersByRecords xmlns:ns0="http://com.sap/b"> <record> <orderType> external </orderType> <itemCategory> Guitars </itemCategory> <itemName> Fender Strat V1 </itemName> </record> <record> <orderType> external </orderType> <itemCategory> Guitars </itemCategory> <itemName> Ovation Light </itemName> </record> <record> <orderType> external </orderType> <itemCategory> Percussion </itemCategory> <itemName> Sticks (Standard) </itemName> </record> <record> <orderType> internal </orderType> <itemCategory> Harps </itemCategory> <itemName> Hohner Cross Harp D-Dur </itemName> </record> <record> <orderType> internal </orderType> <itemCategory> Harps </itemCategory> <itemName> Hohner Pro Harp F-Dur </itemName> </record> <record> <orderType> external </orderType> <itemCategory> Harps </itemCategory> <itemName> Hohner Riverboat C-Dur </itemName> </record> </ns0:OrdersByRecords> |
Anpassen der Queues mit useOneAsMany()
Anhand des Zielfeld-Mappings zum Zielfeld orderType soll nun die Verwendung von useOneAsMany() verdeutlicht werden:
Die Funktion useOneAsMany() hat drei Eingabeparameter:
Als erster Parameter wird das Feld erwartet, dessen Häufigkeit 1..1 ist, in unserem Fall ist dies type .
Als dritter Parameter wird das Feld erwartet, das mehrfach auftreten kann. In unserem Beispiel ist dies name Um Paare von type und name zu bilden, muss useOneAsMany() die jeweiligen Werte aus der type -Queue so oft replizieren bis genügend Werte vorhanden sind, die 1:1 den Werten aus der name -Queue zugeordnet werden können. Die Kontextwechsel übernimmt useOneAsMany() aus der name -Queue.
Schließlich muss useOneAsMany() noch ermitteln, wie oft unterschiedliche Werte aus der type -Queue jeweils repliziert werden müssen. Sie geben dies über den zweiten Parameter von useOneAsMany() an, indem Sie für jede Bestellung (die ja jeweils entweder den Typ external oder internal hat) alle Item-Namen aller itemGroups in den Order-Kontext stellen. Beispielsweise hat die erste Bestellung vom Typ external zwei itemGroups . Zum Wert external gehören also die Namen "Fender Strat V1", "Ovation Light" und "Sticks (Standard)". Anhand des zweiten Parameters wird der Wert von type bestimmt, anhand des dritten Parameters die nötigen Kontextwechsel.

Um für jeden Record jeweils einen Wert aus der Ergebnisqueue von useOneAsMany() übernehmen zu können, verwenden Sie die Funktion SplitByValue() Sie fügt nach jedem Wert der Ergebnisqueue einen Kontextwechsel ein.
Die Verwendung von useOneAsMany() für die Paarbildung von category und name funktioniert analog.