Schema validator reports the wrong child element as missing
With the following XSD schema
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Person" type="Person"/>
<xsd:complexType name="Person">
<xsd:sequence>
<xsd:element name="Name" type="xsd:string"/>
<xsd:element name="Role" type="xsd:string" maxOccurs="2"/>
<xsd:element name="Detail" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
validation of the following XML document
<Person>
<Name>Guido</Name>
<Role>TechnicalBackup</Role>
</Person>
produces the following result:
Error at line 4, column 0
Element 'Person': Missing child element(s). Expected is ( Role ).
repro.xml: failed to parse in line 4, col 0. Error 1871: Element 'Person': Missing child element(s). Expected is ( Role ).
It's clear from examining the schema and the XML document being validated that adding a second Role element is not necessary, and would do nothing to make the document valid. The correct assessment of the validation is that the required Details child element is missing.
Here's the repro code (built with the current HEAD of the master branch, commit e85f9b9):
#include <stdio.h>
#include <stdbool.h>
#include <libxml/xmlreader.h>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>
static void schemaParseErrorHandler(void *arg, xmlErrorPtr error) {
fprintf(stderr, "Error at line %d, column %d\n%s", error->line,
error->int2, error->message);
*((bool*)arg) = true;
}
int main(int argc, char **argv) {
xmlInitParser();
xmlSchemaPtr schema = NULL;
xmlSchemaParserCtxtPtr schema_parser_ctxt = NULL;
int has_schema_errors = 0;
int ret = -1;
xmlSchemaValidCtxtPtr valid_ctxt = NULL;
if ((schema_parser_ctxt = xmlSchemaNewParserCtxt("repro.xsd"))) {
schema = xmlSchemaParse(schema_parser_ctxt);
xmlSchemaFreeParserCtxt(schema_parser_ctxt);
if (schema) {
valid_ctxt = xmlSchemaNewValidCtxt(schema);
}
}
xmlTextReaderPtr reader = NULL;
const char* filename = "repro.xml";
reader = xmlReaderForFile(filename, NULL, 0);
if (reader != NULL) {
if (valid_ctxt) {
xmlTextReaderSchemaValidateCtxt(reader, valid_ctxt, 0);
xmlSchemaSetValidStructuredErrors(valid_ctxt,
schemaParseErrorHandler,
&has_schema_errors);
}
ret = xmlTextReaderRead(reader);
while (ret == 1 && !has_schema_errors) {
ret = xmlTextReaderRead(reader);
}
}
if (ret != 0) {
xmlErrorPtr err = xmlGetLastError();
fprintf(stdout,
"%s: failed to parse in line %d, col %d. Error %d: %s\n",
err->file,
err->line,
err->int2,
err->code,
err->message);
}
xmlFreeTextReader(reader);
xmlCleanupParser();
return 0;
}