[xml] libxml .xsd validation problem



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



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