I’ve had an funny issue with multi-dimension looping in IS Developer, and thought I should share it here.
I wanted to loop over a record like this in developer:
– Array1
---- Array2 <— Loop only over Array2
In my situation, the top-level array (‘Array1’) only ever has a single element (i.e. only ‘Array1[0]’ exists).
So I tried a single LOOP with the in-array set to ‘/Array1[0]/Array2’. However, this gave me strange results.
The end result was that I had to code two loops - the outer being a dummy loop over Array1 with only one iteration
– LOOP over Array1 (exit after one iteration)
---- LOOP over Array2
What if Array1 has more than one element? It seems you have the situation controlled in this particular instance, but I know you well enough to know that you planned for both a single and multiple-elemented Array1.
What did you come up with to handle both scenarios simultaneously?
I’m a bit embarrassed to admit - I didn’t cater for a multiple-elemented “Array1” at all. I just setup a dummy string array with one element, and made the outer loop LOOP over it. This was because the multi-dim record (/Array1[0]/Array2[n]) was actually the output array for flow (I was building a multi-dimensional Ariba cXML document). However, I’ve since confirmed that this problem exists for in-arrays as well (i.e. You cannot LOOP over /Array[0]/Array2[n] in a single LOOP)
To put in a little context, I came across this situation implementing cXML Detail Invoices. I wanted to LOOP over an array of line items:
/cXML/Request/InvoiceDetailRequest/InvoiceDetailOrder[0]/InvoiceDetailItem[n]
In my situation, InvoiceDetailOrder (“Array1”) only has one element with subscript 0 because we only carry one order per invoice.
However, regarding what you were saying Dan, putting the second LOOP under a simple IF construct allows you to check if a particular iteration of Array1 matches a condition you want (say, if Array1[n].Element = “WhatIWant”)
– LOOP over Array1
---- IF Array1.Element = “WhatIWant”
------ LOOP over Array2 <— Loop only when IF condition met
I have a similar scenario.
I receive an xml with more than one line item level elements. That makes it a record list (Let us call it RL1). I have to loop over this record list, and for each element in this list, search the database and find items(RL2). And then for each of the items found, create a record and get a recordList. Append all the results to a final recordList.
I did create a flow to do this. I havent done extensive testing though. Here is how I did it
First Loop
in-array : /PDSUpdateReq/PDS-UPDATE-REQ/ITEM
out-array : /PDSUpdateResp/PDS-UPDATE/ITEM
2. Second Loop
in-array: /CADataResp
out-array: /RespItem
At the level of the first loop, I created a map that maps the “RespItem” recordList to the /PDSUpdateReq/PDS-UPDATE-REQ/ITEM record (This is a record becoz it is mentioned in the inarray).
This works when I test with just 2 line items.
Did anyone understand anything I said here?
Could the problem with your looping behavior be related to how webMethods creates the arrays?
When using a flow like documentToRecord to convert an incoming node object (some xml) to a IData record structure, webMethods will not automatically give you a record list when the source xml only has one instance of the list in question.
You have to declare all the arrays that you want wm to always create, either with an explicit declaration of arrays or by pointing to some record reference.
I seem to recall some inconsistant behaviour with using the record reference approach, and resolved to using the explicit arrays approach. Within the context of your loop -you may not have to declare absolutely every array - just enough to insure your specific flow works.
> Could the problem with your looping behavior be related
> to how webMethods creates the arrays?
…
> webMethods will not automatically give you a record list
> when the source xml only has one instance of the list in
> question.
Hi Haithem - I don’t think this is the reason. In my test case, I had initialized my outer array (Array1) with 2 elements, but a single LOOP (no outer LOOP) over “Array1[0]/Array2” still gave unexpected results. I think we’re probably just not meant to directly loop over an array whose path contains an outer array – we need an outer loop. Do let me know if you think this isn’t trie.
Hi VR - thanks man. This is sort of what I do too. Just a word of caution I’ve learnt - make sure any documentToRecord call feeding an record array to a LOOP step has its recordName set correctly.
I’ve lost many, many, many hours in cases when recordToDocument didn’t get the correct record structure. In such cases, the LOOP would work just fine for documents with 2 or more lines (in the array), but then would fail miserably for documents with only one line – since documentToRecord no longer generated an array, the LOOP would simply not be entered. My post here ties in with my other post today, on caution while setting recordName in recordToDocument.