Author |
Message
|
Pegazus |
Posted: Thu Aug 10, 2006 11:30 am Post subject: Losing XML Attributes in Environment.Variables |
|
|
Novice
Joined: 10 Aug 2006 Posts: 16
|
Hi
I am facing a weird situation here and I need some help.
Once I read the message of the MQInput Node in the first Compute Node I copy the InputRoot.XML to Environment.Variables.Message
This XML has values like these
<Name age="25">
</Name>
Later in the flow I copy back the Environment.Variables.Message to OutputRoot.XML in a different Compute Node and write to a queue using the MQ Output Node.
The output now looks like
<Name>
<age>25</age>
</Name>
Am I doing something wrong here ? How do I recitfy this error. I want output xml look the same as the input with the xml attributes and not a separate tag.
Pls.respond.
Thanks |
|
Back to top |
|
 |
Vitor |
Posted: Thu Aug 10, 2006 11:57 pm Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
You need something like
Code: |
SET OutputNode.XML.Name.(XML.Attribute)age = Environment.Variables.Messaage.etc.etc.etc |
(Above snippet written entirely from memory, has not been tested and is provided as-is for illustration purposes only.)  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
kimbert |
Posted: Fri Aug 11, 2006 12:24 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
Did you use the search button before posting?
http://www.mqseries.net/phpBB2/viewtopic.php?t=15269&highlight=xml+attributes+elements
This keeps on cropping up. It's not enough to simply copy InputRoot to Environment.Variables. You need to set up a parser in the Environment tree first. Something like
Code: |
CREATE LASTCHILD OF Environment.Variables Name 'XMLNS' Domain 'XMLNS' |
Please stop using the XML domain unless you are on v2.1 ( in which case you should be planning to upgrade very soon). XMLNS ( v5) and XMLNSC ( v6 ) are the recommended XML parsers. |
|
Back to top |
|
 |
Vitor |
Posted: Fri Aug 11, 2006 12:58 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
kimbert wrote: |
Did you use the search button before posting? |
I certainly didn't....  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
Pegazus |
Posted: Fri Aug 11, 2006 8:14 am Post subject: |
|
|
Novice
Joined: 10 Aug 2006 Posts: 16
|
Thanks for the Response Guys ....
Its working ....
Here is the Code
CREATE LASTCHILD OF Environment.Variables.Input DOMAIN('XML') NAME 'XMLMessage';
SET Environment.Variables.XMLMessage = InputRoot.XML;
Later
SET OutputRoot.XML = Environment.Variables.Input.XMLMessage;
This preserves the XML Structure
Last edited by Pegazus on Fri Aug 11, 2006 9:03 am; edited 1 time in total |
|
Back to top |
|
 |
kimbert |
Posted: Fri Aug 11, 2006 8:33 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
I can't help noticing the continued use of the XML domain in a new message flow. Please tell me there's a really good reason  |
|
Back to top |
|
 |
Pegazus |
Posted: Fri Aug 11, 2006 9:11 am Post subject: |
|
|
Novice
Joined: 10 Aug 2006 Posts: 16
|
Well I guess because XML Namespaces are still not being handled properly in broker. Inspite of the way we code according to the manual, the results are quite unpredictable.
Here is a simple example,
DECLARE ns1 NAMESPACE 'http://tempuri.org';
SET OutputRoot.XMLNS.Temp.(XML.NamespaceDecl)xmlns = 'http://tempuri.org/';
Well I thought it was supposed to produce an output like
<Temp xmlns='http://tempuri.org'>
but the result was
<NS1:Temp xmlns:NS1="http://tempuri.org">
Although I was using the default namespace ? I didnt want the output prefixed.
Besides fix paks after fix paks .... nothing is ever fixed ???
What is wrong with the statement here ??? |
|
Back to top |
|
 |
fjb_saper |
Posted: Fri Aug 11, 2006 1:53 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Pegazus wrote: |
Well I guess because XML Namespaces are still not being handled properly in broker. Inspite of the way we code according to the manual, the results are quite unpredictable.
Here is a simple example,
DECLARE ns1 NAMESPACE 'http://tempuri.org';
SET OutputRoot.XMLNS.Temp.(XML.NamespaceDecl)xmlns = 'http://tempuri.org/';
Well I thought it was supposed to produce an output like
<Temp xmlns='http://tempuri.org'>
but the result was
<NS1:Temp xmlns:NS1="http://tempuri.org">
Although I was using the default namespace ? I didnt want the output prefixed.
Besides fix paks after fix paks .... nothing is ever fixed ???
What is wrong with the statement here ??? |
Well for one part your understanding of the XML Standard?
My undersanding is that both notations are XML grammatically and syntactically correct and that you are free to choose which one you will adhere to....
Enjoy
 _________________ MQ & Broker admin |
|
Back to top |
|
 |
kimbert |
Posted: Mon Aug 14, 2006 2:12 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
Your message tree is badly-formed. You need to put element 'Temp' in the default namespace. Unfortunately, in v5 the serializer did not trap this error, so you can be forgiven for thinking that it was a defect. All you need to do is change your code to:
Code: |
DECLARE ns1 NAMESPACE 'http://tempuri.org';
SET OutputRoot.XMLNS.ns1:Temp.(XML.NamespaceDecl)xmlns = 'http://tempuri.org/'; |
Incidentally, I tried your code in v6 and got this very helpfully-worded error:
Code: |
ParserException BIP5014E: Element must have a namespace specified if there is a default namespace in scope.
Whilst writing the XMLNS message, element 'Temp' was found to be in scope of a default namespace, but this element does not have a namespace defined.
This error can occur if the NamespaceDecl correlation name has been used to create a default namespace for a parent element, and a child element has been created that does not have a namespace. If you have defined a default namespace in your output message tree, then all elements that are in scope of this default namespace must be defined to be in a namespace. Modify the output message tree so that element 'Temp' is defined to be in a namespace. If element 'Temp' belongs to the default namespace, then this element needs to be created in the default namespace. |
My advice remains the same : move to XMLNS as soon as possible, and use your IBM rep or this forum to resolve any initial difficulties. |
|
Back to top |
|
 |
ydsk |
Posted: Wed Aug 16, 2006 12:42 pm Post subject: |
|
|
Chevalier
Joined: 23 May 2005 Posts: 410
|
fjb_saper,
Though both are syntactically similar, there are some differences. The differences becaome problematic when you use digital signatures, check-sum , etc for example.
We had a few problems in v5 when one end-application ( .NET platform) was digitally signing a part of the soap Body and inserting the signature in the soap Header. The part of the soap Body that was used was in scope of a default namespace and message broker was suppressing all the prefixes ( if they were different from that of the top-most element) when it forms the output to the other end-application, though the namespace was the same throughout the part of soap Body ( just the prefix was redefined for a few elements inside the top-most element that had the default namespace prefix, but the namespace URI was still the same).
This behavior changed in v6, and the prefixes are preserved. I think the XMLNSC ( Compact ) parser behaves similar to that of v5 in some ways.
The bottomline is, as Kimbert suggested, we need to move to XMLNS !!!
thanks.
ydsk. |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Aug 16, 2006 3:44 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
The other thing is if you are looking at digital signatures you should really be passing the message from input to output as a BLOB.
What you do inbetween to allow routing etc is then open to you but you do not change the message content and as such the ultimate consumer can check the digital signatures and be assured the message has not been tampered with...
You do not recreate the BLOB, (by serialization or other, just take it from input to environment and when all the parsing and routing is done move it from environment to output...
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
kimbert |
Posted: Thu Aug 17, 2006 12:36 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
Quote: |
The bottomline is, as Kimbert suggested, we need to move to XMLNS !!! |
...if on v5. Move to XMLNSC if on v6. |
|
Back to top |
|
 |
ydsk |
Posted: Thu Aug 17, 2006 8:00 am Post subject: |
|
|
Chevalier
Joined: 23 May 2005 Posts: 410
|
fib_saper,
What you suggested is ideal.
But end-applications always do things they want the way they want.
In our case the end-application wasn't digitally signing the whole message , it was a part of soap Body rather. It was a requirement that the broker shouldn't modify the part of the soap Body that was digitally signed.
And remember, it's a big hassle to convert part of a soap message into BLOB when you have multiple namespaces in scope. If you don't do things properly you end up getting default prefixes ( NS1, NS2, ..., etc) and not the prefix you want. Even if you do things properly to preserve the prefixes you end up changing the message content ( though semantically it's the same xml message) and thereby affecting the digital signature.
Thanks. |
|
Back to top |
|
 |
RikBaeten |
Posted: Thu Sep 24, 2009 7:38 am Post subject: Literal code that fixes the problem |
|
|
 Novice
Joined: 26 Feb 2007 Posts: 19
|
For future reference: I'm adding some code that I literally used to fix the problem that XML attributes are changed into XML nodes when assigning an XML tree to the Environment.
The pieces of code provided by kimbert and Pegazus were not working for me literally, but pointed me in the good direction.
Also, see this article in the information center:
http://publib.boulder.ibm.com/infocenter/wmbhelp/v6r0m0/topic/com.ibm.etools.mft.doc/au16550_.htm#au16550_25
Quote: |
When copying a message tree, or part of a message tree, ensure that the owning parser association is maintained, by first serializing and then reparsing the message into the appropriate message tree. |
Here's the code:
Code: |
DECLARE xmlMsgBlob BLOB ASBITSTREAM(InputRoot.XMLNSC,InputRoot.MQMD.Encoding, InputRoot.MQMD.CodedCharSetId);
CREATE LASTCHILD OF Environment.Variables.xmlMsg DOMAIN('XMLNSC') PARSE(xmlMsgBlob,InputRoot.MQMD.Encoding,InputRoot.MQMD.CodedCharSetId);
|
After this you can just refer to Environment.Variables.xmlMsg. |
|
Back to top |
|
 |
mqjeff |
Posted: Thu Sep 24, 2009 9:32 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
That's an very very processor intensive way to do that.
There's no good reason to serialize using ASBITSTREAM and then unserialize using PARSE.
Just use Create LastChild DOMAIN() and then a tree copy. |
|
Back to top |
|
 |
|