[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [xml] Validation problems with an XML without default namespace



Hi,

On Thu, 2005-09-29 at 18:36 +0200, Samuel Díaz García wrote:
> Dear guys, first sorry for my english, and second, the problem.
> 
> I have a plain XML in a memory buffer as:
> 
> <E1>
> </E1>
> 
> Parsed in a xmlDocPtr without problems.
> 
> In the other hand I have a XSD file to validate the XML buffer and my 
> xmlSchemaValidCtxtPtr prepared for that XSD file.
> 
> The XSD defines a namespace not present in my plain XML and parsed x_doc 
> (xmlDocPtr type variable).
> 
> When I run (with error checks omited and tested all these lines executes 
> perfectly):
> 
> xmlDocPtr x_doc = xmlReadDoc(
> 	BAD_CAST my_buffer_xml_ptr,
> 	0, // Uri
> 	my_encoding, // Encode
> 	0 // Opciones
> 	);
> xmlSchemaParserCtxtPtr x_sh_parser_ctxt = xmlSchemaNewParserCtxt(
> 	BAD_CAST "my path to the XSD file"
> 	);
> xmlSchemaPtr x_sh = xmlSchemaParse( x_sh_parser_ctxt );
> xmlSchemaValidCtxtPtr x_sh_ctxt = xmlSchemaNewValidCtxt( x_sh );
> 
> I have in x_sh_ctxt my validation context and in x_doc my tree.
> 
> And, the real problem, the next line is:
> 
> int res = xmlSchemaValidateDoc(x_sh_ctxt, x_doc);
> 
> After this line, the validation works, but it says to me that a NS is 
> required. I tried this (before the xmlSchemaValidateDoc() call):
> 
> xmlNsPtr x_ns = 0;
> xmlNsPtr x_ns2 = 0;
> int kk;
> xmlNodePtr x_raiz = xmlDocGetRootElement( x_doc );
> x_ns = xmlNewNs( x_raiz, BAD_CAST "urn:hl7-org:v2xml", BAD_CAST "" );
> if( x_ns ) {
> 	xmlSetNs( x_raiz, x_ns );
> }
> x_ns2 = xmlNewNs( x_raiz, BAD_CAST "urn:hl7-org:v2xml", BAD_CAST "n" );
> if( x_ns2 ) {
> 	xmlSetNs( x_raiz, x_ns2 );
> }
> kk = xmlReconciliateNs( x_doc, x_raiz );

In other words: you are trying to fix the instance by binding the
nodes to the correct namespace, right?

For namespace-normalization I recommend using
xmlDOMWrapReconcileNamespaces() rather than xmlReconciliateNs(), since
the latter will break namespace-wellformedness in special cases.
This would have the nice side-effect, that you would test the first
function, since it is rather new ;-)

With xmlNewNs() you create a namespace declaration on the x_raiz
element.

With xmlSetNs() you bind the element x_raiz to the newly created
namespace declaration.

xmlReconciliateNs() tries to assure namespace-wellformedness; it
will walk the given node-branch and create missing namespace
declarations. I.e. if a node is bound to a namespace declaration,
which is not is scope (in the parent axis), a new namespace
declaration will be created and assigned.

> But now, appears only the root element has a namespace assigned and the 
> validation fails in first root element child, because it not found the 
> namespace.

Yes, what xmlReconciliateNs() does not, is to bind nodes to any declared
namespaces. I.e., speaking in terms of DOM, it will not change the
namespaceURI property of a node. Thus all the other nodes in your tree
are still in the old namespace (or none at all).

> 
> The libxml2 library is not the last version, but before I upgrade the 
> version I want to know if I must use a function as:
> 
> void setElementNS(xmlNode * a_node,xmlNsPtr nameSpace)
> {
>      xmlNode *cur_node = NULL;
>      for (cur_node = a_node; cur_node; cur_node =
> cur_node->next) {
>          if (cur_node->type == XML_ELEMENT_NODE) {
>              cur_node->ns=nameSpace;
>          }
>          setElementNS(cur_node->children,nameSpace);
>      }
> }
> 
> to assign "manually" the namespace to ALL elements, or there are an API 
> to do this task.
> 
> Any idea about this problem?

I think there's no such function in the lib, probably since it is easily
done on our side, plus there are a lot of cases where we might want
to assign a namespace only to _some_ elements or even to some
attribute nodes.
So, yes, remove xmlReconciliateNs() and use your function.

Probably a superflous information, but one can never be sure: If you
want to avoid recursion, then consult
xmlDOMWrapReconcileNamespaces() about how to traverse the
tree efficiently (in case you don't mind "gotos" ;-)).

Regards,

Kasimier



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]