commiting some work done while in the Maldives (hence the timezone on the
* relaxng.c xmlschemas.c include/libxml/schemasInternals.h: commiting
some work done while in the Maldives (hence the timezone on the
laptop !)
* result/schemas/length3* test/schemas/deter0_*
test/schemas/group0_*: some tests added too
Daniel
diff --git a/ChangeLog b/ChangeLog
index b2a56ab..c9eea99 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Jun 2 21:56:15 MVT 2003 Daniel Veillard <daniel@veillard.com>
+
+ * relaxng.c xmlschemas.c include/libxml/schemasInternals.h: commiting
+ some work done while in the Maldives (hence the timezone on the
+ laptop !)
+ * result/schemas/length3* test/schemas/deter0_*
+ test/schemas/group0_*: some tests added too
+
Mon Jun 2 15:34:17 CEST 2003 Daniel Veillard <daniel@veillard.com>
* encoding.c: small fix
diff --git a/include/libxml/schemasInternals.h b/include/libxml/schemasInternals.h
index 54e8fb3..3cf3ff6 100644
--- a/include/libxml/schemasInternals.h
+++ b/include/libxml/schemasInternals.h
@@ -342,6 +342,7 @@
xmlHashTablePtr schemasImports;
void *_private; /* unused by the library for users or bindings */
+ xmlHashTablePtr groupDecl;
};
void xmlSchemaFreeType (xmlSchemaTypePtr type);
diff --git a/relaxng.c b/relaxng.c
index 99ff9e9..c17b344 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -2659,9 +2659,9 @@
*/
void
xmlRelaxNGCleanupTypes(void) {
+ xmlSchemaCleanupTypes();
if (xmlRelaxNGTypeInitialized == 0)
return;
- xmlSchemaCleanupTypes();
xmlHashFree(xmlRelaxNGRegisteredTypes, (xmlHashDeallocator)
xmlRelaxNGFreeTypeLibrary);
xmlRelaxNGTypeInitialized = 0;
diff --git a/result/schemas/length3_0_0 b/result/schemas/length3_0_0
index 6ea7515..e69de29 100644
--- a/result/schemas/length3_0_0
+++ b/result/schemas/length3_0_0
@@ -1 +0,0 @@
-./test/schemas/length3_0.xml validates
diff --git a/result/schemas/length3_0_0.err b/result/schemas/length3_0_0.err
index fa7cd52..d7d8041 100644
--- a/result/schemas/length3_0_0.err
+++ b/result/schemas/length3_0_0.err
@@ -1 +1,2 @@
+compilation error
Schemas: element size type non-positive-integer not found
diff --git a/test/schemas/deter0_0.xml b/test/schemas/deter0_0.xml
new file mode 100644
index 0000000..0ea1a41
--- /dev/null
+++ b/test/schemas/deter0_0.xml
@@ -0,0 +1,5 @@
+<book>
+ <odd-page>first page</odd-page>
+ <even-page>second page</even-page>
+ <odd-page>third page</odd-page>
+</book>
diff --git a/test/schemas/deter0_0.xsd b/test/schemas/deter0_0.xsd
new file mode 100644
index 0000000..8b5da69
--- /dev/null
+++ b/test/schemas/deter0_0.xsd
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="odd-page" type="xs:string"/>
+ <xs:element name="even-page" type="xs:string"/>
+ <xs:element name="book">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:element ref="odd-page"/>
+ <xs:element ref="even-page"/>
+ </xs:sequence>
+ <xs:element ref="odd-page" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/test/schemas/group0_0.xml b/test/schemas/group0_0.xml
new file mode 100644
index 0000000..bf58ba6
--- /dev/null
+++ b/test/schemas/group0_0.xml
@@ -0,0 +1,3 @@
+<author>
+ <name>Foo Bar</name>
+</author>
diff --git a/test/schemas/group0_0.xsd b/test/schemas/group0_0.xsd
new file mode 100644
index 0000000..7dfa393
--- /dev/null
+++ b/test/schemas/group0_0.xsd
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:group name="name">
+ <xs:choice>
+ <xs:element name="name" type="xs:string"/>
+ <xs:sequence>
+ <xs:element name="first-name" type="xs:string"/>
+ <xs:element name="middle-name" type="xs:string" minOccurs="0"/>
+ <xs:element name="last-name" type="xs:string"/>
+ </xs:sequence>
+ </xs:choice>
+ </xs:group>
+ <xs:element name="author">
+ <xs:complexType>
+ <xs:group ref="name"/>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/xmlschemas.c b/xmlschemas.c
index f2049af..fa623a8 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -25,7 +25,7 @@
#include <libxml/xmlautomata.h>
#include <libxml/xmlregexp.h>
-/* #define DEBUG 1 */ /* very verbose output */
+/* #define DEBUG 1 */
/* #define DEBUG_CONTENT 1 */
/* #define DEBUG_TYPE 1 */
/* #define DEBUG_CONTENT_REGEXP 1 */
@@ -406,6 +406,9 @@
if (schema->typeDecl != NULL)
xmlHashFree(schema->typeDecl,
(xmlHashDeallocator) xmlSchemaFreeType);
+ if (schema->groupDecl != NULL)
+ xmlHashFree(schema->groupDecl,
+ (xmlHashDeallocator) xmlSchemaFreeType);
if (schema->annot != NULL)
xmlSchemaFreeAnnot(schema->annot);
if (schema->doc != NULL)
@@ -436,6 +439,7 @@
int line = 0;
const xmlChar *file = NULL;
const xmlChar *name = NULL;
+ const xmlChar *prefix = NULL;
const char *type = "error";
if ((ctxt == NULL) || (ctxt->error == NULL))
@@ -467,6 +471,9 @@
file = node->doc->URL;
if (node->name != NULL)
name = node->name;
+ if ((node->type == XML_ELEMENT_NODE) && (node->ns != NULL) &&
+ (node->ns->prefix != NULL))
+ prefix = node->ns->prefix;
}
}
@@ -475,9 +482,15 @@
else if (schema != NULL)
type = "runtime error";
- if ((file != NULL) && (line != 0) && (name != NULL))
+ if ((file != NULL) && (line != 0) && (name != NULL) && (prefix != NULL))
+ ctxt->error(ctxt->userData, "%s: file %s line %d element %s:%s\n",
+ type, file, line, prefix, name);
+ else if ((file != NULL) && (line != 0) && (name != NULL))
ctxt->error(ctxt->userData, "%s: file %s line %d element %s\n",
type, file, line, name);
+ else if ((file != NULL) && (name != NULL) && (prefix != NULL))
+ ctxt->error(ctxt->userData, "%s: file %s element %s:%s\n",
+ type, file, prefix, name);
else if ((file != NULL) && (name != NULL))
ctxt->error(ctxt->userData, "%s: file %s element %s\n",
type, file, name);
@@ -485,6 +498,8 @@
ctxt->error(ctxt->userData, "%s: file %s line %d\n", type, file, line);
else if (file != NULL)
ctxt->error(ctxt->userData, "%s: file %s\n", type, file);
+ else if ((name != NULL) && (prefix != NULL))
+ ctxt->error(ctxt->userData, "%s: element %s:%s\n", type, prefix, name);
else if (name != NULL)
ctxt->error(ctxt->userData, "%s: element %s\n", type, name);
else
@@ -741,7 +756,7 @@
*
* Lookup a type in the schemas or the predefined types
*
- * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
+ * Returns the group definition or NULL if not found.
*/
static xmlSchemaTypePtr
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
@@ -835,7 +850,7 @@
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Could not add notation %s\n",
+ ctxt->error(ctxt->userData, "Notation %s already defined\n",
name);
xmlFree((char *) ret->name);
xmlFree(ret);
@@ -886,7 +901,7 @@
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Could not add attribute %s\n",
+ ctxt->error(ctxt->userData, "Attribute %s already defined\n",
name);
xmlFree((char *) ret->name);
xmlFree(ret);
@@ -934,7 +949,7 @@
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Could not add attribute group %s\n",
+ ctxt->error(ctxt->userData, "Attribute group %s already defined\n",
name);
xmlFree((char *) ret->name);
xmlFree(ret);
@@ -990,7 +1005,7 @@
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Could not add element %s\n",
+ ctxt->error(ctxt->userData, "Element %s already defined\n",
name);
xmlFree((char *) ret->name);
xmlFree(ret);
@@ -1040,7 +1055,57 @@
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Could not add type %s\n", name);
+ ctxt->error(ctxt->userData, "Type %s already defined\n", name);
+ xmlFree((char *) ret->name);
+ xmlFree(ret);
+ return (NULL);
+ }
+ ret->minOccurs = 1;
+ ret->maxOccurs = 1;
+
+ return (ret);
+}
+
+/**
+ * xmlSchemaAddGroup:
+ * @ctxt: a schema validation context
+ * @schema: the schema being built
+ * @name: the group name
+ *
+ * Add an XML schema Group definition
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaTypePtr
+xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+ const xmlChar * name)
+{
+ xmlSchemaTypePtr ret = NULL;
+ int val;
+
+ if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
+ return (NULL);
+
+ if (schema->groupDecl == NULL)
+ schema->groupDecl = xmlHashCreate(10);
+ if (schema->groupDecl == NULL)
+ return (NULL);
+
+ ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
+ if (ret == NULL) {
+ ctxt->nberrors++;
+ if ((ctxt != NULL) && (ctxt->error != NULL))
+ ctxt->error(ctxt->userData, "Out of memory\n");
+ return (NULL);
+ }
+ memset(ret, 0, sizeof(xmlSchemaType));
+ ret->name = xmlStrdup(name);
+ val = xmlHashAddEntry2(schema->groupDecl, name, schema->targetNamespace,
+ ret);
+ if (val != 0) {
+ ctxt->nberrors++;
+ if ((ctxt != NULL) && (ctxt->error != NULL))
+ ctxt->error(ctxt->userData, "Group %s already defined\n", name);
xmlFree((char *) ret->name);
xmlFree(ret);
return (NULL);
@@ -1808,6 +1873,7 @@
schema->targetNamespace);
else
ret = xmlSchemaAddElement(ctxt, schema, name, namespace);
+ ret->node = node;
if (namespace != NULL)
xmlFree(namespace);
if (ret == NULL) {
@@ -2118,7 +2184,7 @@
snprintf(buf, 99, "anongroup%d", ctxt->counter++ + 1);
name = xmlStrdup((xmlChar *) buf);
}
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddGroup(ctxt, schema, name);
if (type == NULL)
return (NULL);
type->node = node;
@@ -3456,6 +3522,8 @@
xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
break;
case XML_SCHEMA_TYPE_GROUP:
+ if (type->subtypes == NULL) {
+ }
case XML_SCHEMA_TYPE_COMPLEX:
case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
if (type->subtypes != NULL)
@@ -3470,10 +3538,11 @@
}
/**
* xmlSchemaBuildContentModel:
- * @typeDecl: the schema type definition
+ * @elem: the element
* @ctxt: the schema parser context
+ * @name: the element name
*
- * Fixes the content model of the element.
+ * Builds the content model of the element.
*/
static void
xmlSchemaBuildContentModel(xmlSchemaElementPtr elem,
@@ -3507,19 +3576,29 @@
xmlSchemaBuildAContentModel(elem->subtypes, ctxt, name);
xmlAutomataSetFinalState(ctxt->am, ctxt->state);
elem->contModel = xmlAutomataCompile(ctxt->am);
- if (!xmlAutomataIsDeterminist(ctxt->am)) {
- xmlGenericError(xmlGenericErrorContext,
+ if (elem->contModel == NULL) {
+ xmlSchemaErrorContext(ctxt, NULL, elem->node, NULL);
+ if ((ctxt != NULL) && (ctxt->error != NULL))
+ ctxt->error(ctxt->userData,
+ "failed to compile %s content model\n",
+ name);
+ ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
+ ctxt->nberrors++;
+ } else if (xmlRegexpIsDeterminist(elem->contModel) != 1) {
+ xmlSchemaErrorContext(ctxt, NULL, elem->node, NULL);
+ if ((ctxt != NULL) && (ctxt->error != NULL))
+ ctxt->error(ctxt->userData,
"Content model of %s is not determinist:\n", name);
ctxt->err = XML_SCHEMAS_ERR_NOTDETERMINIST;
- ctxt->state = NULL;
+ ctxt->nberrors++;
} else {
#ifdef DEBUG_CONTENT_REGEXP
xmlGenericError(xmlGenericErrorContext,
"Content model of %s:\n", name);
xmlRegexpPrint(stderr, elem->contModel);
#endif
- ctxt->state = NULL;
}
+ ctxt->state = NULL;
xmlFreeAutomata(ctxt->am);
ctxt->am = NULL;
}