Select children of a CHOICE parent

When defining an XML Business Document, you can create parents of a special kind called choice parents. Such parents are similar to CHOICE elements in XML Schemas: they allow only one of the nodes they contain to be present within the containing node.

Unlike the other usual elements, choice parents are not real nodes of Business Document instances. They are just a definition of what is possible within the document instances. As a consequence, names of choice parents never appear in path to nodes (see chapter Get data from input: Paths to nodes).

Basically, choice parents define alternatives in the contents of a part of a Business Document. Imagine you create an integration that generates delivery notes. Delivery notes usually include contact information that can be used to call the customer, for example, to schedule the delivery. Today, you can communicate to real people using phone, cellular, or even email. The delivery note shall handle all of these:

deliveryNote              1..1
   …
   contactRecord           1..n
      choice
          phone                0..1, class s
          cellular             0..1, class s
          email                0..1, class s

A document defined similar to above can contain multiple contact records which each can be a phone number, a cellular phone number, or an e-mail address. With such a definition, the different types of contacts are segregated and therefore can be better controlled.

Now that the form of the expected delivery note document is defined, you have to setup the rules to generate instances of that document. Your next challenge is how to specify which one among phone, cellular and email nodes you actually want in the instance.

Maybe, your intuition would tell you to use times…do statements on each child to alternatively generate phone, cellular or email. This won’t work in the integration engine. Selection is centralized in the integration engine: the expression attached to the choice node defines which child to generate and expressions attached to children determine their value. The following is an example of a Map to generate delivery notes from an input document:

Output node Bound expression

contactRecord

for each in2:\contact[where item\name = in1:\customer\name]

choice

switch (this\contactTypeId)
{
   case 0,1,8:
      { select 1st }
   case 10 to 50:
      { select 2nd }
   case 99:
      { select 3rd }
   default:
      { exit reject }
}

phone

this\data

cellular

this\data

email

this\data

 

In that example, the document from input in1 contains the name of the addressed customer while the contact information is carried by the document from the input in2.

The expression attached to contactRecord selects contact information from in2 document using the customer name. Contact information from in2 is a set of records that contain the name of the customer (name node) along with the id of the type of contact (contactTypeId node) and the contact data itself (data node).

The job of the Map here is to:

  • Use contactTypeId to determine which child to generate among phone, cellular and email.
  • Place in the generated child the contents of data.

To tell the integration engine to select a specific child of a choice node, you must use a select statement. Those statements are composed of the keyword select followed by the indication of which child to select in the form of a usual English ordinal.

In the previous example, the cellular node is the second child of CHOICE. Telling integration engine to generate it is accomplished thru the statement:

select 2nd

Examine completely the expression attached to the CHOICE node of the previous example:

1   switch (this\contactTypeId)
2   {
3      case 0,1,8:
4         { select 1st }
5      case 10 to 50:
6         { select 2nd }
7      case 99:
8         { select 3rd }
9      default:
10        { exit reject }
11   }

A switch statement starts at line 1. It tests the value of contactTypeId to generate the appropriate child. When the value is 0, 1 or 8, the contact data is a phone number, the phone child is generated as stated by select 1st at line 4. Values from 10 to 50 say the contact is a cellular phone number, so line 6 selects the second child cellular. Value 99 means the contact is an email address: the third child email is generated as stated by line 8.

Lines 9 and 10 define the behavior when an unexpected value of contactTypeId is encountered. In that example, an error is signaled thru the exception mechanism; have a look at chapter Get data from input: Paths to nodes for more information about that concept.

The integration engine checks your expressions for activation of undefined children. This means you receive an error message whenever you specify an out of bounds ordinal in a select statement. In the previous example, select 45th is rejected as well as select 101st. You also receive a warning for children your expression never selects.

But, the integration engine is not clever enough to detect path of execution in expressions that do not select at all. In the previous example, the default case of the switch statement does not select anything but the expression checks successfully.

In the example, since an exception is raised (interrupting the execution), the expression executes correctly. The paths of execution, without any select or exit, leads to undefined behavior.

Related Links