ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Small issue with namespace declaration copying

Post new topic  Reply to topic
 Small issue with namespace declaration copying « View previous topic :: View next topic » 
Author Message
huwgb
PostPosted: Thu Jun 16, 2016 5:43 pm    Post subject: Small issue with namespace declaration copying Reply with quote

Novice

Joined: 07 May 2013
Posts: 21

Hi,
I have a strange issue with namespace declaration copying. I suspect it is down to me being out of practice with WMB/IIB development.
Anyway.
The issue:
Request message:
Code:
<ns1:RetrieveRequest xmlns:ns1="namespace1">
 <ns2:DocumentID xmlns:ns2="namespace2">A549</ns2:DocumentID>
</ns1:RetrieveRequest>


Transformed Message:
Code:
<ns3:FetchObject xmlns:ns3="namespace3">
 <idObject xmlns:ns2="namespace2">A549</idObject>
</ns3:FetchObject>


Desired Transformed Message:
Code:
<ns3:FetchObject xmlns:ns3="namespace3">
 <idObject>A549</idObject>
</ns3:FetchObject>


ESQL Code:
Code:

Call CopyMessageHeaders();
SET OutputRoot.Properties.MessageSet = 'MS_ProviderFetch';
SET OutputRoot.XMLNSC.ns3:FetchObject.(XMLNSC.NamespaceDecl)xmlns:ns3 = 'namespace3';
SET OutputRoot.XMLNSC.ns3:FetchObject.idObject = InputRoot.XMLNSC.ns1:RetrieveRequest.ns2:DocumentID;


I know I can get it to work with the following snippet:
Code:
Call CopyMessageHeaders();
SET OutputRoot.Properties.MessageSet = 'MS_ProviderFetch';
SET OutputRoot.XMLNSC.ns3:FetchObject.(XMLNSC.NamespaceDecl)xmlns:ns3 = 'namespace3';
SET OutputRoot.XMLNSC.ns3:FetchObject.idObject = FIELDVALUE(InputRoot.XMLNSC.ns1:RetrieveRequest.ns2:DocumentID);


However this code is present in hundreds of places throughout the interface I am modifying and represents a risk to change (As part of the interface uses MTOM xop+xml elements adding a FIELDVALUE function seems to break it).

I can also get it working by assigning the Input DocumentID to a character variable first. This again represents a very large change to hundreds of places through the interface

I can use a Delete Field on the namespace Declarations on the OutputRoot before I propagate it, but this is very similiar to using the FIELDVALUE function.

I also know I can process the input message at the very start of the interface to shift all namespace declarations down to the root level. I just have to be careful with some of the MTOM and Base64 elements to make sure I don't clobber them as well...


I was wandering if there were any suggestions I should be looking at, of if I am stuck with the risk of the above approaches.

Before you ask: The provider system does not have very good XML parsing libraries and is not likely to change.

Edit: Thanks in advance for any assistance here. I am kind of hoping there is something I can specify at a messageSet level, or Properties or possibly even in the ESQL statement on the left hand side of the SET command.

edit 2: I guess this behaviour is completely normal considering the number of search options I am seeing. I guess I have just never come across a provider system that is incapable of handling it before. Or I have always been converting XMLNSC to MRM or the like.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Thu Jun 16, 2016 7:22 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

Wouldn't that be the expected behavior if the node you are specifying as source has children (describing a namespace)?
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
huwgb
PostPosted: Thu Jun 16, 2016 8:10 pm    Post subject: Reply with quote

Novice

Joined: 07 May 2013
Posts: 21

fjb_saper wrote:
Wouldn't that be the expected behavior if the node you are specifying as source has children (describing a namespace)?


Yes... I am starting to realise this.

You know. I know I haven't touched WMB code in depth for a number of years. But I don't think I have ever come across this issue before...
The provider systems either just accepted the namespace declarations or I was converting between different parsers...

As it is, I am putting together a recursive tree scanner to detach all namespaces and attach them to the root element *prior* to any mappings.
Hopefully it doesn't interfere with the MTOM functionality, otherwise I will probably just declare this as a too difficult to fix defect as the risk would be too great...

Or I just selectively fix it with a few FIELDVALUE functions on the most common occurrences...


EDIT:

This code appears to do the trick.
Not the prettiest, and I would appreciate any input as to any gotchas I am likely to come across (the only I can think of is the case where the namespace prefixes in two disparate children match but the namespace declaration is different, in which case the last namespace will take precedence).

I can probably use a select clause in the MoveNamespaceDeclarations function to do it in a one liner...

Code:
CREATE FUNCTION Main() RETURNS BOOLEAN
   BEGIN
      SET OutputRoot = InputRoot;
      DECLARE RootElement REFERENCE TO OutputRoot.XMLNSC.*;
      DECLARE Cursor REFERENCE TO RootElement.(XMLNSC.Field)*;
      WHILE LASTMOVE(Cursor) DO
         CALL MoveNamespaceDeclarations(Cursor, RootElement);
         CALL MapChildren(Cursor, RootElement);
         MOVE Cursor NEXTSIBLING;   
      END WHILE;
         
      RETURN TRUE;
   END;
   
CREATE PROCEDURE MapChildren(INOUT Cursor REFERENCE, INOUT RootElement REFERENCE) BEGIN
      DECLARE ChildCursor REFERENCE TO Cursor;
      MOVE ChildCursor FIRSTCHILD;
      IF NOT SAMEFIELD(ChildCursor, Cursor) THEN
         WHILE LASTMOVE(ChildCursor) DO
            CALL MoveNamespaceDeclarations(ChildCursor, RootElement);
            CALL MapChildren(ChildCursor, RootElement);
            MOVE ChildCursor NEXTSIBLING;
         END WHILE;
      END IF;
         
END;

CREATE PROCEDURE MoveNamespaceDeclarations(INOUT Cursor REFERENCE, INOUT RootElement REFERENCE) BEGIN
   DECLARE NamespaceRef REFERENCE TO Cursor.(XMLNSC.NamespaceDecl)*;
         WHILE LASTMOVE(NamespaceRef) DO
            DETACH NamespaceRef;
            ATTACH NamespaceRef TO RootElement AS LASTCHILD;
            MOVE NamespaceRef TO Cursor.(XMLNSC.NamespaceDecl)*;
         END WHILE;
   END;
Back to top
View user's profile Send private message
mqjeff
PostPosted: Fri Jun 17, 2016 4:47 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

Are you sure that the inner fields really have to belong to no namespace and aren't supposed to belong to the parent namespace?

It's possible the other team is expecting the actual physical representation of the message to appear a certain way, without understanding what it actually represents in an XML Document.

It's also possible that they don't use a real XML Parser and are using some kind of string matching or something.
_________________
chmod -R ugo-wx /
Back to top
View user's profile Send private message
huwgb
PostPosted: Sun Jun 19, 2016 1:56 pm    Post subject: Reply with quote

Novice

Joined: 07 May 2013
Posts: 21

mqjeff wrote:
Are you sure that the inner fields really have to belong to no namespace and aren't supposed to belong to the parent namespace?

It's possible the other team is expecting the actual physical representation of the message to appear a certain way, without understanding what it actually represents in an XML Document.

It's also possible that they don't use a real XML Parser and are using some kind of string matching or something.


Yep, absolutely sure. the interface in question is about 5 years old. The defect only came about because we got some new clients
Back to top
View user's profile Send private message
maurito
PostPosted: Sun Jun 19, 2016 9:53 pm    Post subject: Reply with quote

Partisan

Joined: 17 Apr 2014
Posts: 358

Code:
SET OutputRoot.XMLNSC.ns3:FetchObject.idObject = FIELDVALUE(InputRoot.XMLNSC.ns1:RetrieveRequest.ns2:DocumentID);

or
Code:
SET OutputRoot.XMLNSC.ns3:FetchObject.idObject VALUE = InputRoot.XMLNSC.ns1:RetrieveRequest.ns2:DocumentID;


either of those two statements will only copy the value, rather than doing a tree copy which will include namespace if present.


Last edited by maurito on Tue Jun 21, 2016 5:38 am; edited 1 time in total
Back to top
View user's profile Send private message
mqjeff
PostPosted: Mon Jun 20, 2016 4:31 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

huwgb wrote:
mqjeff wrote:
Are you sure that the inner fields really have to belong to no namespace and aren't supposed to belong to the parent namespace?

It's possible the other team is expecting the actual physical representation of the message to appear a certain way, without understanding what it actually represents in an XML Document.

It's also possible that they don't use a real XML Parser and are using some kind of string matching or something.


Yep, absolutely sure. the interface in question is about 5 years old. The defect only came about because we got some new clients


Are the new clients trying to actually validate the data against the schema/wsdl you sent them? If that is the case, then either the schema/wsdl is wrong, or the messages you are sending don't match the schema/wsdl.

Again, this points as much to some kind of non-conformant processing by the "working" clients, and that the message flow is producing a non-conformant message. Or at least one that doesn't match the schema/wsdl/whatever.
_________________
chmod -R ugo-wx /
Back to top
View user's profile Send private message
huwgb
PostPosted: Wed Jun 22, 2016 4:13 pm    Post subject: Reply with quote

Novice

Joined: 07 May 2013
Posts: 21

So... Namespace declarations can be restricted at the schema level?

So I can write a schema such that the below is valid:
Example 1:
Code:

<NS1:rootElement xmlns:NS1="namespacedeclaration1" xmlns:NS2="namespacedeclaration2">
<NS2:leafElement>Some Value</NS2:leafElement>
</NS1:rootElement>


But the below is invalid:
Example 2:
Code:

<NS1:rootElement xmlns:NS1="namespacedeclaration1">
<NS2:leafElement xmlns:NS2="namespacedeclaration2">Some Value</NS2:leafElement>
</NS1:rootElement>


Because that is my situation.
Anyway, when I get more time I will be testing the recursive functions I built a few posts back. Hopefully they don't uncover any more issues.

mqjeff:
The messages are validating against the schema/wsdls provided. The Provider system we transform the messages into is not handling them when the messages match the structure outlined in example 2 above.

maurito:
Regarding your two options:
Option 1 broke some of the fields that handled MTOM and Base64 attachments, so a lot of care had to be taken to use that.
Option 2 would send 'null' or empty values to the provider for optional fields that aren't mapped, too great a risk.

Thank you for the suggestions nonetheless.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Wed Jun 22, 2016 5:27 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

huwgb wrote:
So... Namespace declarations can be restricted at the schema level?

So I can write a schema such that the below is valid:
Example 1:
Code:

<NS1:rootElement xmlns:NS1="namespacedeclaration1" xmlns:NS2="namespacedeclaration2">
<NS2:leafElement>Some Value</NS2:leafElement>
</NS1:rootElement>


But the below is invalid:
Example 2:
Code:

<NS1:rootElement xmlns:NS1="namespacedeclaration1">
<NS2:leafElement xmlns:NS2="namespacedeclaration2">Some Value</NS2:leafElement>
</NS1:rootElement>


Because that is my situation.
Anyway, when I get more time I will be testing the recursive functions I built a few posts back. Hopefully they don't uncover any more issues.

mqjeff:
The messages are validating against the schema/wsdls provided. The Provider system we transform the messages into is not handling them when the messages match the structure outlined in example 2 above.

maurito:
Regarding your two options:
Option 1 broke some of the fields that handled MTOM and Base64 attachments, so a lot of care had to be taken to use that.
Option 2 would send 'null' or empty values to the provider for optional fields that aren't mapped, too great a risk.

Thank you for the suggestions nonetheless.

Well there is nothing wrong at the XML level with exemple 2 and as such it should validate. If your destination system is not handling them, tell them they need to use a compliant parser...
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
maurito
PostPosted: Wed Jun 22, 2016 7:25 pm    Post subject: Reply with quote

Partisan

Joined: 17 Apr 2014
Posts: 358

huwgb wrote:


maurito:
Regarding your two options:
Option 1 broke some of the fields that handled MTOM and Base64 attachments, so a lot of care had to be taken to use that.
Option 2 would send 'null' or empty values to the provider for optional fields that aren't mapped, too great a risk.

Thank you for the suggestions nonetheless.


I didn't say you have to use them in ALL the fields. You use that ONLY in the one you were complaining about, as I showed in the example.
Back to top
View user's profile Send private message
joebuckeye
PostPosted: Thu Jun 23, 2016 4:51 am    Post subject: Reply with quote

Partisan

Joined: 24 Aug 2007
Posts: 364
Location: Columbus, OH

fjb_saper wrote:
huwgb wrote:
Example 1:
Code:

<NS1:rootElement xmlns:NS1="namespacedeclaration1" xmlns:NS2="namespacedeclaration2">
<NS2:leafElement>Some Value</NS2:leafElement>
</NS1:rootElement>


But the below is invalid:
Example 2:
Code:

<NS1:rootElement xmlns:NS1="namespacedeclaration1">
<NS2:leafElement xmlns:NS2="namespacedeclaration2">Some Value</NS2:leafElement>
</NS1:rootElement>



Well there is nothing wrong at the XML level with exemple 2 and as such it should validate. If your destination system is not handling them, tell them they need to use a compliant parser...




Your 2 examples are logically equivalent.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Small issue with namespace declaration copying
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.