Author |
Message
|
sumit |
Posted: Sat Jan 12, 2013 3:48 am Post subject: Working with Attributes in MRM domain |
|
|
Partisan
Joined: 19 Jan 2006 Posts: 398
|
Hi All,
I know the topic has been widely discussed here but I am still clueless about it.
I am working on MB8 and using a message set in MRM domain.
My XML structure is like-
Code: |
Input message
<Input>
<Data>
<Item1>Item1</Item>
<Item2>Item2</Item>
</Data>
</Input>
Output Message
<Output>
<Record>
<Line lineattrib="itemattrib1">Item1</Line>
<Line lineattrib="itemattrib2">Item2</Line>
</Record>
</Output> |
So, I in target I need value at both attribute and element level. The message set is looking good and have the attributes defined in it.
ESQL has
Code: |
SET OutputRoot.MRM.Record.Line[1].lineattrib='itemattrib1';
SET OutputRoot.MRM.Record.Line[2].lineattrib='itemattrib2';
SET OutputRoot.MRM.Record.Line[1] = InputRoot.MRM.Data.Item1;
SET OutputRoot.MRM.Record.Line[2] = InputRoot.MRM.Data.Item2; |
When I was checking the execution in debug mode, I noticed that
1. When the execution hits first 2 statement, it creates attributes at the correct hierarchy (as expected)
2. But the moment it executes 3rd and 4 SET command, it removes the attribute 'lineattrib' and it's corresponding value and only set the Line as Item1 and Item2.
I must say, I have not yet run the code to completion to see the output in queue or elsewhere. This example is like a small snippet from the bigger code which still has some problem I am working on. However, this behavior while debugging looks odd to me. _________________ Regards
Sumit |
|
Back to top |
|
 |
marko.pitkanen |
Posted: Sat Jan 12, 2013 4:00 am Post subject: |
|
|
 Chevalier
Joined: 23 Jul 2008 Posts: 440 Location: Jamsa, Finland
|
Hi Sumit,
Have you taken debug user trace? I supose that from there you could find information that your 3rd and 4th SET statements executes tree copy. You should perhaps consider to use different order of the statements or study what InfoCenter say about FIELDVALUE function.
--
Marko |
|
Back to top |
|
 |
sumit |
Posted: Sat Jan 12, 2013 4:30 am Post subject: |
|
|
Partisan
Joined: 19 Jan 2006 Posts: 398
|
Yes Marko. I did take a user trace before posting. Here is the part of it (the names will differ as the one given in first post was a sample. And the one I am putting now has the actual tag names)
Code: |
2013-01-11 22:43:46.915454 4960 UserTrace BIP2537I: Node 'MF_MOM_WCS_RetrieveOrder_SYNC.CMP_Transform_Response_GBOtoWCS': Executing statement ''SET OutputRoot.MRM.ord:DataArea.ord:Order.ord:OrderItem[iOMSOrderLine].ord:ItemAttributes[1].name = 'ItemName';'' at ('.MF_MOM_WCS_RetrieveOrder_SYNC_CMP_Transform_Response_GBOtoWCS.Main', '75.7').
2013-01-11 22:43:46.915477 4960 UserTrace BIP2539I: Node '': Evaluating expression ''iOMSOrderLine'' at ('.MF_MOM_WCS_RetrieveOrder_SYNC_CMP_Transform_Response_GBOtoWCS.Main', '75.63'). This resolved to ''iOMSOrderLine''. The result was ''1''.
2013-01-11 22:43:46.915512 4960 UserTrace BIP2566I: Node 'MF_MOM_WCS_RetrieveOrder_SYNC.CMP_Transform_Response_GBOtoWCS': Assigning value '''ItemName''' to field / variable ''OutputRoot.MRM.ord:DataArea.ord:Order.ord:OrderItem[iOMSOrderLine].ord:ItemAttributes[1].name''.
2013-01-11 22:43:46.915855 4960 UserTrace BIP2537I: Node 'MF_MOM_WCS_RetrieveOrder_SYNC.CMP_Transform_Response_GBOtoWCS': Executing statement ''SET OutputRoot.MRM.ord:DataArea.ord:Order.ord:OrderItem[iOMSOrderLine].ord:ItemAttributes[1] = InputRoot.MRM.OrderLineItems.OrderLineItem[iOMSOrderLine].CustomerItemDesc;'' at ('.MF_MOM_WCS_RetrieveOrder_SYNC_CMP_Transform_Response_GBOtoWCS.Main', '82.7').
2013-01-11 22:43:46.915874 4960 UserTrace BIP2539I: Node '': Evaluating expression ''iOMSOrderLine'' at ('.MF_MOM_WCS_RetrieveOrder_SYNC_CMP_Transform_Response_GBOtoWCS.Main', '83.51'). This resolved to ''iOMSOrderLine''. The result was ''1''.
2013-01-11 22:43:46.915912 4960 UserTrace BIP2539I: Node '': Evaluating expression ''iOMSOrderLine'' at ('.MF_MOM_WCS_RetrieveOrder_SYNC_CMP_Transform_Response_GBOtoWCS.Main', '83.51'). This resolved to ''iOMSOrderLine''. The result was ''1''.
2013-01-11 22:43:46.915939 4960 UserTrace BIP2539I: Node '': Evaluating expression ''InputRoot.MRM.OrderLineItems.OrderLineItem[iOMSOrderLine].CustomerItemDesc'' at ('.MF_MOM_WCS_RetrieveOrder_SYNC_CMP_Transform_Response_GBOtoWCS.Main', '83.8'). This resolved to ''InputRoot.MRM.OrderLineItems.OrderLineItem[1].CustomerItemDesc''. The result was ''ROW... Root Element Type=50331659 NameSpace='' Name='CustomerItemDesc' Value='ItemShortDesc'''.
2013-01-11 22:43:46.916007 4960 UserTrace BIP2539I: Node '': Evaluating expression ''iOMSOrderLine'' at ('.MF_MOM_WCS_RetrieveOrder_SYNC_CMP_Transform_Response_GBOtoWCS.Main', '82.63'). This resolved to ''iOMSOrderLine''. The result was ''1''.
2013-01-11 22:43:46.916042 4960 UserTrace BIP2568I: Node 'MF_MOM_WCS_RetrieveOrder_SYNC.CMP_Transform_Response_GBOtoWCS': Copying sub-tree from ''InputRoot.MRM.OrderLineItems.OrderLineItem[iOMSOrderLine].CustomerItemDesc'' to ''OutputRoot.MRM.ord:DataArea.ord:Order.ord:OrderItem[iOMSOrderLine].ord:ItemAttributes[1]''. |
I also deleted some sections from trace to show what is happening with first occurance (i.e. [1]) of the tag.
I checked the Infocenter for FIELDVALUE and looks like it works with XML/XMLNSC domains. Don't think if we can use it for MRM. _________________ Regards
Sumit |
|
Back to top |
|
 |
sumit |
Posted: Sat Jan 12, 2013 4:32 am Post subject: |
|
|
Partisan
Joined: 19 Jan 2006 Posts: 398
|
And as you see, we are using namespaces. _________________ Regards
Sumit |
|
Back to top |
|
 |
marko.pitkanen |
Posted: Sat Jan 12, 2013 5:05 am Post subject: |
|
|
 Chevalier
Joined: 23 Jul 2008 Posts: 440 Location: Jamsa, Finland
|
Quote: |
The FIELDVALUE field function returns the scalar value of a given field.
|
I didn't see any statement that FIELDVALUE function works only for XML or XMLNSC domains.
What happens if you try it?
Code: |
SET OutputRoot.MRM.ord:DataArea.ord:Order.ord:OrderItem[iOMSOrderLine].ord:ItemAttributes[1] = FIELDVALUE(InputRoot.MRM.OrderLineItems.OrderLineItem[iOMSOrderLin.... |
Another thing is that you are using long index reference paths, you should perhaps consider to use REFERENCE variables to improve your code efficiency.
--
Marko |
|
Back to top |
|
 |
sumit |
Posted: Sat Jan 12, 2013 5:22 am Post subject: |
|
|
Partisan
Joined: 19 Jan 2006 Posts: 398
|
Oh yes.. REFERENCE is very much what I am going to do. Wondering, I have to use too many REFERENCE.
By the way, does the use of REFERENCE also reduce compile and deploy time? I am struggling as my system is not a very quick one and the size of code is making it worse.
Got to read some more about FIELDVALUE and will use it. _________________ Regards
Sumit |
|
Back to top |
|
 |
kimbert |
Posted: Sat Jan 12, 2013 1:22 pm Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
This suprised me a little:
Quote: |
I am working on MB8 and using a message set in MRM domain.
My XML structure is like- |
Since v6.1, XMLNSC has been the recommended parser for XML data. It can do everything that the MRM XML parser can do, and can do it a lot faster and more accurately.
For the non-XML side of the message flow, you should take a look at the new DFDL domain.
btw, the title of your post is a little misleading - the behaviour of those SET statements is nothing to do with the MRM domain - it is standard, documented ESQL behaviour. |
|
Back to top |
|
 |
mqsiuser |
Posted: Sat Jan 12, 2013 2:52 pm Post subject: Re: Working with Attributes in MRM domain |
|
|
 Yatiri
Joined: 15 Apr 2008 Posts: 637 Location: Germany
|
There are 3 simple rules that you need to always consider when working with Message Broker (and you currently don't do that) !
Beside that... try to flag your xml-attribute with "(XMLNSC.Attribute)":
Code: |
Input message
<Input>
<Data>
<Item1>Item1</Item>
<Item2>Item2</Item>
</Data>
</Input>
Output Message
<Output>
<Record>
<Line lineattrib="itemattrib1">Item1</Line>
<Line lineattrib="itemattrib2">Item2</Line>
</Record>
</Output> |
Code: |
SET OutputRoot.XMLNSC.Record.Line[1] = InputRoot.XMLNSC.Data.Item1;
SET OutputRoot.XMLNSC.Record.Line[1].(XMLNSC.Attribute)lineattrib='itemattrib1';
SET OutputRoot.XMLNSC.Record.Line[2] = InputRoot.XMLNSC.Data.Item2;
SET OutputRoot.XMLNSC.Record.Line[2].(XMLNSC.Attribute)lineattrib='itemattrib2'; |
_________________ Just use REFERENCEs |
|
Back to top |
|
 |
kimbert |
Posted: Sat Jan 12, 2013 3:34 pm Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
Quote: |
try to flag your xml-attribute with "(XMLNSC.Attribute) |
That advice would be appropriate if the output contained 'lineAttrib' as a tag instead of an attribute. But that's not the problem. The problem is that the tree copy in the third SET statement is overwriting the assignment made by the first.
Secondly, and very importantly, the OP has clearly stated that he/she is using the MRM domain. You cannot use XMLNSC.Attribute with the MRM domain. MRM attributes are identified as such by the XML Physical Format, not by a flag in the element's field type. |
|
Back to top |
|
 |
rekarm01 |
Posted: Sun Jan 13, 2013 12:54 pm Post subject: Re: Working with Attributes in MRM domain |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 1415
|
sumit wrote: |
2. But the moment it executes 3rd and 4 SET command, it removes the attribute 'lineattrib' and it's corresponding value and only set the Line as Item1 and Item2. |
Marko mentioned this earlier, but it's worth repeating. Try switching the order of the SET statements, so they're created from the top down:
Code: |
SET OutputRoot.MRM.Record.Line[1] = InputRoot.MRM.Data.Item1;
SET OutputRoot.MRM.Record.Line[2] = InputRoot.MRM.Data.Item2;
SET OutputRoot.MRM.Record.Line[1].lineattrib='itemattrib1';
SET OutputRoot.MRM.Record.Line[2].lineattrib='itemattrib2'; |
Or, try using the VALUE clause of the ESQL SET statement:
Code: |
SET OutputRoot.MRM.Record.Line[1] VALUE = InputRoot.MRM.Data.Item1;
SET OutputRoot.MRM.Record.Line[2] VALUE = InputRoot.MRM.Data.Item2; |
Or, try using the FIELDVALUE function, as Marko also suggested:
Code: |
SET OutputRoot.MRM.Record.Line[1] = FIELDVALUE(InputRoot.MRM.Data.Item1);
SET OutputRoot.MRM.Record.Line[2] = FIELDVALUE(InputRoot.MRM.Data.Item2); |
The FIELDVALUE function would be more common for reading Line elements, but could also help to write them.
sumit wrote: |
By the way, does the use of REFERENCE also reduce compile and deploy time? I am struggling as my system is not a very quick one and the size of code is making it worse. |
Probably not much. Switching from MRM to XMLNSC might help too, but again, probably not much. |
|
Back to top |
|
 |
sumit |
Posted: Mon Jan 14, 2013 12:51 am Post subject: |
|
|
Partisan
Joined: 19 Jan 2006 Posts: 398
|
kimbert wrote: |
This suprised me a little:
Quote: |
I am working on MB8 and using a message set in MRM domain.
My XML structure is like- |
Since v6.1, XMLNSC has been the recommended parser for XML data. It can do everything that the MRM XML parser can do, and can do it a lot faster and more accurately. |
Yes, I agree. However, I still wonder why MRM is causing trouble here.
kimbert wrote: |
btw, the title of your post is a little misleading - the behaviour of those SET statements is nothing to do with the MRM domain - it is standard, documented ESQL behaviour. |
Not sure what I missed however, I am surprised where the attributes are disappearing. As the problems is with Attributes only; hence the title. _________________ Regards
Sumit |
|
Back to top |
|
 |
sumit |
Posted: Mon Jan 14, 2013 1:08 am Post subject: Re: Working with Attributes in MRM domain |
|
|
Partisan
Joined: 19 Jan 2006 Posts: 398
|
rekarm01 wrote: |
sumit wrote: |
2. But the moment it executes 3rd and 4 SET command, it removes the attribute 'lineattrib' and it's corresponding value and only set the Line as Item1 and Item2. |
Marko mentioned this earlier, but it's worth repeating. Try switching the order of the SET statements, so they're created from the top down:
Code: |
SET OutputRoot.MRM.Record.Line[1] = InputRoot.MRM.Data.Item1;
SET OutputRoot.MRM.Record.Line[2] = InputRoot.MRM.Data.Item2;
SET OutputRoot.MRM.Record.Line[1].lineattrib='itemattrib1';
SET OutputRoot.MRM.Record.Line[2].lineattrib='itemattrib2'; |
|
I even shuffled the statements before posting the query. Not like the one mentioned above, but like
Code: |
SET OutputRoot.MRM.Record.Line[1].lineattrib='itemattrib1';
SET OutputRoot.MRM.Record.Line[1] = InputRoot.MRM.Data.Item1;
SET OutputRoot.MRM.Record.Line[2].lineattrib='itemattrib2';
SET OutputRoot.MRM.Record.Line[2] = InputRoot.MRM.Data.Item2; |
I set the attribute first because I have read somewhere (searching the source) that if we set element first and then the attribute, attribute comes like a child element in resulting XML.
I will use VALUE and FIELDVALUE and update the outcome here.
Couple of points which I feel is worth mentioning.
1. accessing attributes in MRM domain is similar to accessing a child element. We have even used it at other places and it works fine.
2. I've merged 2 XSDs and validated that in XMLSpy. Also created a Sample XML to be sure that it is fine. Then I used the XSD and created message set.
3. I have checked the attribute definition in message set and am not able to find any problem. Though, I am still looking if I have missed anything. _________________ Regards
Sumit |
|
Back to top |
|
 |
kimbert |
Posted: Mon Jan 14, 2013 1:24 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
sumit: You need to put the SET statements in the order recommended by rekarm01.
Quote: |
I set the attribute first because I have read somewhere (searching the source) that if we set element first and then the attribute, attribute comes like a child element in resulting XML. |
I don't know where you read that, but it was probably talking about a different scenario.
One more time: This problem is caused by a defect in your ESQL. Your SET statements are in the wrong order. Put them in the correct order and this problem will go away. |
|
Back to top |
|
 |
rekarm01 |
Posted: Tue Jan 15, 2013 1:06 am Post subject: Re: Working with Attributes in MRM domain |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 1415
|
sumit wrote: |
I set the attribute first ... |
The point of switching the order of SET statements was to set the attribute last, because setting it first clearly doesn't work.
sumit wrote: |
I will use VALUE and FIELDVALUE and update the outcome here. |
Although either of these options may work, I have not actually tested them. Putting the SET statements in the right order seems to be a more straightforward solution. |
|
Back to top |
|
 |
sumit |
Posted: Wed Jan 16, 2013 5:11 am Post subject: |
|
|
Partisan
Joined: 19 Jan 2006 Posts: 398
|
So, it's finally working for me. Here is the outcome.
1. Jumbled the attributes and element i.e. element first and attribute second - Did Not Work
2. Use the VALUE/FIELDVALUE while setting element value (as I am hardcoding the attribute value) - Worked
3. Set attributes and elements in any order but used VALUE - Worked _________________ Regards
Sumit |
|
Back to top |
|
 |
|