Powered By

Free XML Skins for Blogger

Powered by Blogger

Wednesday, December 31, 2008

useOneAsMany in XI Message Mappings

Use

You require the function useOneAsMany() if a field that only occurs once needs to be replicated as often as another field occurs in the outbound message so that the fields can be written to the target structure in pairs as a record.

Example

In the following test instance in which purchase orders are sent, there are two examples for the use of useOneAsMany():

This graphic is explained in the accompanying text

· The purchase orders (structure nodes order) are first divided by type (external or internal). The field type may only occur once in the structure order. Multiple itemGroup substructures can follow in which different items are listed by their name (field name), which all belong to one category. However, in the target structure, the purchase order type and the name of the item are to be saved in pairs (, , ).

· Equally, there can only be one category (field category) within an itemGroup but multiple named items (field name). The category is also written to the same record as the value of the fields name and type (, , ).

The structure of the source and target messages are described by the following XSD defintions:

Source and Target Structure

Field Name

Occurrence

Field Name

Occurrence

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



Before we look in more detail at how useOneAsMany() is used, let us look at the entire message mapping:

Message Mapping with useOneAsMany()

Target-Field Mapping (and Explanation)

/OrdersByRecords/record=
/OrdersByType/order/itemGroup/name[context=/OrdersByType]

(a record is to be created in the target structure for each occurrence of name)

/OrdersByRecords/record/orderType=
SplitByValue([type=Each value]
useOneAsMany(
/OrdersByType/order/type ,
/OrdersByType/order/itemGroup/name[context=order] ,
/OrdersByType/order/itemGroup/name))

(see below)

/OrdersByRecords/record/itemCategory=
SplitByValue([type=Each value]
useOneAsMany(
/
OrdersByType/order/itemGroup/category ,
/OrdersByType/order/itemGroup/name ,
/OrdersByType/order/itemGroup/name))

(see below)

/OrdersByRecords/record/itemName=
SplitByValue([type=Each value]
/OrdersByType/order/itemGroup/name)

(a context in the source structure can contain multiple name values) One value is to be transferred to each record context in the target structure. Therefore, by using SplitByValue(), you can insert additional context changes.

Example Test Case

Source Instance

Result


external

Guitars
Fender Strat V1
<name>Ovation Light


Percussion
Sticks (Standard)


internal

Harps

Hohner Cross Harp D-Dur


Hohner Pro Harp F-Dur



external

Harps

Hohner Riverboat C-Dur




external


Guitars


Fender Strat V1



external


Guitars


Ovation Light



external


Percussion


Sticks (Standard)



internal


Harps


Hohner Cross Harp D-Dur



internal


Harps


Hohner Pro Harp F-Dur



external


Harps


Hohner Riverboat C-Dur

Adjusting the Queue with useOneAsMany()

The use of useOneAsMany() is now to be explained by using the target-field mapping for the target field orderType:

This graphic is explained in the accompanying text

The function useOneAsMany() has three input parameters:

  • The field that has the occurrence 1..1 is expected as the first parameter; in our example this is type.
  • The field that can occur more than once is expected as the third parameter. In our example, this is name. To make a pair out of type and name, useOneAsMany() must replicate the respective values from the type queue as many times as is necessary to assign the values from the name queue 1:1. The context change takes useOneAsMany() from the name queue.
  • Finally, useOneAsMany() must determine how often different values from the type queue need to be replicated. You specify this value with the second parameter of useOneAsMany() by putting all item names of all itemGroups in the order context for each purchase order (which has either the type external or internal). For example, the first order of type external has two itemGroups. The names Fender Strat V1, Ovation Light, and Sticks (Standard) also belong to the value external. The second parameter determines the value of type, while the third parameter determines the required context change.

This graphic is explained in the accompanying text

To be able to take one value from the result queue of useOneAsMany() for each record, use the function SplitByValue(). It inserts a context change after each value of the result queue.

Using useOneAsMany() to create pairs from category and name functions in the same way.

No comments: