Namespace in soap messages

Olivier,

I think you are confusing the prefix (“spp” in your example) with the namespace definition. The your first example, the namespace is not defined which makes the XML fragment non-deterministic as you didn’t specify to which namespace the prefix “spp” is referring.

You can’t always count on the prefix being something you expect in an incoming message. By populating nsdecls, you’ll be able to process xs:notifier, ns1:notifier or spp:notifier as long as those prefixes are associated with the namespace "http://opp.edf.fr/spp/messageriesoap".

Including namespace definitions in the body of soap messages is a Soap spec requirement. The requirement to use nsdecls is tied to that.

HTH,

Mark

Thanks for your answer !

It seems that the XML received message in my first post was interpreted when I posted it on the forum and the namespaces definitions disappeared. That’s strange…

You can find my full incoming xml message in Attachement.
As you can see, spp prefix is associated with the namespace “http://opp.edf.fr/spp/messageriesoap” in my original message.
But if I don’t declare it in nsDecls field, it’s not recognised in my extracted message. Does the trouble come from the fact that the spp prefix is defined in the “spp:Notifier” tag and not in the header ?


XMLmessage.txt (0.4 k)

If you uncheck the “Enable HTML code in message” box, the forum software should display the entire message. When we switch to vBulletin (maybe this weekend, cross your fingers), you’ll be able to put HTML, XML or Java code in a “code” box.

At any rate, declaring the namespace helps IS know which “Notifier” element you are referring to. This comes in handy when validating the document created from this pub.xml:xmlNodeToDocument call against a document type generated from an XML schema. Without defining the namespace, IS does not know how to validate it properly.

Again, you can use any prefix in your nsdecls parameter, but the namespace definition must match exactly. This comes in handy when using pub.xml:queryXMLNode to extract a portion of an XML document from a node using an XQL query because your queries can use a prefix you define without caring how they came into IS.

Bottom line, this is how IS (and Developer) work. I think there are good reasons for this behavior. You can protest and fight it, but don’t expect webMethods or anyone who has worked with the product for any length of time to consider changing this behavior.

HTH,

Mark

Olivier,
Take a look at this thread - http://www.wmusers.com/wmusers/messages/117/88082.shtml?1133540964 . There are several suggestions from Mark C and myself on how to accomplish this. Note from the above thread that prefixs are assigned (if at all) arbitrarily on the sending system, in others words you will never know what the potential prefix a potential client like Axis, .Net, whatever is going to send. The requirement is that when they send them they are defined and mapped to a namespace. There is no requirement on what they are called.

markg
http://darth.homelinux.net

Olivier,

I’m not quite sure of the sequence of steps you are following. I’ll assume it is:

  1. Create a soapData object from the example xml string using pub.soap.utils:stringToSoapData
  2. Extract the body from the soap message using pub.soap.utils:getBody
  3. Convert the resulting body object to a document using pub.xml:xmlNodetoDocument with the nsdecls parameter populated as you stated above with the “spp” prefix (could be any prefix as long as the namespace matches).
  4. Convert the document back to an XML string by mapping the “document” output (with no renaming) from xmlNodeToDocument to the document input of pub.xml:documentToXMLString and setting the nsdecls parameter to define the spp prefix with the correct namespace.

This sequence of steps takes a soap message that looks like this:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/ xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance xmlns:xsd="http://www.w3.org/2001/XMLSchema
SOAP-ENV:Body
<m:Notifier xmlns:m="http://opp.edf.fr/spp/messageriesoap "
<m:IDCanal>String</m:IDCanal>
</m:Notifier>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

and produces and xml string that looks like this


<spp:Notifier
xmlns:spp=“http://opp.edf.fr/spp/messageriesoap
spp:IDCanalString</spp:IDCanal>
</spp:Notifier>

( I removed the “xsi” prefix definition as it was unecessary).

The only way I could reproduce your behavior was to rename the output of the xmlNodeToDocument service to “m:Notifier” and not define “m” in the documentToXMLString step.

In short, if you use the services they way they are designed to be used, they will produce the desired output.

Mark

I’ve seen Mark indicate in several posting that the namespace in the nsDecls parameter must match the namespace in the incoming XML message when using pub.xml:documentToXMLString and pub.xml:queryXMLNode. I’ve attached a sample SOAP body that I extract using the pub.soap.utils:getBody service.


SOAP-ENV:Body
<wsdns1:myServiceInput xmlns:wsdns1=“http://myTest.com/myservice”>
123
34sdf
sdf
sdf
</wsdns1:myServiceInput></SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The pub.xml:documentToXMLString service works regardless of what namespace I provide. In fact, I can provide the wrong namespace or no namespace at all and it still works.

The pub.xml:queryXMLNode service has the same behavior when I query for the node name using “/*/nodeName()”. However, when I query for fields within the XML document using a query such as “/dx:myServiceInput/field1/text()” the namespace must match.

Can someone explain why pub.xml:documentToXMLString and pub.xml:queryXMLNode (in some situations) don’t actually require the correct namespace in the nsDecls parameter?

Thanks,
Fred

Fred,

Great questions.

pub.xml:documentToXMLString is used to create an XML string representation of an IData (document type). It will use whatever you specify in the nsdecls, but may not generate useful XML if you don’t match a prefix with an entry in the nsdecls.

For example, if your input document contained an element called foo:myVar where foo was associated with the namespace http://myNamespace, but you set your nsdecls to define bar instead, you would end up with the following xmlstring:

<foo:myDoc
xmlns:bar=“http://myNamespace”>
foo:myVarString</foo:myVar>
</foo:myDoc>

This may be technically well-formed, but would be nondeterminsitic on its own because you haven’t defined what namespace is to be associated with the “foo” prefix.

pub.xml:queryXMLNode requires that the prefixes match if you want to be able to use XQL queries that specify a prefix of your choosing that will work regardless of what prefix the client sends. The XQL query “/*/nodeName()” works because the “*” is a wildcard meaning give me the nodeName of the root element regardless of how it is named.

pub.xml:nodeToDocument will name the resulting “document” based on whether it finds a match on the namespace. If the namespace matches it will use the prefix associated with that namespace in nsdecls. If not it will use the prefix that was supplied in the orignal node. Again, this is handy since you don’t know what prefix the sender will use and you can always create a document with a name you expect by correctly specifying the namespace definition.

BTW, the soap spec requires that the contents of the soap body be namespace qualified. While you can turn validation for this off in IS, you will reduce the interoperability of your web services.

HTH,

Mark

Hi All,

I m getting xmlInput from external system which has sbs:ENVELOPE init and I m converting that into document using pub.xml.xmlStringToXMLNode and pub.xml.xmlNodeToDocument.
In the generated document structure is as document/sbs:ENVELOPE/HEADER/Transaction.
But my webservice connector format is tns:document/tns:HEADER/tns:TransactionContext.

Please let me know how do I pass the values to tns:document/tns:HEADER/tns:TransactionContext from
document/sbs:ENVELOPE/HEADER/Transaction.

Please help me it is very urgent.