How to determine namespace prefix declarations

Hi,

When transforming an XML string (read from a file) into an XML Node, any xmlns:xxx attributes used to specify what a given prefix “xxx” maps to, are lost.

These are required when querying the node, when converting to a document, or simply converting back to a string.

For example, when reading in a document with this root element:

<?xml version="1.0" encoding="UTF-8"?>

<ase:aseXML xmlns:ase=“urn:aseXML:r17” xmlns:xsi=“[URL=“http://www.w3.org/2001/XMLSchema-instance”]http://www.w3.org/2001/XMLSchema-instance[/URL]
xsi:schemaLocation=“urn:aseXML:r17
[URL=“http://www.nemmco.com.au/aseXML/schemas/r17/aseXML_r17.xsd”]http://www.nemmco.com.au/aseXML/schemas/r17/aseXML_r17.xsd[/URL]”>

I lose the references for “ase” and for “xsi”.

Am I doing something wrong? Is there “nice” a way to keep these as part of the node (and hence as part of the document the node is converted to)?

Or do I need to parse the string using a regex?

Any help appreciated!

Cheers,
Ben.

If you convert your string to a node using pub.xml:xmlStringToXMLNode and then use pub.xml:queryXMLNode you can view the namespaces. By populating the nsDecls parameter for either queryXMLNode or nodeToDocument, you can preserve both the prefixes and their associated namespaces or, if desired, convert the prefixes to ones that you are expecting.

A best practice is to avoid creating dependencies on the prefixes supplied by inbound XML documents as they are subject to change and still valid.

The Built-In Services Guide is a good resource for the pub.xml:* services.

Mark

Hi Mark,

Thanks for your reply.

I understand that the prefix is subject to change. This is ultimately why I’m trying to determine the actual prefixes used in the instance document, rather than hardcoding these in the nsDecls parameter.

I’m not able to see the namespaces using the queryXMLNode (at least, while running a trace).

Am I missing something?

Perhaps I should go back to the start so you have an understanding of what I’m doing (in case I’ve done something wrong - you can set me straight!).

1. Created document type based on schema (you can view this schema for yourself at
[URL=“http://www.nemmco.com.au/aseXML/schemas/r17/aseXML_r17.xsd”]http://www.nemmco.com.au/aseXML/schemas/r17/aseXML_r17.xsd[/color][/URL][COLOR=black])

(had to modify all the child schemas to ensure they had the same target namespace as parent, as chameleon includes not working… regardless of sp2 fix btw)

Found that document type called “ns:aseXML” instead of “ase:aseXML”. Renamed (as all instance documents will use this prefix).

2. Found that instances of this schema were failing, as they contained an xsi:schemaLocation attribute in the root node.

3. Modified schema to specify the optional use of a qualified schemaLocation attribute (this is supposed to be implied, I understand?). Re-created a webMethods document type based on the updated schema, now get
a new attribute called @ase:schemaLocation. Changed this to @xsi:schemaLocation.

4. Reading in an xml instance as bytes using pub.file:getFile.

File has the following root node
<ase:aseXML xmlns:ase=“urn:aseXML:r17” xmlns:xsi="[URL=“http://www.w3.org/2001/XMLSchema-instance”]http://www.w3.org/2001/XMLSchema-instance[/color][/URL][COLOR=black]"
xsi:schemaLocation="urn:aseXML:r17
[URL=“http://www.nemmco.com.au/aseXML/schemas/r17/aseXML_r17.xsd”]http://www.nemmco.com.au/aseXML/schemas/r17/aseXML_r17.xsd[/color][/URL][COLOR=black]">


5. Convert to a node using pub.string:bytesToString->pub.xml:xmlStringToXMLNode

6. queryXMLNode at this point shows no attributes for either of the two xmlns:xxx declerations.


Thanks heaps for your help.

Cheers,
Ben.

Hi Ben,
Why not just convert it to document and set the nsDecls parameter on the xmlNodetoDocument service? This will force the prefixes to match what you want as Mark C suggested.

Hi Mark G,

Yes that would generally make sense, I agree!

But the (I guess root) problem is that the framework of very strict market standards around the use of its XML schema and instances actually goes as far as to say that the prefixes must have a specific name. Non compliance to this is to be rejected as though the xml is invalid.

You and I know that bob:someTagName is the same as ben:somTagName (so long as in both instances the tag names reflect the same namespace)… but for whatever reason, ben: might be rejected becuase it’s not bob: in this environment.

So, your next question (or at least, mine would be…) will be “Doesn’t that make it EASIER to declare in hard-code what the prefixes and their values will be?”.

Yep. But it makes it harder to VALIDATE the incomming prefixes are correct!

It’s all academic now though. I’ve written a service that
a) Regex’s the xml string to extract the namespace declarations (prefixed and default) to determine the prefix and the actual namespace it represents.

b) Creates an nsDecls document containing fields named the same as the detected prefixes, with the values mapped from the namespace.

Part b was fun. I was suprised that the nsDecls document requires the VALUE of the prefix to be the NAME of a field… makes it hard to deal with at run time! Just goes to confirm it was never considered anyone would ever need to know the ACTUAL declerations from within source XML and then use these to generate some output (which is probably a reasonable assumption mind you… I’ve obviously found the exception to the rule!).

I do note that I’m not the first person to want this information at run time though; There’s a feature request with webMethods to have the stringToXMLNode service provide nsDecls, and I’ve found a couple of support articles that end with “this is not yet supported… feature due for next release”…

Thanks again to everyone for your help, I really appreciate it (and I really wish for once I was able to help others in return… but I don’t think I’m at that level yet!).

Cheers,
Ben.

Oh… and I need to retract my comment re: chameleon includes not working in ISsp2.

Somehow, I’ve managed to get an environment that includes developer 6.5sp3, but IS6.5sp1…

I suspect some incompetence (on my part) might have come in to play!! :wink:

Hi Ben,

If I understood your question correctly then here are my thoughts.

  1. How can we get prefix and namespace out of source xml to validate them?
    Solution : convert xmltoNode then query xmlnode.
    namespace = //namespace() (XQL)
    prefix = //prefix() (XQL)
    This will give you original namespace and prefix in pipeline as variables. Now you can validate prefix in you list of valid values.

  2. Validate document against document your document created from Schema.
    Solution : You would have document created from schema with ns: prefix and with original name space. Now when you convert your incoming xmlnode to document set nsDecls name=ns value= %namespace% (which is original incoming namespace from xmlfile). This will create incoming document with ns prefix, now we can validate against our webMethods document.

Hope this helps…

Cheers,
Ajit

Ajit,

Thankyou very much for the information mate.
You’re spot on - the XQL for //namespace() and //prefix() do work well.

So yes, I can validate that the prefix is correct, thanks.

I’m surprised that given the node apparently does retain this information, that it isn’t included as an attribute in the output from XMLNodeToDocument?

I do still need to ensure the NS: namespace prefix is REPLACED by the content of %prefix% though (as downstream systems may reject the ns: prefix). I had already achieved this by dropping to java to create a new field with that uses the contents of %prefix% as it’s name, and the content of %namespace% as it’s value. (But previously I was using a regex search on the input XML string to determine these values).

Thanks again,
Ben.

I am trying it out and would need more clarification from you. Following your step 1, I have created 2 stringList, NamespaceList and PrefixList with XQL. However, there are 95 items in NamespaceList and only 12 in PrefixList. There are repeated values in both lists. So I cannot match the 2 lists item by item. Could somebody explains what am I supposed to do with these 2 lists to validate my prefix?

Hi,
Why are you getting so mane Namespace and Prefixes in your XQL result?? Does your input xml has various prefixes and namespaces??? If yes then you will have to query at particular nodes where different namespace takes place…and get prefix for that node…
Could you please advise, what exactly you want to achieve?? i.e do you want to validate incoming xml against schema??? For just schema validation we dont need to worry about prefix.
or you want to make sure incoming xml has to have specific prefix??? by xml standard user should be able to use as prefix they like as far as it has valid name space…
Cheers,
Ajit Rathod

I agree with Ajit, attempting to validate a prefix on an incoming XML document is a BAD IDEA and should be avoided. Creators of XML documents should be able to use any prefix provided that it is associated with the correct namespace declaration. Attempting to require them to go against the XML schema specification in order to use your service will lead to problems and will also give others the impression that your company lacks experience with XML schema.

Mark

Yes, my doc does have various prefixes and namespaces. I am now trying to query each node. In order to do that, I need to use getXMLIterator. But for some reason, it is returning null value to me. I am only mapping node to my doc (which is body from getBody) and all other parameters as default. So now I trying every xml related service and none of them seems to work for me.

:sad:

Could you provide sample xml and what extly you want to do with that XML?? i.e conver to document and map to another document to get rid of prefix?? or conver to document with specific prefix?? or just validate incoming xml against schema??

More details and specific queries would help us to provide specific solution…

Cheers,
Ajit