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


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:


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 

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

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 

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) {

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" ;-)).



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