Christian Glahn found a problem with a recent patch to
* parser.c: Christian Glahn found a problem with a recent
patch to xmlParseBalancedChunkMemoryRecover()
* xmlschemas.c: Charles Bozeman fixed some Schemas validation
problems
* result/schemas/elem* result/schemas/seq* test/schemas.elem*
test/schemas/seq*: added the test cases from Charles
Daniel
diff --git a/ChangeLog b/ChangeLog
index 1ad4edc..4b8a363 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sat Oct 26 15:27:00 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+ * parser.c: Christian Glahn found a problem with a recent
+ patch to xmlParseBalancedChunkMemoryRecover()
+ * xmlschemas.c: Charles Bozeman fixed some Schemas validation
+ problems
+ * result/schemas/elem* result/schemas/seq* test/schemas.elem*
+ test/schemas/seq*: added the test cases from Charles
+
Wed Oct 23 16:42:29 CEST 2002 Daniel Veillard <daniel@veillard.com>
* Makefile.am config.h.in libxml.spec.in doc/Makefile.am:
diff --git a/parser.c b/parser.c
index 75d2221..304dc67 100644
--- a/parser.c
+++ b/parser.c
@@ -9831,11 +9831,15 @@
ctxt->validate = 0;
ctxt->loadsubset = 0;
- content = doc->children;
- doc->children = NULL;
- xmlParseContent(ctxt);
- doc->children = content;
-
+ if ( doc != NULL ){
+ content = doc->children;
+ doc->children = NULL;
+ xmlParseContent(ctxt);
+ doc->children = content;
+ }
+ else {
+ xmlParseContent(ctxt);
+ }
if ((RAW == '<') && (NXT(1) == '/')) {
ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
diff --git a/result/schemas/elem0_0_0 b/result/schemas/elem0_0_0
new file mode 100644
index 0000000..0ab06b4
--- /dev/null
+++ b/result/schemas/elem0_0_0
@@ -0,0 +1 @@
+./test/schemas/elem0_0.xml validates
diff --git a/result/schemas/elem0_0_0.err b/result/schemas/elem0_0_0.err
new file mode 100644
index 0000000..8d518f4
--- /dev/null
+++ b/result/schemas/elem0_0_0.err
@@ -0,0 +1,5 @@
+Type of sequence 2 : ./test/schemas/elem0_0.xsd:11 :elements
+Type of anontype1 : ./test/schemas/elem0_0.xsd:10 :elements
+Type of sequence 2 : ./test/schemas/elem0_0.xsd:11 :elements
+Building content model for doc
+Element doc content check succeeded
diff --git a/result/schemas/seq0_0_0 b/result/schemas/seq0_0_0
new file mode 100644
index 0000000..d4c8431
--- /dev/null
+++ b/result/schemas/seq0_0_0
@@ -0,0 +1 @@
+./test/schemas/seq0_0.xml validates
diff --git a/result/schemas/seq0_0_0.err b/result/schemas/seq0_0_0.err
new file mode 100644
index 0000000..3ca2aff
--- /dev/null
+++ b/result/schemas/seq0_0_0.err
@@ -0,0 +1,88 @@
+Type of sequence 14 : ./test/schemas/seq0_0.xsd:55 :elements
+Type of anontype13 : ./test/schemas/seq0_0.xsd:54 :elements
+Type of sequence 12 : ./test/schemas/seq0_0.xsd:47 :elements
+Type of sequence 4 : ./test/schemas/seq0_0.xsd:15 :elements
+Type of anontype3 : ./test/schemas/seq0_0.xsd:14 :elements
+Type of sequence 8 : ./test/schemas/seq0_0.xsd:31 :elements
+Type of anontype7 : ./test/schemas/seq0_0.xsd:30 :elements
+Type of sequence 12 : ./test/schemas/seq0_0.xsd:47 :elements
+Type of anontype11 : ./test/schemas/seq0_0.xsd:46 :elements
+Type of sequence 10 : ./test/schemas/seq0_0.xsd:39 :elements
+Type of sequence 2 : ./test/schemas/seq0_0.xsd:11 :elements
+Type of anontype1 : ./test/schemas/seq0_0.xsd:10 :elements
+Type of sequence 6 : ./test/schemas/seq0_0.xsd:23 :elements
+Type of anontype5 : ./test/schemas/seq0_0.xsd:22 :elements
+Type of sequence 8 : ./test/schemas/seq0_0.xsd:31 :elements
+Type of sequence 4 : ./test/schemas/seq0_0.xsd:15 :elements
+Type of sequence 6 : ./test/schemas/seq0_0.xsd:23 :elements
+Type of sequence 10 : ./test/schemas/seq0_0.xsd:39 :elements
+Type of anontype9 : ./test/schemas/seq0_0.xsd:38 :elements
+Type of sequence 2 : ./test/schemas/seq0_0.xsd:11 :elements
+Type of sequence 14 : ./test/schemas/seq0_0.xsd:55 :elements
+Building content model for z-o
+Building content model for z-3
+Building content model for o-o
+Building content model for z-u
+Building content model for o-u
+Building content model for doc
+Building content model for o-3
+xmlSchemaValidateCallback: z-o, z-o, z-o
+xmlSchemaValidateCallback: b, b, b
+Element z-o content check succeeded
+xmlSchemaValidateCallback: o-o, o-o, o-o
+xmlSchemaValidateCallback: c, c, c
+Element o-o content check succeeded
+xmlSchemaValidateCallback: z-u, z-u, z-u
+xmlSchemaValidateCallback: d, d, d
+Element z-u content check succeeded
+xmlSchemaValidateCallback: o-u, o-u, o-u
+xmlSchemaValidateCallback: e, e, e
+Element o-u content check succeeded
+xmlSchemaValidateCallback: z-3, z-3, z-3
+xmlSchemaValidateCallback: f, f, f
+Element z-3 content check succeeded
+xmlSchemaValidateCallback: o-3, o-3, o-3
+xmlSchemaValidateCallback: g, g, g
+Element o-3 content check succeeded
+xmlSchemaValidateCallback: z-o, z-o, z-o
+xmlSchemaValidateCallback: b, b, b
+Element z-o content check succeeded
+xmlSchemaValidateCallback: o-o, o-o, o-o
+xmlSchemaValidateCallback: c, c, c
+Element o-o content check succeeded
+xmlSchemaValidateCallback: z-u, z-u, z-u
+xmlSchemaValidateCallback: d, d, d
+xmlSchemaValidateCallback: d, d, d
+xmlSchemaValidateCallback: d, d, d
+Element z-u content check succeeded
+xmlSchemaValidateCallback: o-u, o-u, o-u
+xmlSchemaValidateCallback: e, e, e
+xmlSchemaValidateCallback: e, e, e
+xmlSchemaValidateCallback: e, e, e
+Element o-u content check succeeded
+xmlSchemaValidateCallback: z-3, z-3, z-3
+xmlSchemaValidateCallback: f, f, f
+xmlSchemaValidateCallback: f, f, f
+xmlSchemaValidateCallback: f, f, f
+Element z-3 content check succeeded
+xmlSchemaValidateCallback: o-3, o-3, o-3
+xmlSchemaValidateCallback: g, g, g
+xmlSchemaValidateCallback: g, g, g
+xmlSchemaValidateCallback: g, g, g
+Element o-3 content check succeeded
+xmlSchemaValidateCallback: z-o, z-o, z-o
+Element z-o content check succeeded
+xmlSchemaValidateCallback: o-o, o-o, o-o
+xmlSchemaValidateCallback: c, c, c
+Element o-o content check succeeded
+xmlSchemaValidateCallback: z-u, z-u, z-u
+Element z-u content check succeeded
+xmlSchemaValidateCallback: o-u, o-u, o-u
+xmlSchemaValidateCallback: e, e, e
+Element o-u content check succeeded
+xmlSchemaValidateCallback: z-3, z-3, z-3
+Element z-3 content check succeeded
+xmlSchemaValidateCallback: o-3, o-3, o-3
+xmlSchemaValidateCallback: g, g, g
+Element o-3 content check succeeded
+Element doc content check succeeded
diff --git a/test/schemas/elem0_0.xml b/test/schemas/elem0_0.xml
new file mode 100644
index 0000000..f741c58
--- /dev/null
+++ b/test/schemas/elem0_0.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<doc/>
+
diff --git a/test/schemas/elem0_0.xsd b/test/schemas/elem0_0.xsd
new file mode 100644
index 0000000..2c5bf5f
--- /dev/null
+++ b/test/schemas/elem0_0.xsd
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:annotation>
+ <xsd:documentation>
+ Testing min and max occurance attributes on element
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:element name="doc">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name='a' minOccurs='0' maxOccurs='3'/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+</xsd:schema>
diff --git a/test/schemas/seq0_0.xml b/test/schemas/seq0_0.xml
new file mode 100644
index 0000000..54b1c1c
--- /dev/null
+++ b/test/schemas/seq0_0.xml
@@ -0,0 +1,61 @@
+<doc>
+ <!-- at least one present -->
+ <z-o>
+ <b/>
+ </z-o>
+ <o-o>
+ <c/>
+ </o-o>
+ <z-u>
+ <d/>
+ </z-u>
+ <o-u>
+ <e/>
+ </o-u>
+ <z-3>
+ <f/>
+ </z-3>
+ <o-3>
+ <g/>
+ </o-3>
+ <!-- more than one present when allowed -->
+ <z-o>
+ <b/>
+ </z-o>
+ <o-o>
+ <c/>
+ </o-o>
+ <z-u>
+ <d/>
+ <d/>
+ <d/>
+ </z-u>
+ <o-u>
+ <e/>
+ <e/>
+ <e/>
+ </o-u>
+ <z-3>
+ <f/>
+ <f/>
+ <f/>
+ </z-3>
+ <o-3>
+ <g/>
+ <g/>
+ <g/>
+ </o-3>
+ <!-- min 0 are not present -->
+ <z-o/>
+ <o-o>
+ <c/>
+ </o-o>
+ <z-u/>
+ <o-u>
+ <e/>
+ </o-u>
+ <z-3/>
+ <o-3>
+ <g/>
+ </o-3>
+</doc>
diff --git a/test/schemas/seq0_0.xsd b/test/schemas/seq0_0.xsd
new file mode 100644
index 0000000..34d3a78
--- /dev/null
+++ b/test/schemas/seq0_0.xsd
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:annotation>
+ <xsd:documentation>
+ Testing min and max occurance attributes on sequences
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:element name="doc">
+ <xsd:complexType>
+ <xsd:sequence minOccurs='0' maxOccurs='unbounded'>
+
+ <xsd:element name="z-o">
+ <xsd:complexType>
+ <xsd:sequence minOccurs='0' maxOccurs='1'>
+ <xsd:element name='b'/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="o-o">
+ <xsd:complexType>
+ <xsd:sequence minOccurs='1' maxOccurs='1'>
+ <xsd:element name='c'/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="z-u">
+ <xsd:complexType>
+ <xsd:sequence minOccurs='0' maxOccurs='unbounded'>
+ <xsd:element name='d'/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="o-u">
+ <xsd:complexType>
+ <xsd:sequence minOccurs='1' maxOccurs='unbounded'>
+ <xsd:element name='e'/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="z-3">
+ <xsd:complexType>
+ <xsd:sequence minOccurs='0' maxOccurs='3'>
+ <xsd:element name='f'/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="o-3">
+ <xsd:complexType>
+ <xsd:sequence minOccurs='1' maxOccurs='3'>
+ <xsd:element name='g'/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+</xsd:schema>
diff --git a/xmlschemas.c b/xmlschemas.c
index 721f326..773fe6e 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -3165,6 +3165,10 @@
counter);
ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
NULL, counter);
+ if (elem->minOccurs == 0) {
+ /* basically an elem? */
+ xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+ }
} else {
if (elem->refDecl != NULL) {
@@ -3186,12 +3190,87 @@
xmlSchemaTypePtr subtypes;
/*
- * Simply iterate over the subtypes
+ * If max and min occurances are default (1) then
+ * simply iterate over the subtypes
*/
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- subtypes = subtypes->next;
+ if ((type->minOccurs == 1 ) && (type->maxOccurs == 1)) {
+ subtypes = type->subtypes;
+ while (subtypes != NULL) {
+ xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+ subtypes = subtypes->next;
+ }
+ } else {
+ xmlAutomataStatePtr oldstate = ctxt->state;
+ if (type->maxOccurs >= UNBOUNDED) {
+ if (type->minOccurs > 1) {
+ xmlAutomataStatePtr tmp;
+ int counter;
+
+ ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
+ oldstate, NULL);
+ oldstate = ctxt->state;
+
+ counter = xmlAutomataNewCounter(ctxt->am,
+ type->minOccurs - 1, UNBOUNDED);
+
+ subtypes = type->subtypes;
+ while (subtypes != NULL) {
+ xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+ subtypes = subtypes->next;
+ }
+ tmp = ctxt->state;
+ xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
+ counter);
+ ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
+ NULL, counter);
+
+ } else {
+ subtypes = type->subtypes;
+ while (subtypes != NULL) {
+ xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+ subtypes = subtypes->next;
+ }
+ xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
+ if (type->minOccurs == 0) {
+ xmlAutomataNewEpsilon(ctxt->am, oldstate,
+ ctxt->state);
+ }
+ }
+ } else if ((type->maxOccurs > 1) || (type->minOccurs > 1)) {
+ xmlAutomataStatePtr tmp;
+ int counter;
+
+ ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
+ oldstate, NULL);
+ oldstate = ctxt->state;
+
+ counter = xmlAutomataNewCounter(ctxt->am,
+ type->minOccurs - 1, type->maxOccurs - 1);
+
+ subtypes = type->subtypes;
+ while (subtypes != NULL) {
+ xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+ subtypes = subtypes->next;
+ }
+ tmp = ctxt->state;
+ xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
+ counter);
+ ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
+ NULL, counter);
+ if (type->minOccurs == 0) {
+ xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+ }
+
+ } else {
+ subtypes = type->subtypes;
+ while (subtypes != NULL) {
+ xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+ subtypes = subtypes->next;
+ }
+ if (type->minOccurs == 0) {
+ xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+ }
+ }
}
break;
}
@@ -3217,18 +3296,15 @@
} else {
int counter;
xmlAutomataStatePtr hop;
+ int maxOccurs = type->maxOccurs == UNBOUNDED ?
+ UNBOUNDED : type->maxOccurs - 1;
+ int minOccurs = type->minOccurs < 1 ? 0 : type->minOccurs - 1;
/*
* use a counter to keep track of the number of transtions
* which went through the choice.
*/
- if (type->minOccurs < 1) {
- counter = xmlAutomataNewCounter(ctxt->am, 0,
- type->maxOccurs - 1);
- } else {
- counter = xmlAutomataNewCounter(ctxt->am,
- type->minOccurs - 1, type->maxOccurs - 1);
- }
+ counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
hop = xmlAutomataNewState(ctxt->am);
subtypes = type->subtypes;