Hello,

I'm working on a project which requires validation of xml documents against 
.xsd schemas.  We both create xml documents from scratch, and create xml docs 
from char * buffers read from a socket.  I've run into trouble validating the 
docs created from buffers, even when the buffers are generated from a document 
that already validated successfully.

For example I have the following schema in a file called "example.xsd":

<?xml version="1.0" encoding="UTF-8"?>
<!--
 A simple test schema
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
    targetNamespace="http://localhost/test_namespace";
    xmlns="http://localhost/test_namespace";>

    <xs:complexType name="testType">
      <xs:sequence minOccurs="1" maxOccurs="1">
        <xs:element name="element1" type="xs:string"/>
        <xs:element name="element2" type="xs:int"/>
      </xs:sequence>
    </xs:complexType>

    <xs:element name="testInstance" type="testType"/>
</xs:schema>

The following code creates an xml doc from scratch, which validates.  It then 
dumps that doc into a buffer, reads that buffer into a new doc, and tries to 
validate that, but the second validation fails:

void test_validate() {
        xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
        xmlNodePtr root_node = xmlNewNode(NULL, BAD_CAST "testInstance");
        xmlDocSetRootElement(doc, root_node);
    
        //set the namespace
        root_node->ns = xmlNewNs(root_node, BAD_CAST 
"http://localhost/test_namespace";, NULL);
        root_node->nsDef = root_node->ns;
    
        //create the children
        xmlNsPtr child_ns = xmlNewNs(NULL, NULL, NULL);
        xmlNewChild(root_node, child_ns, BAD_CAST "element1", BAD_CAST "foo");
        xmlNewChild(root_node, child_ns, BAD_CAST "element2", BAD_CAST "1");

        xmlSaveFormatFileEnc("generated.xml", doc, "UTF-8", 1);

        int ret = 0;   
        ret = is_valid(doc->xmlChildrenNode, "example.xsd");
        if(ret == 0)
                printf("generated doc is valid\n");
        else
                printf("generated doc is invalid\n");

        //dump the doc to a buffer:
        xmlChar *xmlbuff;
        int buf_size;  
        xmlDocDumpFormatMemory(doc, &xmlbuff, &buf_size, 1);

        xmlDocPtr new_doc = xmlReadMemory((char *)xmlbuff, buf_size, NULL, 
"UTF-8", XML_PARSE_NOBLANKS);

        xmlSaveFormatFileEnc("buffer.xml", doc, "UTF-8", 1);
    
        ret = is_valid(new_doc->xmlChildrenNode, "example.xsd");
        if(ret == 0)
                printf("doc from buffer is valid\n");
        else
                printf("doc from buffer is invalid\n");
}

Here's the is_valid() function:

int is_valid(xmlNodePtr node, char *schema_filename)
{      
        xmlSchemaParserCtxtPtr parser_ctxt = 
xmlSchemaNewParserCtxt(schema_filename);
        if (parser_ctxt == NULL) {
                /* unable to create a parser context for the schema */
                return -1;
        }
        xmlSchemaPtr schema = xmlSchemaParse(parser_ctxt);
        if (schema == NULL) {
                /* the schema itself is not valid */
                xmlSchemaFreeParserCtxt(parser_ctxt);
                return -2;
        }
        xmlSchemaValidCtxtPtr valid_ctxt = xmlSchemaNewValidCtxt(schema);
        if (valid_ctxt == NULL) {
                /* unable to create a validation context for the schema */
                xmlSchemaFree(schema);
                xmlSchemaFreeParserCtxt(parser_ctxt);
                return -3;
        }
       
        int valid = xmlSchemaValidateOneElement(valid_ctxt, node);
        xmlSchemaFreeValidCtxt(valid_ctxt);
        xmlSchemaFree(schema);
        xmlSchemaFreeParserCtxt(parser_ctxt);
        xmlCleanupParser();

        return valid;
}

The output generated when this runs is:

generated doc is valid
element element1: Schemas validity error : Element 
'{http://localhost/test_namespace}element1': This element is not expected. 
Expected is ( element1 ).
doc from buffer is invalid

I dump both docs to output files (generated.xml and buffer.xml), and I 
confirmed that they're the same on disk using diff.

The problem seems to be that when libxml reads from the buffer it attaches the 
parent namespace to the children (if it isn't specified), which later causes 
validation to fail.  Is this a common problem?  Is there a standard workaround 
for this?

Thanks for your help,
Pat McClory
_______________________________________________
xml mailing list, project page  http://xmlsoft.org/
[email protected]
http://mail.gnome.org/mailman/listinfo/xml

Reply via email to