Author |
Message
|
robgfrk |
Posted: Thu Oct 20, 2005 4:39 pm Post subject: WBI 5.0 ESQL function to strip namespace prefixes? |
|
|
Newbie
Joined: 20 Oct 2005 Posts: 2
|
Is there a function in WBI 5.0 ESQL that allows you to strip off the namespace prefix of a qualified element name so that you are left with the local name? e.g. make "soapenv:Envelope" into "Envelope".
Java and XPATH both have get-local-name or local-name functions that will do this for you. Is there an equivalent in WBI 5.0 ESQL? |
|
Back to top |
|
 |
MiLi |
Posted: Fri Oct 21, 2005 1:24 am Post subject: I have the same problem |
|
|
Acolyte
Joined: 07 Oct 2005 Posts: 51
|
Hi
I would also like to know this! |
|
Back to top |
|
 |
JLRowe |
Posted: Sat Oct 22, 2005 3:29 am Post subject: |
|
|
 Yatiri
Joined: 25 May 2002 Posts: 664 Location: South East London
|
Copy the tree, and recursively strip off the namespaces. Search for some recursive code in this forum. |
|
Back to top |
|
 |
elvis_gn |
Posted: Sun Oct 23, 2005 8:51 pm Post subject: |
|
|
 Padawan
Joined: 08 Oct 2004 Posts: 1905 Location: Dubai
|
Hi JLRowe,
Are you suggesting something like taking the entire message as a string and doing a REPLACE of anthing which is of the type "*:" by '' ......
It should work, i suppose..... |
|
Back to top |
|
 |
jefflowrey |
Posted: Mon Oct 24, 2005 3:00 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
No, he's suggesting walking the Input message tree recursively, and creating a new output message tree that has the same nodes but without the namespaces.
And there is example code to do exactly this, buried in this forum somewhere.
And if you SEARCH for it, you will find it. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
elvis_gn |
Posted: Mon Oct 24, 2005 3:16 am Post subject: |
|
|
 Padawan
Joined: 08 Oct 2004 Posts: 1905 Location: Dubai
|
Hi jefflowrey,
Thats what i meant........i guess
Instead of walking the Input message tree recursively in a loop, take the entire thing as BLOB, do a replace at one shot, of anythin which could be of type "<string>:"(it would be the namespace) and make it ""...........
Will it not work ?? |
|
Back to top |
|
 |
jefflowrey |
Posted: Mon Oct 24, 2005 3:24 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
It will work.
It might or might not be faster.
It might or might not be safer. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
Neil Harvey |
Posted: Wed Oct 26, 2005 9:52 am Post subject: |
|
|
Newbie
Joined: 08 Nov 2002 Posts: 4
|
I have searched the forum for the ESQL referenced above and have only found posts that attempt to provide a solution - all that I read were discounted by subsequent posts as not working. Can someone provide a link or new post of the solution? Or even some key words for searching that you think might lead to the post referenced above.
This should be a very common problem with a simple solution...existing XML service knows nothing about schemas, need to provide a new interface that does requiring a transformation that strips namespaces from the inbound XML. In our case the XML elements are exactly what is needed, only the namespaces need to be removed for all elements and all descendants.
Any assistance greatly appreciated. |
|
Back to top |
|
 |
jefflowrey |
Posted: Wed Oct 26, 2005 10:13 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Some variation of code posted here should work. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
TonyD |
Posted: Wed Oct 26, 2005 1:12 pm Post subject: |
|
|
Knight
Joined: 15 May 2001 Posts: 540 Location: New Zealand
|
I did this a while ago to strip a namespace prefix before writing the output message:
Code: |
-- Remove 'NS1:' prefixes
DECLARE msgBlob BLOB ASBITSTREAM(OutputRoot.MRM
ENCODING 546
CCSID 437
SET 'myMessageSet'
TYPE 'my MessageType'
FORMAT 'myMessageFormat';
DECLARE xmlnstnsBlob BLOB CAST('xmlns:NS1' AS BLOB
CCSID OutputRoot.MQMD.CodedCharSetId);
DECLARE xmlnsBlob BLOB CAST('xmlns' AS BLOB
CCSID OutputRoot.MQMD.CodedCharSetId);
DECLARE xmlnsNS1Blob BLOB CAST('NS1:' AS BLOB
CCSID OutputRoot.MQMD.CodedCharSetId);
SET OutputRoot.MRM = NULL;
-- Change 'xmlns:NS1=' declaration to 'xmlns='...
SET OutputRoot."BLOB"."BLOB" = REPLACE(msgBlob, xmlnstnsBlob, xmlnsBlob);
-- Replace all 'NS1:' prefixes with 'nothing'
SET OutputRoot."BLOB"."BLOB" = REPLACE(OutputRoot."BLOB"."BLOB", xmlnsNS1Blob);
|
Worked OK although the message recipient then decided to live with the prefixes so we did not need to use it. I have not run the code above lately but it should be OK. Replace 'NS1:' with your own prefix. |
|
Back to top |
|
 |
elvis_gn |
Posted: Wed Oct 26, 2005 8:22 pm Post subject: |
|
|
 Padawan
Joined: 08 Oct 2004 Posts: 1905 Location: Dubai
|
Hi,
TonyD, i notice that for "xmlns:NS1" you are replacing it with "xmlns"...shouldn't it be replace "xmlns:NS1" by "NS1" alone...???? The word before the ":" is the namespace..........
Also, the above code looks good, but we'll have to run it for each namespace in the Message....also NS1,NS2 are the default namespaces, what if we do not know the namespace name going to be used...i.e write a code which will work for any namespace.........
Has anyone tried using the LIKE operator within the REPLACE ??
Something which would be as LIKE '%:'
REPLACE(msgBlob, CAST(OutputRoot.MRM LIKE '%:' AS BLOB), '');
Don't know if this will work...no harm in trying
Regards. |
|
Back to top |
|
 |
robgfrk |
Posted: Thu Oct 27, 2005 11:28 am Post subject: |
|
|
Newbie
Joined: 20 Oct 2005 Posts: 2
|
Here's the procedure that I came up with for removing namespaces and their prefixes (which disappear automatically when the namespace is removed), based on the sample navigate recursive procedure contained in the ESQL manual. This procedure will also remove the "dreaded" WBI auto-generated namespaces and NS# prefixes!
CREATE PROCEDURE StripNamespaces(IN StartRefPtr REFERENCE)
BEGIN
DECLARE FieldRefPtr REFERENCE TO StartRefPtr;
MOVE FieldRefPtr FIRSTCHILD;
IF LASTMOVE(FieldRefPtr) THEN
IF FIELDTYPE(FieldRefPtr) IN (0x01000000, 0x03000000) THEN
SET FieldRefPtr.(XML.NamespaceDecl)* = NULL;
SET FieldRefPtr NAMESPACE = '';
END IF;
END IF;
WHILE LASTMOVE(FieldRefPtr) DO
CALL StripNamespaces(FieldRefPtr);
IF FIELDTYPE(FieldRefPtr) IN (0x01000000, 0x03000000) THEN
SET FieldRefPtr.(XML.NamespaceDecl)* = NULL;
SET FieldRefPtr NAMESPACE = '';
END IF;
MOVE FieldRefPtr NEXTSIBLING;
END WHILE;
END;
To use it you simply declare a reference to the starting position within an XML message where you want the namespaces removed and it will strip the namespaces from all its children and their siblings for fields of type 0x01000000 and 0x03000000 (i.e. tag field names and attribute names).
Note: You can specify additional field types as well by adding them to the IN list, but these two are the main types we are interested in.
For example, to strip the namespaces and prefixes from the XML document contained in the Body of a SOAP message:
DECLARE BodyRefPtr REFERENCE TO OutputRoot.XMLNS.soapenv:Envelope.soapenv:Body;
CALL StripNamespaces(BodyRefPtr);
Note: It is important that the reference pointer passed into the procedure points to an Output message structure and not an Input one. The message structure has to be modifiable in order for this to work. |
|
Back to top |
|
 |
lamtbs |
Posted: Mon Jul 10, 2006 6:12 am Post subject: |
|
|
Acolyte
Joined: 07 Nov 2005 Posts: 57 Location: Hong Kong
|
Hi,
the code works in most case, but we run into a strange problem.
When we have a default namespace, AND the default namespace is not the first entry. it will run into error......
E.g. the code will parse this okay
<?xml version="1.0" encoding="UTF-8"?>
<COS xmlns="http://www.abc.com/cos" xmlns:ais="http://www.abc.com/ais" xmlns:svm="http://www.abc.com/svm" xmlns:imc="http://www.abc.com/imc">
...... other XML tags ....
BUT this would cause an error because the default namespace is placed in the last entry
<?xml version="1.0" encoding="UTF-8"?>
<COS xmlns:ais="http://www.abc.com/ais" xmlns:svm="http://www.abc.com/svm" xmlns:imc="http://www.abc.com/imc" xmlns="http://www.abc.com/cos"> ...... other XML tags ......
It will cause error
"ParserException BIP5014E: Element must have a namespace specified if there is a default namespace in scope.
Whilst writing the XMLNS message, element 'COS' 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 'COS' is defined to be in a namespace. If element 'COS' belongs to the default namespace, then this element needs to be created in the default namespace. "
Wonder if this is bug?? |
|
Back to top |
|
 |
kimbert |
Posted: Mon Jul 10, 2006 6:56 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
If you delete all the xmlns attributes before writing the output message the problem will go away. I think a generic namespace-stripping algorithm like this ought to remove xmlns attributes anyway - after all, the receiving application is supposed to be ignorant about namespaces, so why would it want xmlns attributes? |
|
Back to top |
|
 |
madi |
Posted: Wed Oct 04, 2006 1:15 pm Post subject: |
|
|
 Chevalier
Joined: 17 Jan 2006 Posts: 475
|
Hi All
I used the procedure given above to strip the namespaces out from SOAP:Body
But then I need the name space for the parent element
but when i set the namespace for the parent element, it is giving the error that was discussed above
Quote: |
Element must have a namespace specified if there is a default namespace in scope. |
can we do this someway??
--madi |
|
Back to top |
|
 |
|