Wrath
Wrath

Reputation: 683

Set the i-th document's field in DocumentList to String

Platform: SoftwareAG WebMethods 8.2 The problem: I have 2 DocumentList's. One of them contains XOPObjects the other Strings. I have to convert XOPObject to String and copy it to the other DocList's correspoding String field. What happens? Nothing. The String field remains entry while the XOPObject's base64string is nicely generated.

Performed steps with Given DocList:A(Source with XOP) DocList:B(Target with String field)

 1. Loop over A
 2. Create Base64String from XOPObject using pub.soap.utils:getXOPObjectContent
 3. Call pub.flow:debugLog to check if the base64String is generated
 4. Generate index variable from $iteration with pub.math:subtractInts as index:=$iteration-1
 5. Perform map step from base64String to B's String field with index set to %index%
 6. After loop
 7. pub.xml:documentToXmlString to generate xml representation of the B document
 8. pub.flow:debugLog
 9. Nothing is in the String field...

Any idea what is going wrong in here?

Upvotes: 3

Views: 6902

Answers (3)

Mektoub
Mektoub

Reputation: 125

Perhaps you can generate a String list as the loop output array and then, outside the loop, map the output String list to B's field ?

Upvotes: 0

Adhiraj
Adhiraj

Reputation: 81

I am not sure if you are still looking for an answer to this. I remember I had the same issue once. The issue comes due to the mapping between the object type and string. So within the map you would have mapped the object type to string as we expect it to contain the base64String during runtime.

You can try by replacing the variable name in the target doc list instead of direct mapping.

Upvotes: 0

Lachlan Dowding
Lachlan Dowding

Reputation: 4546

In a webMethods Integration Server flow service, a loop has two properties to identify the lists to iterate over: an input array, which is mandatory, and an output array, which is optional.

The way a loop step works is that it only preserves changes made to the items in the input and output arrays; if you change items in any other lists in the pipeline, those changes are lost when the loop step exits. This is just the way it works.

Quoting from page 198 of the webMethods Developer User's Guide:

Specifying the Input Array

The LOOP step requires you to specify an input array that contains the individual elements that will be used as input to one or more steps in the LOOP. At run time, the LOOP step executes one pass of the loop for each member in the specified array. For example, if you want to execute a LOOP for each line item stored in a purchase order, you would use the document list in which the order’s line items are stored as the LOOP’s input array.

You specify the name of the input array on the LOOP step’s Properties panel. The array you specify can be any of the following data types: * String list * String table * Document list * Object list

The LOOP step executes once for each member of the array specified in Input array.

When you design your flow, remember that because the services within the loop operate against individual elements in the specified input array, they must be designed to take elements of the array as input, not the entire array.

Loop Step Properties

For example, if your LOOP executes against a document list called LineItems that contains children called Item, Qty, and UnitPrice, you would specify LineItems as the Input array for the LOOP step, but services within the loop would take the individual elements of LineItems (for example, Item, Qty, UnitPrice, and so forth) as input.

Collecting Output from a LOOP Step

If your LOOP step produces an output variable, the server can collect that output into an array in the pipeline.

To do this, you use the Output array parameter to specify the name of the array variable into which you want the server to collect output for each iteration of the loop. For example, if your loop checks inventory status of each line item in a purchase order and produces a String called InventoryStatus each time it executes, you would specify InventoryStatus as the value of Output array. At run time, the server will automatically transform InventoryStatus to an array variable that contains the output from each iteration of the loop.

To collect output from each pass of the loop, specify the name of the output variable that you want the server to collect for each iteration.

Given all that, there are actually a few different ways to tackle your problem:

  1. Specify your second Document List variable name in the output array property of the loop step. Doing this will preserve the changes you make to the second Document List when the loop step exits.

  2. Take a copy of your first Document List (the one with the XOPObject objects) in a map step prior to the loop step, and then loop over the copy instead of the original and mutate the copy's items inline.

  3. Use pub.list:appendToDocumentList or pub.list:appendToStringList to construct a new Document List or String List respectively in the loop step. This requires more code, and in your case isn't necessary since you want the output list to include an item for every item in the input list, but is useful when you are filtering out input list items (ie. the resulting output list will be a subset of the input list).

Upvotes: 1

Related Questions