0
votes

I have an issue with validation in libxml2, in that xmlSchemaValidateDoc fails with the following errors:

Element '{http://evcom.dk}cdr', attribute 'xmlns:xs': The attribute 
'xmlns:xs' is not allowed.
Element '{http://evcom.dk}cdr', attribute 'xmlns:tns': The attribute 
'xmlns:tns' is not allowed.

The generated xml file validates when using xmllint, and after some working-around I found that the file also validates if I save and read-back the xml document before doing the validation.

In other words, with the (simplified - without error checking) code:

char *path = "/home/dev/cdr.xml";
char *namespace = "http://evcom.dk";
xmlDocPtr pDoc = xmlNewDoc(BAD_CAST "1.0");
xmlNsPtr tns = xmlNewNs(NULL, BAD_CAST namespace, BAD_CAST "tns");
xmlNodePtr xnpRoot = xmlNewNode(tns, BAD_CAST "cdr");
xmlNewProp(xnpRoot, BAD_CAST "xmlns:xs", 
    BAD_CAST "http://www.w3.org/2001/XMLSchema");
xmlNewProp(xnpRoot, BAD_CAST "xmlns:tns", BAD_CAST namespace);
xmlDocSetRootElement(pDoc, xnpRoot);
xmlNodePtr xnpChild1 = xmlNewChild(xnpRoot, tns, BAD_CAST "test", NULL);
xmlAddChild(xnpChild1, xmlNewText(BAD_CAST "TEST"));
xmlSaveFormatFileEnc(path, pDoc, "UTF-8", 1);
//xmlFreeDoc(pDoc);
//pDoc = xmlReadFile(path, NULL, XML_PARSE_NONET);
char *schemaPath = "/home/dev/cdr.xsd";
xmlDocPtr pSchemaDoc = xmlReadFile(schemaPath, NULL, XML_PARSE_NONET);
xmlSchemaParserCtxtPtr pParser = xmlSchemaNewDocParserCtxt(pSchemaDoc);
xmlSchemaPtr pSchema = xmlSchemaParse(pParser);
xmlSchemaValidCtxtPtr pSchemaCtxt = xmlSchemaNewValidCtxt(pSchema);
xmlSchemaSetValidErrors(pSchemaCtxt, NULL, NULL, NULL);
xmlSchemaValidateDoc(pSchemaCtxt, pDoc);

the doc does not validate, but if I uncomment the two lines before the "char *schemaPath" line, the doc validates.

This issue has been found to be present on x86 and arm linux 32bit platforms, with libxml version 2.9.1 and 2.9.2, using precompiled or my-own-compiled version of the library.

Can someone shed some light, please?

For reference, the xsd file:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://evcom.dk" 
    elementFormDefault="qualified" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:tns="http://evcom.dk">
    <xs:element name="cdr">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="test">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:minLength value="1"/>
                            <xs:maxLength value="9"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

And the generated xml file:

<?xml version="1.0" encoding="UTF-8"?>
<tns:cdr xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:tns="http://evcom.dk">
  <tns:test>TEST</tns:test>
</tns:cdr>
1
//pDoc = xmlReadFile(path, NULL, XML_PARSE_NONET); --> You have specified encoding = NULL whereas you have saved xml file with encoding = "UTF-8".cm161

1 Answers

0
votes

Never add namespaces with xmlNewProp. This function should only be used for attributes. Use xmlNewNs to add namespace declarations. Replace the lines

xmlNewProp(xnpRoot, BAD_CAST "xmlns:xs", 
    BAD_CAST "http://www.w3.org/2001/XMLSchema");
xmlNewProp(xnpRoot, BAD_CAST "xmlns:tns", BAD_CAST namespace);

with

xmlNewNs(xnpRoot, BAD_CAST "http://www.w3.org/2001/XMLSchema",
    BAD_CAST "xs");

(The xmlns:tns declaration is added implicitly.)