You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-users@xerces.apache.org by Ben Griffin <be...@redsnapper.net> on 2012/11/23 14:46:14 UTC

How to maintain implicit namespaces across importNode() over WSDL/XSD

I am currently using XercesC to extract and recompose the grammars embedded within an WSDL document.

At the DocumentElement level of the WSDL document (the wsdl:definitions element) there are (as is normal) all the namespace declarations used for the document. So, for instance,

xmlns:s3="http://foobar.com/mySOAP/commons"

As you probably know, typically, a sequence of schemas are defined under the "wsdl:types" element.
I am extracting these, so that I can subsequently load them as grammars and then validate / process the instance documents that they define.

For instance:

[...]
<s:schema elementFormDefault="qualified" targetNamespace="http://foobar.com/mySOAP/Responder">
      <s:import namespace="http://foobar.com/mySOAP/commons"/>
      <s:complexType abstract="true" name="Responder">
        <s:complexContent mixed="false">
          <s:extension base="s3:ErrorInfo">
            <s:sequence>
              <s:element maxOccurs="1" minOccurs="1" name="responsetime" type="s:double"/>
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
</s:schema>
[...]

So - during the process of extracting the schemas from the WSDL document, I am using importNode() as follows:

DOMElement* schema_node;	//points to the schema element in the WSDL  document..
DOMDocument* schema_doc =  impl->createDocument();
DOMNode* imported_node = schema_doc->importNode(schema_node,true);
schema_doc->appendChild(imported_node);

The schema_document is then installed as a grammar using DOMLSParser* parser->loadGrammar().

The PROBLEM is that the "s3:ErrorInfo" value loses the scope of the namespace prefix found in the original WSDL document.

What is the solution to this?  Should I itererate through the full list of xmlns:* attributes of the WSDL and insert them into the root element of the new schema_doc?  Or am I missing something?



Re: How to maintain implicit namespaces across importNode() over WSDL/XSD

Posted by Ben Griffin <be...@redsnapper.net>.
> The schema_document is then installed as a grammar using DOMLSParser* parser->loadGrammar().
> The PROBLEM is that the "s3:ErrorInfo" value loses the scope of the namespace prefix found in the original WSDL document.
> What is the solution to this?  Should I itererate through the full list of xmlns:* attributes of the WSDL and insert them into the root element of the new schema_doc?  Or am I missing something?

This is what I have done so far - which is indeed iterate through all document element attributes, looking for a match with xmlns:
Is there a more efficient way of doing this? Am I missing something?

DOMElement* schema_node;	//points to the schema element in the WSDL  document..
DOMDocument* schema_doc =  impl->createDocument();
DOMNode* imported_node = schema_doc->importNode(schema_node,true);
schema_doc->appendChild(imported_node);

[...]

const DOMDocument* schema_node_doc = schema_node->getOwnerDocument();
if ( schema_node_doc != NULL) {
	const DOMElement* wsdl_de = schema_node_doc->getDocumentElement();
	if (wsdl_de != NULL) {
		const DOMNamedNodeMap* wsdl_de_attr= wsdl_de->getAttributes();
		DOMElement* schema_de = schema_doc->getDocumentElement();
		if (schema_de != NULL && wsdl_de_attr != NULL ) {
			size_t n = wsdl_de_attr->getLength();
			for(size_t i=0; i<n; i++) {
				DOMAttr* ai = (DOMAttr*)(wsdl_de_attr->item(i));
				const u_str ain(ai->getName());		//u_str = std::basic_string<XMLCh>
				if (ain.compare(0,6,X("xmlns:")) == 0) {
					DOMAttr* iattr = (DOMAttr*)(schema_doc->importNode(ai,true));
					DOMAttr* oattr = schema_de->setAttributeNode(iattr);
					if ( oattr!= NULL ) { delete oattr; } //This attribute was already there.
				}
			}
		}
	}							
}