Null elements in output array when mapping EDI to output FF schema

Hi Chris,

I’ve trying to map an EDI 850 to another flat file schema. I’m using the wM document EDIFFSchema.X12.V4010:T850DT in the WmEDIforTN package as my input document reference. The output type is based on a custom flat file schema that I’ve created. I’ve sent instances of this flat file document through the service for parsing, and they’ve all worked. I believe that’s okay.

So far, so good.

As you’d expect, both the EDI input and FF output docs follow the same general format: a header, followed by one or more line item details, with a summary bringing up the rear.

When I send an EDI input through and look at the FF output I get, I can see the header, the correct number of line items, and the summary. However, the details underneath the line items in the FF output are lost. There are lists of documents under the line item details (e.g., multiple pricing info docs that should map from the CTP EDI records and order line text that should map from the MSG EDI records) that aren’t mapped into the output doc properly. These are nested loops that I’m still not doing properly. This is where my poor understanding of the pipeline and LOOPing shows up.

%

Hi RMG,

I agree - I will have to speak to our trading partner about the EDI we’re receiving. I’m looking at text files that supposedly represent the “raw EDI”, but I’m not 100% sure that when I configure wM to poll the VAN mailbox to pull out documents on a daily basis that this is what it’ll receive. I’ve got to check that out.

“appendToDocumentList is not a must in the EDI mapping,but due to your target document structure this service makes easier to build the FF structure as expected.I am not sure why you are not comfortable about using this service.”

It’s not a matter of being uncomfortable with using the service, although I will admit that I’m still feeling my way around the API. I’m just saying that if this was such an important technique that I would have expected to see it in the docs and the examples. I’m not sure I understand why my target schema requires it. It’s just another flat file schema that happens to have several loops nested under the line item details loop. That’s different from the examples, which only show one level of LOOPing, but it’s not terribly complex IMO.

“If you are comfortable understanding the provided WmEDISamples,please proceed with that.” - I’m still not comfortable with anything, but I’m going to keep plugging.

“We wmusers will help you further” - I don’t mean to sound ungrateful or to denigrate the response of wM users.

I’m just used to the Java forum over at Sun. I think the pool of participants is bigger there than it is here, that’s all.

Thanks again to all who have taken the time to reply. Sincerely, MOD

Micheal,

As a first step in the mapping use FF as a documentReference or just output document and initialize this structure using setValue null,so this document will be carried out in the pipeline.

Inside the PO1 loop,keep another loop PO1/CTP as the input array
and /11/12 as the output array and map the pricing information to target /12 documentlist and similarly for MSG keep another loop under PO1 inarray is PO1/MSG and map to target FF structure.

Are you using this way?

If the above scenario not working, alternate option is using of appendToDocumentlist as said above.

HTH,
RMG.

Loops can be a killer in wm.
IF your document looks like this
hrdRec …
—>DetList
-----Det1istSub1
--------Det1istSub2
---------->DetRec
SumRec

The flow service will need to do the following to access the DetListSub?:
LOOP on DetList (where DetList is a List)
–>LOOP on Det1ist/Det1istSub1
(where DetList is now a record and DetListSub1 is a List)
-----> LOOP on Det1ist/Det1istSub1/DetListSub2
(where DetList & DetListSub1 are records and DetListSub2 is a List)
Now you can map DetListSub2 and DetRec

When you look at the inputs for your loops are you seeing DetListSub1 or are you seeing DetListSub1[0]?

The key to getting this right is you have to use a step approach. By this I mean map the outter LOOP on DetList and drop only a map step within the LOOP. From there, open the record of DetList and copy DetList/DetListSub1 list and past that into the next LOOP instruction.
Repeat this for each nested LOOP.
At this poine when you look at the empty map statement within the LOOPs you should be able to see list correctly represented as a record. Then you should be able to map. You MUST have a record representation and not a recordList when you actually map. Mapping directly from the recordList can cause unpredicatable results in some cases. Best to stay away from it.

Where you will need to use appendToDocumentList is where you have a one-to-many or man-to-one mapping. For instance the input is a list but your app file stores this info in a record that does not repeat.

Let me know if I’m on the right track and if this helps.
Sorry for the long winded reply.

Hi Chris,

“Loops can be a killer in wm”

Thanks for this. I feel like an eejit for having so much trouble with this.

Okay, I’ve learned one difference between Documents and Document References that’s key: You can only create a reference to a Document that’s defined in your packages. So I can have a reference to the T850DT root document type, and I can have Document and Document List inputs that are PO1 and CTP children of the T850DT/ST root, but I CANNOT have references to PO1 or CTP because neither of those are defined in my packages. I lose all the underlying child info. THAT’S a big difference. (Sorry for being so slow.)

Here’s what I see happening in my debugger when I step through. I have five services involved, and I can see exactly where I go wrong. (I just don’t know what to do about it yet.)

  1. Map850ToTrustedLinkRequest
    service input = T850DT reference
    service output = TrustedLinkPORequest

This is the top level service that has a MAP step for the header, a service named MapAll850LineItemDetails, and another MAP step for the summary. If I click on the “MapAll850LineItemDetails” service in this flow, I see that the pipeline input maps its PO1 document list to the service input; ditto for the output “11” document list. When I step through the debugger, I can see all the header info in the output TrustedLinkPORequest and the complete contents of the T850DT input doc in the Results tab.

  1. MapAll850LineItemDetails
    service input = PO1 Document List
    service output = 11 Document List (Yes, that’s “11” as in “eleven”. Crazy schema.)

This service has a LOOP at the top that has /PO1 as the input array and /11 as the output array. The body of the loop contains a single INVOKE step: Map850LineItemDetail(Note: no mention of parent in arrays.) When I look at the pipeline I see that I’m mapping the PO1 list Document (NOT a reference) from the T850DT into the service input PO1 list; same with the output. When I step into this INVOKE in the debugger I can see a PO1 Document List with 3 child documents underneath, plus the complete T850DT and partial TrustedLinkPORequest.

  1. Map850LineItemDetail
    service input = PO1 Document
    service output = 11 Document

This service contains a MAP step for the line item info, an INVOKE step called MapAll850PricingInfo, and another MAP for tax exempt info. When I look at the pipeline I see that I’m mapping the CTP list child from the PO1 into the service input PO1 list; same with the output. When I step in using the debugger I see the first PO1 Document. It has a Document List of CTP children of length one.

  1. MapAll850PricingInfo
    service input = CTP Document List (NOT a Document Reference List)
    service output = 12 Document List (“twelve”; NOT a Document Reference List)

This service has a LOOP at the top that has /CTP as the input array and /12 as the output array. (Note: no mention of the PO1 or 11 parents.) When I step into this service and look at the Results tag, I see the CTP Document List with a single CTP Document child underneath, along with some other documents. When I enter the LOOP, I see the first CTP Document on the Results tab.

  1. Map850PricingInfo
    service input = CTP Document
    service output = 12 Document (“twelve” Document)

This service has a single MAP step that copies values from the CTP Document into the 12 Document. On the Results tab I can see the first CTP document and its values, so I believe that information is getting down to the service. When I exit this service, I can see the 12 Document populated with the proper values. This appears to be the point at which I lose the 12 data It&#3

Michael,

Please follow my last post in this thread and also modify in your MapAll850PricingInfo
service input = CTP (SegmentDocument)
service output = 12 Document List (“twelve”; NOT a Document Reference List)

and so when you loop over the PO1/CTP then map the CTP(document) to the above service input and the service just add a map step and map the CTP information to a temporary 12/document and use the appendToDocumentList to build /12 documentlist and exit out of the PO1/CTP loop and map the 12 document list to parent 11/12 documentlist.

This way you can eliminate the Map850PricingInfo service since you already mapped the individual elements in the map step of MapAll850PricingInfo service.

HTH,
RMG.

Hi RMG,

Sorry for being so slow. I’ve printed both your responses. I’ll be studying both carefully this afternoon and trying them out. Thanks - MOD

Hi RMG, Chris, and all wM forum members,

Thanks to your patience, and some dogged thinking, I’ve finally seen where I went wrong.

I couldn’t understand why the output Document Lists that I was mapping were getting lost in the pipeline. The key was to make a Document List pipeline output with the same name as the service output Document List and then drag & drop it up to the parent document to make it a child. Map the service output Document List to this new child Document List, drop the service output Document List from the pipeline, and everything is perfect.

Looping in my case turns out to be relatively easy, in spite of all the difficulties I’ve had. The input document array generates one output array entry for each iteration through the loop, so I can use the LOOP /input and /output array notation to good advantage. No need for appending documents to list or anything else.

I’ve done this trick several times since I discovered it. My EDI-to-FF mapping is progressing nicely now.

Thanks to all of you for your patience and insight. I hope this thread will help someone else who’s facing wM LOOPing for the first time in the future. - %

Michael,

Glad you finally got make it working…Hooray!!!

Ofcourse in some cases input/outpurt array notation works,but for me append to document list makes easier in complex cases.

bottomline is loops should be handled carefully.

Goodluck,

Hi RMG,

Thanks again for checking in on me all this time.

Right, I think your appendDocumentToList idiom is required for cases more complex than mine. I’ll have to keep it in mind for future work.

I appreciate those folks who help out noobs like me on this forum. It’s a great service, and you can’t beat the price. Thanks again - %

Michael,
Your solution is ok. I will append to RMG. You will note that if your inner steps of the loop don’t have data to write to the output list, you will have a “null” in its place. RMG’s suggestion would eliminate this for you when you don’t need elements for exist with array position preserved.
Be careful with tricks and short cuts, I too know that putting “input/output” tab variable will allow it to show on loops with the output having the same name. I too would suggest that you make an explicit MAP step before the loop with the variable and just click the blue “set inputs” arrow and leave it blank.
Best practice that you will find over time is this approach for a consolidated list and it only requires one map step before and inside the loop.

Yemi,

I agree with your setValue null the output(document/list) option in a map step before the loop especially when using InArray/OutArray logic.

Regards,

Thought these threads on looping may be of some help:

[url=“wmusers.com”]wmusers.com
[url=“wmusers.com”]wmusers.com

Hi Rob,

Brilliant stuff. The explanations I’ve read from you have been so clear and concise. You’ve added to my meager understanding of webMethods by leaps and bounds. Thanks so much. Sincerely, MOD

Kind of you to say! Glad to be of assistance.

Hello all, especially Rob Eamon. I hope you’re still watching…

I thought I had this knocked, but I’ve still got a subtle problem.

I’ve read Rob’s excellent thoughts and tried to make them my own, but it’s still not working out. I’ve got to be missing something, so I’m back at the forum with my hat in my hand.

I’ve had a doubly-nested loop working out just fine, using both input and output arrays. However, I have a pathological test case that “loses” one line of order message text.

So I ditched the output array approach and tried Rob’s advice. Here’s my flow:

Input document has DocumentList N9 with child DocumentList MSG
Output document has DocumentList 19
+ Outer loop over all /N9 elements; no output array
++ Inner loop over all /N9/MSG elements; no output array
+++ MAP create a temp 19 Document and initialize it to null
+++ MAP the String value out of the N9 Document into temp 19
+++ MAP temp 19 appendToDocumentList to output Document 19 list;
+++ Drop the temp 19 Document from the pipeline

When I loop through in the debugger I see the “dropped” order message text created and appended to the output Document list.

But subsequent iterations through the loop overwrite each other. I end up with a Document list containing the last instance instead of the 8 that I expect.

If I read the built-in service docs I see this:

“The documents contained in fromList and fromItem are not actually appended as entries to toList. Instead, references to the documents in fromList and fromItem are appended as entries to toList. Consequently, any changes made to the documents in fromList and fromItem affect the resulting toList”

Must I resort to a Java server and com.wm.data.IDataUtil.deepClone to append to the list, or did I miss something again?

I can get seven of the eight Documents I expect in the list if I use output array semantics in my Loop. I’m still chasing that one lost Document.

Thanks for your help and patience. Sincerely, MOD

Michael,

Please try to do this way.

Actually move the initialize step outside of the loops as shown below

+++ MAP create a temp 19 Document and initialize it to null

Outer loop over all /N9 elements; no output array
++ Inner loop over all /N9/MSG elements; no output array
+++ MAP the String value out of the N9 Document into temp 19
+++ MAP temp 19 appendToDocumentList to output Document 19 list;(In this map step itself drop the temp19,fromItem,toList

and finally step thru the each N9/MSG loop iteration,you should see the append stuff and come out of the loop see the result as expected.

Note:No need to map froList just use appendToDocumentList Service Input fromItem (temp19),toList(original Document 19) and Service Output toList(Original Document 19).

May be you are looking for Ray for better explanation,i tried my best to respond.

HTH,
RMG.

Hi RMG,

No, your explanation is fine. No insult intended. :wink:

I think I implemented what you suggested, but I’m still not getting the entire list. Only the last line of order message text appears in the list.

The reference semantics seem to be the problem.

What did I miss? I’ve attached a ZIP with the HTML representation in case that’ll help. Thanks - MOD


kac.tn.edi.Boeing.maps_Map850ToTrustedLinkPORequest.zip (30.0 k)

I should point out that level 2.8 is the MAP step at the start of the loop in question. It continues down to level 2.94. Thanks - MOD

Michael,

I have downloaded your HTML file but is not working (no images etc…)it is just showing the segment names.

my solution for appendToDocumentList should work (but critical part here is dropping fromItem,temp document,toList in the pipelineout.

HTH,
RMG.