1. Problem
The structure of a
message from a source system you are integrating with contains multiple
repeating record types. You must map each of these record types into one
record type in the destination system. In order for the message to be
imported into the destination system, a transformation must be applied
to the source document to consolidate, or standardize, the message
structure.
2. Solution
Create a map that utilizes the BizTalk Server Looping functoid, by taking the following steps:
Click
the Toolbox, and then click the Advanced Functoids tab. On the map
surface, between the source and destination schemas, drag and drop a
Looping functoid. This functoid accepts 1 to 100 repeating source
records (or data elements) as its input parameters. The return value is a
reference to a single repeating record or data element in the
destination schema.
Connect the left side of the Looping functoid to the multiple repeating source data elements that need to be consolidated.
Connect
the right side of the Looping functoid to the repeating destination
data element that contains the standardized data structure.
3. How It Works
An example of a map that uses the Looping functoid is shown in Figure 1.
In this example,
multiple types of plane flight reservations are consolidated into a
single list of records capturing passengers and their associated seats.
The XML snippet in Listing 1 represents one possible instance of the source schema.
Example 1. Source Schema Instance for the Looping Functoid Example
<ns0:PassengerReservations xmlns:ns0="http://LoopingFunctoid.PassengerReservations"> <FlightNumber>666</FlightNumber> <OnlineReservation> <Name>Lucifer Smith</Name> <Seat>13A</Seat> <Website>www.greatdeals.com</Website> <Confirmed>True</Confirmed> </OnlineReservation> <OnlineReservation> <Name>Beelzebub Walker, Jr.</Name> <Seat>13B</Seat> <Website>www.hellofadeal.com</Website> <Confirmed>False</Confirmed> </OnlineReservation> <TravelAgentReservation> <PassengerName>Jim Diablo</PassengerName> <Seat>13C</Seat> <AgentName>Sunny Rodriguez</AgentName> </TravelAgentReservation> <AirlineReservation> <Name>Imin Trouble</Name> <Seat>13D</Seat> <BookingDesk>Chicago</BookingDesk> </AirlineReservation> </ns0:PassengerReservations>
|
Based on this source XML, the looping map displayed in Figure 3-35 will produce the XML document shown in Listing 2, containing a single passenger seat assignment list.
Example 2. Destination Schema Instance for the Looping Functoid Example
<ns0:Manifest FlightNumber="666" xmlns:ns0="http://LoopingFunctoid.Manifest"> <Passenger Name="Lucifer Smith" SeatNumber="13A" /> <Passenger Name="Beelzebub Walker, Jr." SeatNumber="13B" /> <Passenger Name="Jim Diablo" SeatNumber="13C" /> <Passenger Name="Imin Trouble" SeatNumber="13D" /> </ns0:Manifest>
|
This example displays a
simplistic but useful scenario in which the Looping functoid can be
used. Essentially, this functoid iterates over the specified repeating
source records (all those with a link to the left side of the functoid),
similar to the For...Each structure in coding languages, and maps the desired elements to a single repeating record type in the destination schema.
NOTE
The four source records in the XML instance (the two OnlineReservations records, the one TravelAgentReservation record, and the one AirlineReservation
record) produced four records in the output XML. If the source instance
had contained five records, the resulting output XML document would
also contain five records.
Based on this simple principle,
you can develop much more complex mappings via the Looping functoid.
One example of a more advanced use of the Looping functoid is
conditional looping. This technique involves filtering which source
records actually create destination records in the resulting XML
document. The filtering is done by adding a logical functoid to the map,
which produces a true or false
Boolean value based on the logic. Common examples of filtering are
based on elements that indicate a certain type of source record, or
numeric elements that posses a certain minimum or maximum value.
The previous flight
reservation example can be extended to implement conditional looping, in
order to map only those online reservations that have been confirmed.
This can be accomplished via the following steps:
Click
the Toolbox, and click the Logical Functoids tab. On the map surface,
in between the source and destination schemas, drag and drop a logical
Equal functoid. This functoid accepts two input parameters, which are
checked for equality. The return value is a Boolean true or false.
Specify the second input parameter for the logical Equal functoid as a constant with a value of True.
Connect
the left side of the logical Equal functoid to the data element whose
value is the key input for the required decision (Confirmed in the OnlineReservation node, in this case) logic.
Connect
the right side of the logical Equal functoid to the element in the
destination schema containing the repeating destination data element
that contains the standardized data structure.
An example of the enhanced map is shown in Figure 2.
Based on the same source XML outlined earlier in Listing 1, the looping map displayed in Figure 2
will produce the following XML document, containing a single passenger
seat assignment list with only three passengers (Lauren Jones's
reservation, which was not confirmed, is filtered out by the conditional
looping logic):
<ns0:Manifest FlightNumber="666" xmlns:ns0="http://LoopingFunctoid.Manifest">
<Passenger Name="Lucifer Smith" SeatNumber="13A" />
<Passenger Name="Jim Diablo" SeatNumber="13C" />
<Passenger Name="Imin Trouble" SeatNumber="13D" />
</ns0:Manifest>
NOTE
Due to the fact that the Confirmation element is not being mapped over to the destination schema, the output of the logical Equal functoid is tied to the Passenger
record. If the logical Equal functoid were being applied to an element
that is being mapped to the destination schema, such as the Seat element, the output of the Equal functoid could be tied directly to the SeatNumber element in the destination schema.
In this example of
conditional looping, the second input parameter of the logical Equal
functoid is a hard-coded constant set to True.
In real-world scenarios, it may not be ideal for this value to be
hard-coded. You may prefer to have it driven off a configurable value.
Several alternatives exist:
Implement a
Scripting functoid to the map, which passes the name of a configuration
value to an external assembly. This external assembly would then handle
the lookup of the actual configuration value.
Implement
a Database Lookup functoid, which as the name implies, would look up
the appropriate configuration value from a database table.
Use
a custom functoid, written in any .NET-compliant language. This option
is similar to the external assembly route, except that it is implemented
specifically as a functoid as opposed to a general .NET assembly.
When implementing a map that
uses the Looping functoid, it is important to understand how BizTalk
Server inherently handles repeating records in the source schema. If a
record in the source schema has a Max Occurs
property set to a value greater than 1, BizTalk Server handles the
record via a loop. No Looping functoid is required for the map to
process all appropriate source records. A Looping functoid is needed
only to consolidate multiple repeating source records into a single
repeating destination record.