[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
[xml] occurrences on elements & sequences
- From: Charles Bozeman <cbozeman hiwaay net>
- To: xml gnome org
- Subject: [xml] occurrences on elements & sequences
- Date: 26 Oct 2002 08:56:44 -0600
I've come across a couple of bugs in schema handling, specifically
dealing with min & max occurrences on elements and sequences.
If an element has a minOccur='0' and maxOccur > 1 and the element is not
present in the xml file being validated, then the validation fails. See
attached elem.* files for test case. Also minOccur and maxOccur on
sequence are not handled at all.
I (hopefully) fixed the problems in xmlSchemaBuildAContentModel with the
attached patch, but I don't really understand the automata routines so
the patch needs checking. The patch also adds a check for unbounded case
when building a model for choice types.
Charlie B.
<?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>
<?xml version="1.0"?>
<doc/>
<?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>
<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>
Index: xmlschemas.c
===================================================================
RCS file: /cvs/gnome/libxml2/xmlschemas.c,v
retrieving revision 1.20
diff -c -r1.20 xmlschemas.c
*** xmlschemas.c 16 Oct 2002 14:08:12 -0000 1.20
--- xmlschemas.c 26 Oct 2002 13:34:18 -0000
***************
*** 3165,3170 ****
--- 3165,3174 ----
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,3197 ****
xmlSchemaTypePtr subtypes;
/*
! * Simply iterate over the subtypes
*/
! subtypes = type->subtypes;
! while (subtypes != NULL) {
! xmlSchemaBuildAContentModel(subtypes, ctxt, name);
! subtypes = subtypes->next;
}
break;
}
--- 3190,3276 ----
xmlSchemaTypePtr subtypes;
/*
! * If max and min occurances are default (1) then
! * simply iterate over the subtypes
*/
! 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,3234 ****
} else {
int counter;
xmlAutomataStatePtr hop;
/*
* 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);
! }
hop = xmlAutomataNewState(ctxt->am);
subtypes = type->subtypes;
--- 3296,3310 ----
} 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.
*/
! counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
hop = xmlAutomataNewState(ctxt->am);
subtypes = type->subtypes;
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]