2 * schemas.c : implementation of the XML Schema handling and
3 * schema validity checking
5 * See Copyright for the status of this software.
7 * Daniel Veillard <veillard@redhat.com>
13 #ifdef LIBXML_SCHEMAS_ENABLED
16 #include <libxml/xmlmemory.h>
17 #include <libxml/parser.h>
18 #include <libxml/parserInternals.h>
19 #include <libxml/hash.h>
20 #include <libxml/uri.h>
22 #include <libxml/xmlschemas.h>
23 #include <libxml/schemasInternals.h>
24 #include <libxml/xmlschemastypes.h>
25 #include <libxml/xmlautomata.h>
26 #include <libxml/xmlregexp.h>
28 #define DEBUG 1 /* very verbose output */
29 #define DEBUG_CONTENT 1
31 /* #define DEBUG_CONTENT_REGEXP 1 */
32 /* #define DEBUG_AUTOMATA 1 */
34 #define UNBOUNDED (1 << 30)
36 xmlGenericError(xmlGenericErrorContext, \
37 "Unimplemented block at %s:%d\n", \
40 #define XML_SCHEMAS_DEFAULT_NAMESPACE (const xmlChar *)"the default namespace"
43 * The XML Schemas namespaces
45 static const xmlChar
*xmlSchemaNs
= (const xmlChar
*)
46 "http://www.w3.org/2001/XMLSchema";
48 static const xmlChar
*xmlSchemaInstanceNs
= (const xmlChar
*)
49 "http://www.w3.org/2001/XMLSchema-instance";
51 #define IS_SCHEMA(node, type) \
52 ((node != NULL) && (node->ns != NULL) && \
53 (xmlStrEqual(node->name, (const xmlChar *) type)) && \
54 (xmlStrEqual(node->ns->href, xmlSchemaNs)))
56 #define XML_SCHEMAS_PARSE_ERROR 1
58 struct _xmlSchemaParserCtxt
{
59 void *userData
; /* user specific data block */
60 xmlSchemaValidityErrorFunc error
; /* the callback in case of errors */
61 xmlSchemaValidityWarningFunc warning
;/* the callback in case of warning */
62 xmlSchemaValidError err
;
64 xmlSchemaPtr schema
; /* The schema in use */
65 xmlChar
*container
; /* the current element, group, ... */
75 * Used to build complex element content models
78 xmlAutomataStatePtr start
;
79 xmlAutomataStatePtr end
;
80 xmlAutomataStatePtr state
;
84 #define XML_SCHEMAS_ATTR_UNKNOWN 1
85 #define XML_SCHEMAS_ATTR_CHECKED 2
87 typedef struct _xmlSchemaAttrState xmlSchemaAttrState
;
88 typedef xmlSchemaAttrState
*xmlSchemaAttrStatePtr
;
89 struct _xmlSchemaAttrState
{
97 * A Schemas validation context
100 struct _xmlSchemaValidCtxt
{
101 void *userData
; /* user specific data block */
102 xmlSchemaValidityErrorFunc error
; /* the callback in case of errors */
103 xmlSchemaValidityWarningFunc warning
;/* the callback in case of warning */
105 xmlSchemaPtr schema
; /* The schema in use */
107 xmlParserInputBufferPtr input
;
109 xmlSAXHandlerPtr sax
;
116 xmlSchemaTypePtr type
;
118 xmlRegExecCtxtPtr regexp
;
119 xmlSchemaValPtr value
;
124 xmlSchemaAttrStatePtr attr
;
128 /************************************************************************
130 * Some predeclarations *
132 ************************************************************************/
133 static int xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt
,
134 xmlSchemaTypePtr type
,
137 /************************************************************************
139 * Allocation functions *
141 ************************************************************************/
144 * xmlSchemaNewSchema:
145 * @ctxt: a schema validation context (optional)
147 * Allocate a new Schema structure.
149 * Returns the newly allocated structure or NULL in case or error
152 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt
)
156 ret
= (xmlSchemaPtr
) xmlMalloc(sizeof(xmlSchema
));
158 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
159 ctxt
->error(ctxt
->userData
, "Out of memory\n");
162 memset(ret
, 0, sizeof(xmlSchema
));
169 * @ctxt: a schema validation context (optional)
171 * Allocate a new Facet structure.
173 * Returns the newly allocated structure or NULL in case or error
175 static xmlSchemaFacetPtr
176 xmlSchemaNewFacet(xmlSchemaParserCtxtPtr ctxt
)
178 xmlSchemaFacetPtr ret
;
180 ret
= (xmlSchemaFacetPtr
) xmlMalloc(sizeof(xmlSchemaFacet
));
182 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
183 ctxt
->error(ctxt
->userData
, "Out of memory\n");
186 memset(ret
, 0, sizeof(xmlSchemaFacet
));
193 * @ctxt: a schema validation context (optional)
196 * Allocate a new annotation structure.
198 * Returns the newly allocated structure or NULL in case or error
200 static xmlSchemaAnnotPtr
201 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
)
203 xmlSchemaAnnotPtr ret
;
205 ret
= (xmlSchemaAnnotPtr
) xmlMalloc(sizeof(xmlSchemaAnnot
));
207 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
208 ctxt
->error(ctxt
->userData
, "Out of memory\n");
211 memset(ret
, 0, sizeof(xmlSchemaAnnot
));
217 * xmlSchemaFreeAnnot:
218 * @annot: a schema type structure
220 * Deallocate a annotation structure
223 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot
)
231 * xmlSchemaFreeNotation:
232 * @schema: a schema notation structure
234 * Deallocate a Schema Notation structure.
237 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota
)
241 if (nota
->name
!= NULL
)
242 xmlFree((xmlChar
*) nota
->name
);
247 * xmlSchemaFreeAttribute:
248 * @schema: a schema attribute structure
250 * Deallocate a Schema Attribute structure.
253 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr
)
257 if (attr
->name
!= NULL
)
258 xmlFree((xmlChar
*) attr
->name
);
259 if (attr
->ref
!= NULL
)
260 xmlFree((xmlChar
*) attr
->ref
);
261 if (attr
->refNs
!= NULL
)
262 xmlFree((xmlChar
*) attr
->refNs
);
263 if (attr
->typeName
!= NULL
)
264 xmlFree((xmlChar
*) attr
->typeName
);
265 if (attr
->typeNs
!= NULL
)
266 xmlFree((xmlChar
*) attr
->typeNs
);
271 * xmlSchemaFreeAttributeGroup:
272 * @schema: a schema attribute group structure
274 * Deallocate a Schema Attribute Group structure.
277 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attr
)
281 if (attr
->name
!= NULL
)
282 xmlFree((xmlChar
*) attr
->name
);
287 * xmlSchemaFreeElement:
288 * @schema: a schema element structure
290 * Deallocate a Schema Element structure.
293 xmlSchemaFreeElement(xmlSchemaElementPtr elem
)
297 if (elem
->name
!= NULL
)
298 xmlFree((xmlChar
*) elem
->name
);
299 if (elem
->namedType
!= NULL
)
300 xmlFree((xmlChar
*) elem
->namedType
);
301 if (elem
->namedTypeNs
!= NULL
)
302 xmlFree((xmlChar
*) elem
->namedTypeNs
);
303 if (elem
->ref
!= NULL
)
304 xmlFree((xmlChar
*) elem
->ref
);
305 if (elem
->refNs
!= NULL
)
306 xmlFree((xmlChar
*) elem
->refNs
);
307 if (elem
->annot
!= NULL
)
308 xmlSchemaFreeAnnot(elem
->annot
);
309 if (elem
->contModel
!= NULL
)
310 xmlRegFreeRegexp(elem
->contModel
);
315 * xmlSchemaFreeFacet:
316 * @facet: a schema facet structure
318 * Deallocate a Schema Facet structure.
321 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet
)
325 if (facet
->value
!= NULL
)
326 xmlFree((xmlChar
*) facet
->value
);
327 if (facet
->id
!= NULL
)
328 xmlFree((xmlChar
*) facet
->id
);
329 if (facet
->val
!= NULL
)
330 xmlSchemaFreeValue(facet
->val
);
331 if (facet
->regexp
!= NULL
)
332 xmlRegFreeRegexp(facet
->regexp
);
333 if (facet
->annot
!= NULL
)
334 xmlSchemaFreeAnnot(facet
->annot
);
340 * @type: a schema type structure
342 * Deallocate a Schema Type structure.
345 xmlSchemaFreeType(xmlSchemaTypePtr type
)
349 if (type
->name
!= NULL
)
350 xmlFree((xmlChar
*) type
->name
);
351 if (type
->base
!= NULL
)
352 xmlFree((xmlChar
*) type
->base
);
353 if (type
->baseNs
!= NULL
)
354 xmlFree((xmlChar
*) type
->baseNs
);
355 if (type
->annot
!= NULL
)
356 xmlSchemaFreeAnnot(type
->annot
);
357 if (type
->facets
!= NULL
) {
358 xmlSchemaFacetPtr facet
, next
;
360 facet
= type
->facets
;
361 while (facet
!= NULL
) {
363 xmlSchemaFreeFacet(facet
);
372 * @schema: a schema structure
374 * Deallocate a Schema structure.
377 xmlSchemaFree(xmlSchemaPtr schema
)
382 if (schema
->name
!= NULL
)
383 xmlFree((xmlChar
*) schema
->name
);
384 if (schema
->notaDecl
!= NULL
)
385 xmlHashFree(schema
->notaDecl
,
386 (xmlHashDeallocator
) xmlSchemaFreeNotation
);
387 if (schema
->attrDecl
!= NULL
)
388 xmlHashFree(schema
->attrDecl
,
389 (xmlHashDeallocator
) xmlSchemaFreeAttribute
);
390 if (schema
->attrgrpDecl
!= NULL
)
391 xmlHashFree(schema
->attrgrpDecl
,
392 (xmlHashDeallocator
) xmlSchemaFreeAttributeGroup
);
393 if (schema
->elemDecl
!= NULL
)
394 xmlHashFree(schema
->elemDecl
,
395 (xmlHashDeallocator
) xmlSchemaFreeElement
);
396 if (schema
->typeDecl
!= NULL
)
397 xmlHashFree(schema
->typeDecl
,
398 (xmlHashDeallocator
) xmlSchemaFreeType
);
399 if (schema
->annot
!= NULL
)
400 xmlSchemaFreeAnnot(schema
->annot
);
401 if (schema
->doc
!= NULL
)
402 xmlFreeDoc(schema
->doc
);
407 /************************************************************************
411 ************************************************************************/
414 * xmlSchemaErrorContext:
415 * @ctxt: the parsing context
416 * @schema: the schema being built
417 * @node: the node being processed
418 * @child: the child being processed
420 * Dump a SchemaType structure
423 xmlSchemaErrorContext(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
424 xmlNodePtr node
, xmlNodePtr child
)
427 const xmlChar
*file
= NULL
;
428 const xmlChar
*name
= NULL
;
429 const char *type
= "error";
431 if ((ctxt
== NULL
) || (ctxt
->error
== NULL
))
438 if ((node
->type
== XML_DOCUMENT_NODE
) ||
439 (node
->type
== XML_HTML_DOCUMENT_NODE
)) {
440 xmlDocPtr doc
= (xmlDocPtr
) node
;
445 * Try to find contextual informations to report
447 if (node
->type
== XML_ELEMENT_NODE
) {
448 line
= (int) node
->content
;
449 } else if ((node
->prev
!= NULL
) &&
450 (node
->prev
->type
== XML_ELEMENT_NODE
)) {
451 line
= (int) node
->prev
->content
;
452 } else if ((node
->parent
!= NULL
) &&
453 (node
->parent
->type
== XML_ELEMENT_NODE
)) {
454 line
= (int) node
->parent
->content
;
456 if ((node
->doc
!= NULL
) && (node
->doc
->URL
!= NULL
))
457 file
= node
->doc
->URL
;
458 if (node
->name
!= NULL
)
464 type
= "compilation error";
465 else if (schema
!= NULL
)
466 type
= "runtime error";
468 if ((file
!= NULL
) && (line
!= 0) && (name
!= NULL
))
469 ctxt
->error(ctxt
->userData
, "%s: file %s line %d element %s\n",
470 type
, file
, line
, name
);
471 else if ((file
!= NULL
) && (name
!= NULL
))
472 ctxt
->error(ctxt
->userData
, "%s: file %s element %s\n",
474 else if ((file
!= NULL
) && (line
!= 0))
475 ctxt
->error(ctxt
->userData
, "%s: file %s line %d\n", type
, file
, line
);
476 else if (file
!= NULL
)
477 ctxt
->error(ctxt
->userData
, "%s: file %s\n", type
, file
);
478 else if (name
!= NULL
)
479 ctxt
->error(ctxt
->userData
, "%s: element %s\n", type
, name
);
481 ctxt
->error(ctxt
->userData
, "%s\n", type
);
484 /************************************************************************
488 ************************************************************************/
491 * xmlSchemaElementDump:
493 * @output: the file output
498 xmlSchemaElementDump(xmlSchemaElementPtr elem
, FILE * output
,
499 const xmlChar
*name ATTRIBUTE_UNUSED
,
500 const xmlChar
*context ATTRIBUTE_UNUSED
,
501 const xmlChar
*namespace ATTRIBUTE_UNUSED
)
506 fprintf(output
, "Element ");
507 if (elem
->flags
& XML_SCHEMAS_ELEM_TOPLEVEL
)
508 fprintf(output
, "toplevel ");
509 fprintf(output
, ": %s ", elem
->name
);
510 if (namespace != NULL
)
511 fprintf(output
, "namespace '%s' ", namespace);
513 if (elem
->flags
& XML_SCHEMAS_ELEM_NILLABLE
)
514 fprintf(output
, "nillable ");
515 if (elem
->flags
& XML_SCHEMAS_ELEM_GLOBAL
)
516 fprintf(output
, "global ");
517 if (elem
->flags
& XML_SCHEMAS_ELEM_DEFAULT
)
518 fprintf(output
, "default ");
519 if (elem
->flags
& XML_SCHEMAS_ELEM_FIXED
)
520 fprintf(output
, "fixed ");
521 if (elem
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
)
522 fprintf(output
, "abstract ");
523 if (elem
->flags
& XML_SCHEMAS_ELEM_REF
)
524 fprintf(output
, "ref '%s' ", elem
->ref
);
525 if (elem
->id
!= NULL
)
526 fprintf(output
, "id '%s' ", elem
->id
);
527 fprintf(output
, "\n");
528 if ((elem
->minOccurs
!= 1) || (elem
->maxOccurs
!= 1)) {
529 fprintf(output
, " ");
530 if (elem
->minOccurs
!= 1)
531 fprintf(output
, "min: %d ", elem
->minOccurs
);
532 if (elem
->maxOccurs
>= UNBOUNDED
)
533 fprintf(output
, "max: unbounded\n");
534 else if (elem
->maxOccurs
!= 1)
535 fprintf(output
, "max: %d\n", elem
->maxOccurs
);
537 fprintf(output
, "\n");
539 if (elem
->namedType
!= NULL
) {
540 fprintf(output
, " type: %s", elem
->namedType
);
541 if (elem
->namedTypeNs
!= NULL
)
542 fprintf(output
, " ns %s\n", elem
->namedTypeNs
);
544 fprintf(output
, "\n");
546 if (elem
->substGroup
!= NULL
) {
547 fprintf(output
, " substitutionGroup: %s", elem
->substGroup
);
548 if (elem
->substGroupNs
!= NULL
)
549 fprintf(output
, " ns %s\n", elem
->substGroupNs
);
551 fprintf(output
, "\n");
553 if (elem
->value
!= NULL
)
554 fprintf(output
, " default: %s", elem
->value
);
558 * xmlSchemaAnnotDump:
559 * @output: the file output
560 * @annot: a annotation
562 * Dump the annotation
565 xmlSchemaAnnotDump(FILE * output
, xmlSchemaAnnotPtr annot
)
572 content
= xmlNodeGetContent(annot
->content
);
573 if (content
!= NULL
) {
574 fprintf(output
, " Annot: %s\n", content
);
577 fprintf(output
, " Annot: empty\n");
582 * @output: the file output
583 * @type: a type structure
585 * Dump a SchemaType structure
588 xmlSchemaTypeDump(xmlSchemaTypePtr type
, FILE * output
)
591 fprintf(output
, "Type: NULL\n");
594 fprintf(output
, "Type: ");
595 if (type
->name
!= NULL
)
596 fprintf(output
, "%s, ", type
->name
);
598 fprintf(output
, "no name");
599 switch (type
->type
) {
600 case XML_SCHEMA_TYPE_BASIC
:
601 fprintf(output
, "basic ");
603 case XML_SCHEMA_TYPE_SIMPLE
:
604 fprintf(output
, "simple ");
606 case XML_SCHEMA_TYPE_COMPLEX
:
607 fprintf(output
, "complex ");
609 case XML_SCHEMA_TYPE_SEQUENCE
:
610 fprintf(output
, "sequence ");
612 case XML_SCHEMA_TYPE_CHOICE
:
613 fprintf(output
, "choice ");
615 case XML_SCHEMA_TYPE_ALL
:
616 fprintf(output
, "all ");
618 case XML_SCHEMA_TYPE_UR
:
619 fprintf(output
, "ur ");
621 case XML_SCHEMA_TYPE_RESTRICTION
:
622 fprintf(output
, "restriction ");
624 case XML_SCHEMA_TYPE_EXTENSION
:
625 fprintf(output
, "extension ");
628 fprintf(output
, "unknowntype%d ", type
->type
);
631 if (type
->base
!= NULL
) {
632 fprintf(output
, "base %s, ", type
->base
);
634 switch (type
->contentType
) {
635 case XML_SCHEMA_CONTENT_UNKNOWN
:
636 fprintf(output
, "unknown ");
638 case XML_SCHEMA_CONTENT_EMPTY
:
639 fprintf(output
, "empty ");
641 case XML_SCHEMA_CONTENT_ELEMENTS
:
642 fprintf(output
, "element ");
644 case XML_SCHEMA_CONTENT_MIXED
:
645 fprintf(output
, "mixed ");
647 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS
:
648 fprintf(output
, "mixed_or_elems ");
650 case XML_SCHEMA_CONTENT_BASIC
:
651 fprintf(output
, "basic ");
653 case XML_SCHEMA_CONTENT_SIMPLE
:
654 fprintf(output
, "simple ");
656 case XML_SCHEMA_CONTENT_ANY
:
657 fprintf(output
, "any ");
660 fprintf(output
, "\n");
661 if ((type
->minOccurs
!= 1) || (type
->maxOccurs
!= 1)) {
662 fprintf(output
, " ");
663 if (type
->minOccurs
!= 1)
664 fprintf(output
, "min: %d ", type
->minOccurs
);
665 if (type
->maxOccurs
>= UNBOUNDED
)
666 fprintf(output
, "max: unbounded\n");
667 else if (type
->maxOccurs
!= 1)
668 fprintf(output
, "max: %d\n", type
->maxOccurs
);
670 fprintf(output
, "\n");
672 if (type
->annot
!= NULL
)
673 xmlSchemaAnnotDump(output
, type
->annot
);
674 if (type
->subtypes
!= NULL
) {
675 xmlSchemaTypePtr sub
= type
->subtypes
;
677 fprintf(output
, " subtypes: ");
678 while (sub
!= NULL
) {
679 fprintf(output
, "%s ", sub
->name
);
682 fprintf(output
, "\n");
689 * @output: the file output
690 * @schema: a schema structure
692 * Dump a Schema structure.
695 xmlSchemaDump(FILE * output
, xmlSchemaPtr schema
)
697 if (schema
== NULL
) {
698 fprintf(output
, "Schemas: NULL\n");
701 fprintf(output
, "Schemas: ");
702 if (schema
->name
!= NULL
)
703 fprintf(output
, "%s, ", schema
->name
);
705 fprintf(output
, "no name, ");
706 if (schema
->targetNamespace
!= NULL
)
707 fprintf(output
, "%s", schema
->targetNamespace
);
709 fprintf(output
, "no target namespace");
710 fprintf(output
, "\n");
711 if (schema
->annot
!= NULL
)
712 xmlSchemaAnnotDump(output
, schema
->annot
);
714 xmlHashScan(schema
->typeDecl
, (xmlHashScanner
) xmlSchemaTypeDump
,
716 xmlHashScanFull(schema
->elemDecl
,
717 (xmlHashScannerFull
) xmlSchemaElementDump
, output
);
720 /************************************************************************
722 * Parsing functions *
724 ************************************************************************/
728 * @schema: the schemas context
729 * @name: the type name
730 * @ns: the type namespace
732 * Lookup a type in the schemas or the predefined types
734 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
736 static xmlSchemaTypePtr
737 xmlSchemaGetType(xmlSchemaPtr schema
, const xmlChar
* name
,
738 const xmlChar
* namespace) {
739 xmlSchemaTypePtr ret
;
743 if (schema
!= NULL
) {
744 ret
= xmlHashLookup2(schema
->typeDecl
, name
, namespace);
748 ret
= xmlSchemaGetPredefinedType(name
, namespace);
751 if (namespace == NULL
)
752 fprintf(stderr
, "Unable to lookup type %s", name
);
754 fprintf(stderr
, "Unable to lookup type %s:%s", name
, namespace);
760 /************************************************************************
762 * Parsing functions *
764 ************************************************************************/
766 #define IS_BLANK_NODE(n) \
767 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content)))
773 * Check if a string is ignorable
775 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
778 xmlSchemaIsBlank(xmlChar
*str
) {
782 if (!(IS_BLANK(*str
))) return(0);
789 * xmlSchemaAddNotation:
790 * @ctxt: a schema validation context
791 * @schema: the schema being built
792 * @name: the item name
794 * Add an XML schema Attrribute declaration
795 * *WARNING* this interface is highly subject to change
797 * Returns the new struture or NULL in case of error
799 static xmlSchemaNotationPtr
800 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
801 const xmlChar
* name
)
803 xmlSchemaNotationPtr ret
= NULL
;
806 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
809 if (schema
->notaDecl
== NULL
)
810 schema
->notaDecl
= xmlHashCreate(10);
811 if (schema
->notaDecl
== NULL
)
814 ret
= (xmlSchemaNotationPtr
) xmlMalloc(sizeof(xmlSchemaNotation
));
816 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
817 ctxt
->error(ctxt
->userData
, "Out of memory\n");
820 memset(ret
, 0, sizeof(xmlSchemaNotation
));
821 ret
->name
= xmlStrdup(name
);
822 val
= xmlHashAddEntry2(schema
->notaDecl
, name
, schema
->targetNamespace
,
825 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
826 ctxt
->error(ctxt
->userData
, "Could not add notation %s\n",
828 xmlFree((char *) ret
->name
);
837 * xmlSchemaAddAttribute:
838 * @ctxt: a schema validation context
839 * @schema: the schema being built
840 * @name: the item name
841 * @container: the container's name
843 * Add an XML schema Attrribute declaration
844 * *WARNING* this interface is highly subject to change
846 * Returns the new struture or NULL in case of error
848 static xmlSchemaAttributePtr
849 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
850 const xmlChar
* name
)
852 xmlSchemaAttributePtr ret
= NULL
;
855 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
858 if (schema
->attrDecl
== NULL
)
859 schema
->attrDecl
= xmlHashCreate(10);
860 if (schema
->attrDecl
== NULL
)
863 ret
= (xmlSchemaAttributePtr
) xmlMalloc(sizeof(xmlSchemaAttribute
));
865 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
866 ctxt
->error(ctxt
->userData
, "Out of memory\n");
869 memset(ret
, 0, sizeof(xmlSchemaAttribute
));
870 ret
->name
= xmlStrdup(name
);
871 val
= xmlHashAddEntry3(schema
->attrDecl
, name
,
872 schema
->targetNamespace
, ctxt
->container
, ret
);
874 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
875 ctxt
->error(ctxt
->userData
, "Could not add attribute %s\n",
877 xmlFree((char *) ret
->name
);
885 * xmlSchemaAddAttributeGroup:
886 * @ctxt: a schema validation context
887 * @schema: the schema being built
888 * @name: the item name
890 * Add an XML schema Attrribute Group declaration
892 * Returns the new struture or NULL in case of error
894 static xmlSchemaAttributeGroupPtr
895 xmlSchemaAddAttributeGroup(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
896 const xmlChar
* name
)
898 xmlSchemaAttributeGroupPtr ret
= NULL
;
901 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
904 if (schema
->attrgrpDecl
== NULL
)
905 schema
->attrgrpDecl
= xmlHashCreate(10);
906 if (schema
->attrgrpDecl
== NULL
)
909 ret
= (xmlSchemaAttributeGroupPtr
) xmlMalloc(sizeof(xmlSchemaAttributeGroup
));
911 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
912 ctxt
->error(ctxt
->userData
, "Out of memory\n");
915 memset(ret
, 0, sizeof(xmlSchemaAttributeGroup
));
916 ret
->name
= xmlStrdup(name
);
917 val
= xmlHashAddEntry3(schema
->attrgrpDecl
, name
,
918 schema
->targetNamespace
, ctxt
->container
, ret
);
920 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
921 ctxt
->error(ctxt
->userData
, "Could not add attribute group %s\n",
923 xmlFree((char *) ret
->name
);
931 * xmlSchemaAddElement:
932 * @ctxt: a schema validation context
933 * @schema: the schema being built
934 * @name: the type name
935 * @namespace: the type namespace
937 * Add an XML schema Element declaration
938 * *WARNING* this interface is highly subject to change
940 * Returns the new struture or NULL in case of error
942 static xmlSchemaElementPtr
943 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
944 const xmlChar
* name
, const xmlChar
* namespace)
946 xmlSchemaElementPtr ret
= NULL
;
949 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
952 if (schema
->elemDecl
== NULL
)
953 schema
->elemDecl
= xmlHashCreate(10);
954 if (schema
->elemDecl
== NULL
)
957 ret
= (xmlSchemaElementPtr
) xmlMalloc(sizeof(xmlSchemaElement
));
959 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
960 ctxt
->error(ctxt
->userData
, "Out of memory\n");
963 memset(ret
, 0, sizeof(xmlSchemaElement
));
964 ret
->name
= xmlStrdup(name
);
965 val
= xmlHashAddEntry3(schema
->elemDecl
, name
,
966 namespace, ctxt
->container
, ret
);
970 snprintf(buf
, 99, "privatieelem%d", ctxt
->counter
++ + 1);
971 val
= xmlHashAddEntry3(schema
->elemDecl
, name
, (xmlChar
*) buf
,
974 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
975 ctxt
->error(ctxt
->userData
, "Could not add element %s\n",
977 xmlFree((char *) ret
->name
);
987 * @ctxt: a schema validation context
988 * @schema: the schema being built
989 * @name: the item name
991 * Add an XML schema Simple Type definition
992 * *WARNING* this interface is highly subject to change
994 * Returns the new struture or NULL in case of error
996 static xmlSchemaTypePtr
997 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
998 const xmlChar
* name
)
1000 xmlSchemaTypePtr ret
= NULL
;
1003 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
1006 if (schema
->typeDecl
== NULL
)
1007 schema
->typeDecl
= xmlHashCreate(10);
1008 if (schema
->typeDecl
== NULL
)
1011 ret
= (xmlSchemaTypePtr
) xmlMalloc(sizeof(xmlSchemaType
));
1013 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1014 ctxt
->error(ctxt
->userData
, "Out of memory\n");
1017 memset(ret
, 0, sizeof(xmlSchemaType
));
1018 ret
->name
= xmlStrdup(name
);
1019 val
= xmlHashAddEntry2(schema
->typeDecl
, name
, schema
->targetNamespace
,
1022 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1023 ctxt
->error(ctxt
->userData
, "Could not add type %s\n", name
);
1024 xmlFree((char *) ret
->name
);
1034 /************************************************************************
1036 * Utilities for parsing *
1038 ************************************************************************/
1042 * @ctxt: a schema validation context
1043 * @node: a subtree containing XML Schema informations
1044 * @name: the attribute name
1045 * @namespace: the result namespace if any
1047 * Extract a QName Attribute value
1049 * Returns the NCName or NULL if not found, and also update @namespace
1050 * with the namespace URI
1053 xmlGetQNameProp(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
,
1055 xmlChar
**namespace) {
1056 xmlChar
*val
, *ret
, *prefix
;
1060 if (namespace != NULL
)
1062 val
= xmlGetProp(node
, (const xmlChar
*) name
);
1066 ret
= xmlSplitQName2(val
, &prefix
);
1071 ns
= xmlSearchNs(node
->doc
, node
, prefix
);
1073 xmlSchemaErrorContext(ctxt
, NULL
, node
, NULL
);
1074 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1075 ctxt
->error(ctxt
->userData
,
1076 "Attribute %s: the QName prefix %s is undefined\n",
1079 *namespace = xmlStrdup(ns
->href
);
1087 * @ctxt: a schema validation context
1088 * @node: a subtree containing XML Schema informations
1090 * Get the maxOccurs property
1092 * Returns the default if not found, or the value
1095 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
) {
1099 val
= xmlGetProp(node
, (const xmlChar
*) "maxOccurs");
1103 if (xmlStrEqual(val
, (const xmlChar
*) "unbounded")) {
1105 return(UNBOUNDED
); /* encoding it with -1 might be another option */
1109 while (IS_BLANK(*cur
)) cur
++;
1110 while ((*cur
>= '0') && (*cur
<= '9')) {
1111 ret
= ret
* 10 + (*cur
- '0');
1114 while (IS_BLANK(*cur
)) cur
++;
1116 xmlSchemaErrorContext(ctxt
, NULL
, node
, NULL
);
1117 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1118 ctxt
->error(ctxt
->userData
, "invalid value for minOccurs: %s\n",
1129 * @ctxt: a schema validation context
1130 * @node: a subtree containing XML Schema informations
1132 * Get the minOccurs property
1134 * Returns the default if not found, or the value
1137 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
) {
1141 val
= xmlGetProp(node
, (const xmlChar
*) "minOccurs");
1146 while (IS_BLANK(*cur
)) cur
++;
1147 while ((*cur
>= '0') && (*cur
<= '9')) {
1148 ret
= ret
* 10 + (*cur
- '0');
1151 while (IS_BLANK(*cur
)) cur
++;
1153 xmlSchemaErrorContext(ctxt
, NULL
, node
, NULL
);
1154 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1155 ctxt
->error(ctxt
->userData
, "invalid value for minOccurs: %s\n",
1165 * xmlGetBooleanProp:
1166 * @ctxt: a schema validation context
1167 * @node: a subtree containing XML Schema informations
1168 * @name: the attribute name
1169 * @def: the default value
1171 * Get is a bolean property is set
1173 * Returns the default if not found, 0 if found to be false,
1174 * 1 if found to be true
1177 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
,
1178 const char *name
, int def
) {
1181 val
= xmlGetProp(node
, (const xmlChar
*) name
);
1185 if (xmlStrEqual(val
, BAD_CAST
"true"))
1187 else if (xmlStrEqual(val
, BAD_CAST
"false"))
1190 xmlSchemaErrorContext(ctxt
, NULL
, node
, NULL
);
1191 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1192 ctxt
->error(ctxt
->userData
,
1193 "Attribute %s: the value %s is not boolean\n",
1200 /************************************************************************
1202 * Shema extraction from an Infoset *
1204 ************************************************************************/
1205 static xmlSchemaTypePtr
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
1206 ctxt
, xmlSchemaPtr schema
,
1208 static xmlSchemaTypePtr
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt
,
1209 xmlSchemaPtr schema
,
1211 static xmlSchemaTypePtr
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt
,
1212 xmlSchemaPtr schema
,
1215 static xmlSchemaTypePtr
xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt
,
1216 xmlSchemaPtr schema
,
1218 static xmlSchemaTypePtr
xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt
,
1219 xmlSchemaPtr schema
,
1221 static xmlSchemaAttributePtr
xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr
1223 xmlSchemaPtr schema
,
1225 static xmlSchemaAttributeGroupPtr
1226 xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt
,
1227 xmlSchemaPtr schema
, xmlNodePtr node
);
1228 static xmlSchemaTypePtr
xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt
,
1229 xmlSchemaPtr schema
,
1231 static xmlSchemaTypePtr
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt
,
1232 xmlSchemaPtr schema
,
1234 static xmlSchemaAttributePtr
1235 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1239 * xmlSchemaParseAttrDecls:
1240 * @ctxt: a schema validation context
1241 * @schema: the schema being built
1242 * @node: a subtree containing XML Schema informations
1243 * @type: the hosting type
1245 * parse a XML schema attrDecls declaration corresponding to
1246 * <!ENTITY % attrDecls
1247 * '((%attribute;| %attributeGroup;)*,(%anyAttribute;)?)'>
1250 xmlSchemaParseAttrDecls(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1251 xmlNodePtr child
, xmlSchemaTypePtr type
)
1253 xmlSchemaAttributePtr lastattr
, attr
;
1256 while ((IS_SCHEMA(child
, "attribute")) ||
1257 (IS_SCHEMA(child
, "attributeGroup"))) {
1259 if (IS_SCHEMA(child
, "attribute")) {
1260 attr
= xmlSchemaParseAttribute(ctxt
, schema
, child
);
1261 } else if (IS_SCHEMA(child
, "attributeGroup")) {
1262 attr
= (xmlSchemaAttributePtr
)
1263 xmlSchemaParseAttributeGroup(ctxt
, schema
, child
);
1266 if (lastattr
== NULL
) {
1267 type
->attributes
= attr
;
1271 lastattr
->next
= attr
;
1275 child
= child
->next
;
1277 if (IS_SCHEMA(child
, "anyAttribute")) {
1278 attr
= xmlSchemaParseAnyAttribute(ctxt
, schema
, child
);
1280 if (lastattr
== NULL
) {
1281 type
->attributes
= attr
;
1285 lastattr
->next
= attr
;
1289 child
= child
->next
;
1295 * xmlSchemaParseAnnotation:
1296 * @ctxt: a schema validation context
1297 * @schema: the schema being built
1298 * @node: a subtree containing XML Schema informations
1300 * parse a XML schema Attrribute declaration
1301 * *WARNING* this interface is highly subject to change
1303 * Returns -1 in case of error, 0 if the declaration is inproper and
1304 * 1 in case of success.
1306 static xmlSchemaAnnotPtr
1307 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1310 xmlSchemaAnnotPtr ret
;
1312 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1314 ret
= xmlSchemaNewAnnot(ctxt
, node
);
1320 * xmlSchemaParseFacet:
1321 * @ctxt: a schema validation context
1322 * @schema: the schema being built
1323 * @node: a subtree containing XML Schema informations
1325 * parse a XML schema Facet declaration
1326 * *WARNING* this interface is highly subject to change
1328 * Returns the new type structure or NULL in case of error
1330 static xmlSchemaFacetPtr
1331 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1334 xmlSchemaFacetPtr facet
;
1335 xmlNodePtr child
= NULL
;
1338 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1341 facet
= xmlSchemaNewFacet(ctxt
);
1345 value
= xmlGetProp(node
, (const xmlChar
*) "value");
1346 if (value
== NULL
) {
1347 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1348 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1349 ctxt
->error(ctxt
->userData
, "Facet %s has no value\n", node
->name
);
1350 xmlSchemaFreeFacet(facet
);
1353 if (IS_SCHEMA(node
, "minInclusive")) {
1354 facet
->type
= XML_SCHEMA_FACET_MININCLUSIVE
;
1355 } else if (IS_SCHEMA(node
, "minExclusive")) {
1356 facet
->type
= XML_SCHEMA_FACET_MINEXCLUSIVE
;
1357 } else if (IS_SCHEMA(node
, "maxInclusive")) {
1358 facet
->type
= XML_SCHEMA_FACET_MAXINCLUSIVE
;
1359 } else if (IS_SCHEMA(node
, "maxExclusive")) {
1360 facet
->type
= XML_SCHEMA_FACET_MAXEXCLUSIVE
;
1361 } else if (IS_SCHEMA(node
, "totalDigits")) {
1362 facet
->type
= XML_SCHEMA_FACET_TOTALDIGITS
;
1363 } else if (IS_SCHEMA(node
, "fractionDigits")) {
1364 facet
->type
= XML_SCHEMA_FACET_FRACTIONDIGITS
;
1365 } else if (IS_SCHEMA(node
, "pattern")) {
1366 facet
->type
= XML_SCHEMA_FACET_PATTERN
;
1367 } else if (IS_SCHEMA(node
, "enumeration")) {
1368 facet
->type
= XML_SCHEMA_FACET_ENUMERATION
;
1369 } else if (IS_SCHEMA(node
, "whiteSpace")) {
1370 facet
->type
= XML_SCHEMA_FACET_WHITESPACE
;
1371 } else if (IS_SCHEMA(node
, "length")) {
1372 facet
->type
= XML_SCHEMA_FACET_LENGTH
;
1373 } else if (IS_SCHEMA(node
, "maxLength")) {
1374 facet
->type
= XML_SCHEMA_FACET_MAXLENGTH
;
1375 } else if (IS_SCHEMA(node
, "minLength")) {
1376 facet
->type
= XML_SCHEMA_FACET_MINLENGTH
;
1378 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1379 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1380 ctxt
->error(ctxt
->userData
, "Unknown facet type %s\n", node
->name
);
1381 xmlSchemaFreeFacet(facet
);
1384 facet
->id
= xmlGetProp(node
, (const xmlChar
*) "id");
1385 facet
->value
= value
;
1386 child
= node
->children
;
1388 if (IS_SCHEMA(child
, "annotation")) {
1389 facet
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
1390 child
= child
->next
;
1392 if (child
!= NULL
) {
1393 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1394 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1395 ctxt
->error(ctxt
->userData
,
1396 "Facet %s has unexpected child content\n",
1403 * xmlSchemaParseAny:
1404 * @ctxt: a schema validation context
1405 * @schema: the schema being built
1406 * @node: a subtree containing XML Schema informations
1408 * parse a XML schema Any declaration
1409 * *WARNING* this interface is highly subject to change
1411 * Returns the new type structure or NULL in case of error
1413 static xmlSchemaTypePtr
1414 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1417 xmlSchemaTypePtr type
;
1418 xmlNodePtr child
= NULL
;
1421 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1423 snprintf((char *)name
, 30, "any %d", ctxt
->counter
++ + 1);
1424 type
= xmlSchemaAddType(ctxt
, schema
, name
);
1428 type
->type
= XML_SCHEMA_TYPE_ANY
;
1429 child
= node
->children
;
1430 type
->minOccurs
= xmlGetMinOccurs(ctxt
, node
);
1431 type
->maxOccurs
= xmlGetMaxOccurs(ctxt
, node
);
1433 if (IS_SCHEMA(child
, "annotation")) {
1434 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
1435 child
= child
->next
;
1437 if (child
!= NULL
) {
1438 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1439 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1440 ctxt
->error(ctxt
->userData
,
1441 "Sequence %s has unexpected content\n",
1449 * xmlSchemaParseNotation:
1450 * @ctxt: a schema validation context
1451 * @schema: the schema being built
1452 * @node: a subtree containing XML Schema informations
1454 * parse a XML schema Notation declaration
1456 * Returns the new structure or NULL in case of error
1458 static xmlSchemaNotationPtr
1459 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1463 xmlSchemaNotationPtr ret
;
1464 xmlNodePtr child
= NULL
;
1466 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1468 name
= xmlGetProp(node
, (const xmlChar
*) "name");
1470 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1471 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1472 ctxt
->error(ctxt
->userData
, "Notation has no name\n");
1475 ret
= xmlSchemaAddNotation(ctxt
, schema
, name
);
1480 child
= node
->children
;
1481 if (IS_SCHEMA(child
, "annotation")) {
1482 ret
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
1483 child
= child
->next
;
1485 if (child
!= NULL
) {
1486 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1487 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1488 ctxt
->error(ctxt
->userData
,
1489 "notation %s has unexpected content\n",
1497 * xmlSchemaParseAnyAttribute:
1498 * @ctxt: a schema validation context
1499 * @schema: the schema being built
1500 * @node: a subtree containing XML Schema informations
1502 * parse a XML schema AnyAttrribute declaration
1503 * *WARNING* this interface is highly subject to change
1505 * Returns an attribute def structure or NULL
1507 static xmlSchemaAttributePtr
1508 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1511 xmlChar
*processContents
;
1512 xmlSchemaAttributePtr ret
;
1513 xmlNodePtr child
= NULL
;
1516 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1519 snprintf(name
, 99, "anyattr %d", ctxt
->counter
++ + 1);
1520 ret
= xmlSchemaAddAttribute(ctxt
, schema
, (xmlChar
*)name
);
1524 ret
->id
= xmlGetProp(node
, (const xmlChar
*) "id");
1525 processContents
= xmlGetProp(node
, (const xmlChar
*) "processContents");
1526 if ((processContents
== NULL
) ||
1527 (xmlStrEqual(processContents
, (const xmlChar
*)"strict"))) {
1528 ret
->occurs
= XML_SCHEMAS_ANYATTR_STRICT
;
1529 } else if (xmlStrEqual(processContents
, (const xmlChar
*)"skip")) {
1530 ret
->occurs
= XML_SCHEMAS_ANYATTR_SKIP
;
1531 } else if (xmlStrEqual(processContents
, (const xmlChar
*)"lax")) {
1532 ret
->occurs
= XML_SCHEMAS_ANYATTR_LAX
;
1534 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1535 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1536 ctxt
->error(ctxt
->userData
,
1537 "anyAttribute has unexpected content for processContents: %s\n",
1539 ret
->occurs
= XML_SCHEMAS_ANYATTR_STRICT
;
1541 if (processContents
!= NULL
)
1542 xmlFree(processContents
);
1544 child
= node
->children
;
1545 if (IS_SCHEMA(child
, "annotation")) {
1546 ret
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
1547 child
= child
->next
;
1549 if (child
!= NULL
) {
1550 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1551 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1552 ctxt
->error(ctxt
->userData
,
1553 "anyAttribute %s has unexpected content\n",
1562 * xmlSchemaParseAttribute:
1563 * @ctxt: a schema validation context
1564 * @schema: the schema being built
1565 * @node: a subtree containing XML Schema informations
1567 * parse a XML schema Attrribute declaration
1568 * *WARNING* this interface is highly subject to change
1570 * Returns -1 in case of error, 0 if the declaration is inproper and
1571 * 1 in case of success.
1573 static xmlSchemaAttributePtr
1574 xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1577 xmlChar
*name
, *refNs
= NULL
, *ref
= NULL
;
1578 xmlSchemaAttributePtr ret
;
1579 xmlNodePtr child
= NULL
;
1581 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1583 name
= xmlGetProp(node
, (const xmlChar
*) "name");
1587 ref
= xmlGetQNameProp(ctxt
, node
, "ref", &refNs
);
1589 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1590 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1591 ctxt
->error(ctxt
->userData
, "Attribute has no name nor ref\n");
1594 snprintf(buf
, 99, "anonattr%d", ctxt
->counter
++ + 1);
1595 name
= xmlStrdup((xmlChar
*) buf
);
1597 ret
= xmlSchemaAddAttribute(ctxt
, schema
, name
);
1607 ret
->typeName
= xmlGetQNameProp(ctxt
, node
, "type", &(ret
->typeNs
));
1608 child
= node
->children
;
1609 if (IS_SCHEMA(child
, "annotation")) {
1610 ret
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
1611 child
= child
->next
;
1613 if (IS_SCHEMA(child
, "simpleType")) {
1614 ret
->subtypes
= xmlSchemaParseSimpleType(ctxt
, schema
, child
);
1615 child
= child
->next
;
1617 if (child
!= NULL
) {
1618 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1619 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1620 ctxt
->error(ctxt
->userData
,
1621 "attribute %s has unexpected content\n",
1629 * xmlSchemaParseAttributeGroup:
1630 * @ctxt: a schema validation context
1631 * @schema: the schema being built
1632 * @node: a subtree containing XML Schema informations
1634 * parse a XML schema Attribute Group declaration
1635 * *WARNING* this interface is highly subject to change
1637 * Returns the attribute group or NULL in case of error.
1639 static xmlSchemaAttributeGroupPtr
1640 xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1643 xmlChar
*name
, *refNs
= NULL
, *ref
= NULL
;
1644 xmlSchemaAttributeGroupPtr ret
;
1645 xmlSchemaAttributePtr last
= NULL
, attr
;
1646 xmlNodePtr child
= NULL
;
1647 xmlChar
*oldcontainer
;
1649 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1651 oldcontainer
= ctxt
->container
;
1652 name
= xmlGetProp(node
, (const xmlChar
*) "name");
1656 ref
= xmlGetQNameProp(ctxt
, node
, "ref", &refNs
);
1658 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1659 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1660 ctxt
->error(ctxt
->userData
,
1661 "AttributeGroup has no name nor ref\n");
1664 snprintf(buf
, 99, "anonattrgroup%d", ctxt
->counter
++ + 1);
1665 name
= xmlStrdup((xmlChar
*) buf
);
1667 ret
= xmlSchemaAddAttributeGroup(ctxt
, schema
, name
);
1676 ret
->type
= XML_SCHEMA_TYPE_ATTRIBUTEGROUP
;
1677 child
= node
->children
;
1678 ctxt
->container
= name
;
1679 if (IS_SCHEMA(child
, "annotation")) {
1680 ret
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
1681 child
= child
->next
;
1683 while ((IS_SCHEMA(child
, "attribute")) ||
1684 (IS_SCHEMA(child
, "attributeGroup"))) {
1686 if (IS_SCHEMA(child
, "attribute")) {
1687 attr
= xmlSchemaParseAttribute(ctxt
, schema
, child
);
1688 } else if (IS_SCHEMA(child
, "attributeGroup")) {
1689 attr
= (xmlSchemaAttributePtr
)
1690 xmlSchemaParseAttributeGroup(ctxt
, schema
, child
);
1694 ret
->attributes
= attr
;
1701 child
= child
->next
;
1703 if (IS_SCHEMA(child
, "anyAttribute")) {
1705 child
= child
->next
;
1707 if (child
!= NULL
) {
1708 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1709 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1710 ctxt
->error(ctxt
->userData
,
1711 "attribute group %s has unexpected content\n",
1715 ctxt
->container
= oldcontainer
;
1720 * xmlSchemaParseElement:
1721 * @ctxt: a schema validation context
1722 * @schema: the schema being built
1723 * @node: a subtree containing XML Schema informations
1725 * parse a XML schema Element declaration
1726 * *WARNING* this interface is highly subject to change
1728 * Returns -1 in case of error, 0 if the declaration is inproper and
1729 * 1 in case of success.
1731 static xmlSchemaElementPtr
1732 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1733 xmlNodePtr node
, int toplevel
)
1735 xmlChar
*name
, *refNs
= NULL
, *ref
= NULL
, *namespace, *fixed
;
1736 xmlSchemaElementPtr ret
;
1737 xmlNodePtr child
= NULL
;
1738 xmlChar
*oldcontainer
;
1740 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1742 oldcontainer
= ctxt
->container
;
1743 name
= xmlGetProp(node
, (const xmlChar
*) "name");
1747 ref
= xmlGetQNameProp(ctxt
, node
, "ref", &refNs
);
1749 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1750 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1751 ctxt
->error(ctxt
->userData
, "Element has no name nor ref\n");
1754 snprintf(buf
, 99, "anonelem%d", ctxt
->counter
++ + 1);
1755 name
= xmlStrdup((xmlChar
*) buf
);
1757 namespace = xmlGetProp(node
, (const xmlChar
*) "targetNamespace");
1758 if (namespace == NULL
)
1760 xmlSchemaAddElement(ctxt
, schema
, name
,
1761 schema
->targetNamespace
);
1763 ret
= xmlSchemaAddElement(ctxt
, schema
, name
, namespace);
1764 if (namespace != NULL
)
1772 ret
->type
= XML_SCHEMA_TYPE_ELEMENT
;
1776 ret
->flags
|= XML_SCHEMAS_ELEM_REF
;
1778 ret
->flags
|= XML_SCHEMAS_ELEM_TOPLEVEL
;
1779 if (xmlGetBooleanProp(ctxt
, node
, "nillable", 0))
1780 ret
->flags
|= XML_SCHEMAS_ELEM_NILLABLE
;
1781 if (xmlGetBooleanProp(ctxt
, node
, "abstract", 0))
1782 ret
->flags
|= XML_SCHEMAS_ELEM_NILLABLE
;
1783 ctxt
->container
= name
;
1785 ret
->id
= xmlGetProp(node
, BAD_CAST
"id");
1786 ret
->namedType
= xmlGetQNameProp(ctxt
, node
, "type", &(ret
->namedTypeNs
));
1787 ret
->substGroup
= xmlGetQNameProp(ctxt
, node
, "substitutionGroup",
1788 &(ret
->substGroupNs
));
1789 fixed
= xmlGetProp(node
, BAD_CAST
"fixed");
1790 ret
->minOccurs
= xmlGetMinOccurs(ctxt
, node
);
1791 ret
->maxOccurs
= xmlGetMaxOccurs(ctxt
, node
);
1793 ret
->value
= xmlGetProp(node
, BAD_CAST
"default");
1794 if ((ret
->value
!= NULL
) && (fixed
!= NULL
)) {
1795 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1796 ctxt
->error(ctxt
->userData
,
1797 "Element %s has both default and fixed\n",
1800 } else if (fixed
!= NULL
) {
1801 ret
->flags
|= XML_SCHEMAS_ELEM_FIXED
;
1805 child
= node
->children
;
1806 if (IS_SCHEMA(child
, "annotation")) {
1807 ret
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
1808 child
= child
->next
;
1810 if (IS_SCHEMA(child
, "complexType")) {
1811 ret
->subtypes
= xmlSchemaParseComplexType(ctxt
, schema
, child
);
1812 child
= child
->next
;
1813 } else if (IS_SCHEMA(child
, "simpleType")) {
1814 ret
->subtypes
= xmlSchemaParseSimpleType(ctxt
, schema
, child
);
1815 child
= child
->next
;
1817 while ((IS_SCHEMA(child
, "unique")) ||
1818 (IS_SCHEMA(child
, "key")) ||
1819 (IS_SCHEMA(child
, "keyref"))) {
1821 child
= child
->next
;
1823 if (child
!= NULL
) {
1824 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1825 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1826 ctxt
->error(ctxt
->userData
,
1827 "element %s has unexpected content\n",
1831 ctxt
->container
= oldcontainer
;
1837 * xmlSchemaParseUnion:
1838 * @ctxt: a schema validation context
1839 * @schema: the schema being built
1840 * @node: a subtree containing XML Schema informations
1842 * parse a XML schema Union definition
1843 * *WARNING* this interface is highly subject to change
1845 * Returns -1 in case of error, 0 if the declaration is inproper and
1846 * 1 in case of success.
1848 static xmlSchemaTypePtr
1849 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1852 xmlSchemaTypePtr type
, subtype
, last
= NULL
;
1853 xmlNodePtr child
= NULL
;
1856 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1860 snprintf((char *)name
, 30, "union %d", ctxt
->counter
++ + 1);
1861 type
= xmlSchemaAddType(ctxt
, schema
, name
);
1865 type
->type
= XML_SCHEMA_TYPE_LIST
;
1866 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
1867 type
->ref
= xmlGetProp(node
, BAD_CAST
"memberTypes");
1869 child
= node
->children
;
1870 if (IS_SCHEMA(child
, "annotation")) {
1871 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
1872 child
= child
->next
;
1874 while (IS_SCHEMA(child
, "simpleType")) {
1875 subtype
= (xmlSchemaTypePtr
)
1876 xmlSchemaParseSimpleType(ctxt
, schema
, child
);
1877 if (subtype
!= NULL
) {
1879 type
->subtypes
= subtype
;
1882 last
->next
= subtype
;
1887 child
= child
->next
;
1889 if (child
!= NULL
) {
1890 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1891 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1892 ctxt
->error(ctxt
->userData
,
1893 "Union %s has unexpected content\n",
1900 * xmlSchemaParseList:
1901 * @ctxt: a schema validation context
1902 * @schema: the schema being built
1903 * @node: a subtree containing XML Schema informations
1905 * parse a XML schema List definition
1906 * *WARNING* this interface is highly subject to change
1908 * Returns -1 in case of error, 0 if the declaration is inproper and
1909 * 1 in case of success.
1911 static xmlSchemaTypePtr
1912 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1915 xmlSchemaTypePtr type
, subtype
;
1916 xmlNodePtr child
= NULL
;
1919 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1922 snprintf((char *)name
, 30, "list %d", ctxt
->counter
++ + 1);
1923 type
= xmlSchemaAddType(ctxt
, schema
, name
);
1927 type
->type
= XML_SCHEMA_TYPE_LIST
;
1928 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
1929 type
->ref
= xmlGetQNameProp(ctxt
, node
, "ref", &(type
->refNs
));
1931 child
= node
->children
;
1932 if (IS_SCHEMA(child
, "annotation")) {
1933 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
1934 child
= child
->next
;
1937 if (IS_SCHEMA(child
, "simpleType")) {
1938 subtype
= (xmlSchemaTypePtr
)
1939 xmlSchemaParseSimpleType(ctxt
, schema
, child
);
1940 child
= child
->next
;
1941 type
->subtypes
= subtype
;
1943 if (child
!= NULL
) {
1944 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1945 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1946 ctxt
->error(ctxt
->userData
,
1947 "List %s has unexpected content\n",
1953 * xmlSchemaParseSimpleType:
1954 * @ctxt: a schema validation context
1955 * @schema: the schema being built
1956 * @node: a subtree containing XML Schema informations
1958 * parse a XML schema Simple Type definition
1959 * *WARNING* this interface is highly subject to change
1961 * Returns -1 in case of error, 0 if the declaration is inproper and
1962 * 1 in case of success.
1964 static xmlSchemaTypePtr
1965 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1968 xmlSchemaTypePtr type
, subtype
;
1969 xmlNodePtr child
= NULL
;
1972 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
1976 name
= xmlGetProp(node
, (const xmlChar
*) "name");
1980 snprintf(buf
, 99, "simpletype%d", ctxt
->counter
++ + 1);
1981 name
= xmlStrdup((xmlChar
*) buf
);
1984 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
1985 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
1986 ctxt
->error(ctxt
->userData
, "simpleType has no name\n");
1989 type
= xmlSchemaAddType(ctxt
, schema
, name
);
1994 type
->type
= XML_SCHEMA_TYPE_SIMPLE
;
1995 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
1997 child
= node
->children
;
1998 if (IS_SCHEMA(child
, "annotation")) {
1999 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2000 child
= child
->next
;
2003 if (IS_SCHEMA(child
, "restriction")) {
2004 subtype
= (xmlSchemaTypePtr
)
2005 xmlSchemaParseRestriction(ctxt
, schema
, child
, 1);
2006 child
= child
->next
;
2007 } else if (IS_SCHEMA(child
, "list")) {
2008 subtype
= (xmlSchemaTypePtr
)
2009 xmlSchemaParseList(ctxt
, schema
, child
);
2010 child
= child
->next
;
2011 } else if (IS_SCHEMA(child
, "union")) {
2012 subtype
= (xmlSchemaTypePtr
)
2013 xmlSchemaParseUnion(ctxt
, schema
, child
);
2014 child
= child
->next
;
2016 type
->subtypes
= subtype
;
2017 if (child
!= NULL
) {
2018 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2019 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2020 ctxt
->error(ctxt
->userData
,
2021 "SimpleType %s has unexpected content\n",
2030 * xmlSchemaParseGroup:
2031 * @ctxt: a schema validation context
2032 * @schema: the schema being built
2033 * @node: a subtree containing XML Schema informations
2035 * parse a XML schema Group definition
2036 * *WARNING* this interface is highly subject to change
2038 * Returns -1 in case of error, 0 if the declaration is inproper and
2039 * 1 in case of success.
2041 static xmlSchemaTypePtr
2042 xmlSchemaParseGroup(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
2045 xmlSchemaTypePtr type
, subtype
;
2046 xmlNodePtr child
= NULL
;
2047 xmlChar
*name
, *ref
= NULL
, *refNs
= NULL
;
2049 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
2053 name
= xmlGetProp(node
, (const xmlChar
*) "name");
2057 ref
= xmlGetQNameProp(ctxt
, node
, "ref", &refNs
);
2059 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2060 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2061 ctxt
->error(ctxt
->userData
, "Group has no name nor ref\n");
2064 snprintf(buf
, 99, "anongroup%d", ctxt
->counter
++ + 1);
2065 name
= xmlStrdup((xmlChar
*) buf
);
2067 type
= xmlSchemaAddType(ctxt
, schema
, name
);
2071 type
->type
= XML_SCHEMA_TYPE_GROUP
;
2072 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
2074 type
->refNs
= refNs
;
2075 type
->minOccurs
= xmlGetMinOccurs(ctxt
, node
);
2076 type
->maxOccurs
= xmlGetMaxOccurs(ctxt
, node
);
2078 child
= node
->children
;
2079 if (IS_SCHEMA(child
, "annotation")) {
2080 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2081 child
= child
->next
;
2084 if (IS_SCHEMA(child
, "all")) {
2085 subtype
= (xmlSchemaTypePtr
)
2086 xmlSchemaParseAll(ctxt
, schema
, child
);
2087 child
= child
->next
;
2088 } else if (IS_SCHEMA(child
, "choice")) {
2089 subtype
= xmlSchemaParseChoice(ctxt
, schema
, child
);
2090 child
= child
->next
;
2091 } else if (IS_SCHEMA(child
, "sequence")) {
2092 subtype
= (xmlSchemaTypePtr
)
2093 xmlSchemaParseSequence(ctxt
, schema
, child
);
2094 child
= child
->next
;
2096 if (subtype
!= NULL
)
2097 type
->subtypes
= subtype
;
2098 if (child
!= NULL
) {
2099 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2100 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2101 ctxt
->error(ctxt
->userData
,
2102 "Group %s has unexpected content\n",
2110 * xmlSchemaParseAll:
2111 * @ctxt: a schema validation context
2112 * @schema: the schema being built
2113 * @node: a subtree containing XML Schema informations
2115 * parse a XML schema All definition
2116 * *WARNING* this interface is highly subject to change
2118 * Returns -1 in case of error, 0 if the declaration is inproper and
2119 * 1 in case of success.
2121 static xmlSchemaTypePtr
2122 xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
2125 xmlSchemaTypePtr type
, subtype
, last
= NULL
;
2126 xmlNodePtr child
= NULL
;
2129 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
2133 snprintf((char *)name
, 30, "all%d", ctxt
->counter
++ + 1);
2134 type
= xmlSchemaAddType(ctxt
, schema
, name
);
2138 type
->type
= XML_SCHEMA_TYPE_ALL
;
2139 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
2140 type
->minOccurs
= xmlGetMinOccurs(ctxt
, node
);
2141 type
->maxOccurs
= xmlGetMaxOccurs(ctxt
, node
);
2143 child
= node
->children
;
2144 if (IS_SCHEMA(child
, "annotation")) {
2145 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2146 child
= child
->next
;
2148 while (IS_SCHEMA(child
, "element")) {
2149 subtype
= (xmlSchemaTypePtr
)
2150 xmlSchemaParseElement(ctxt
, schema
, child
, 0);
2151 if (subtype
!= NULL
) {
2153 type
->subtypes
= subtype
;
2156 last
->next
= subtype
;
2161 child
= child
->next
;
2163 if (child
!= NULL
) {
2164 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2165 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2166 ctxt
->error(ctxt
->userData
,
2167 "All %s has unexpected content\n",
2175 * xmlSchemaParseImport:
2176 * @ctxt: a schema validation context
2177 * @schema: the schema being built
2178 * @node: a subtree containing XML Schema informations
2180 * parse a XML schema Import definition
2181 * *WARNING* this interface is highly subject to change
2183 * Returns -1 in case of error, 0 if the declaration is inproper and
2184 * 1 in case of success.
2187 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
2190 xmlNodePtr child
= NULL
;
2192 xmlChar
*schemaLocation
;
2196 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
2199 namespace = xmlGetProp(node
, BAD_CAST
"namespace");
2200 if (namespace != NULL
) {
2201 check
= xmlParseURI((const char *) namespace);
2202 if (check
== NULL
) {
2203 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2204 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2205 ctxt
->error(ctxt
->userData
,
2206 "Import namespace attribute is not an URI: %s\n",
2214 schemaLocation
= xmlGetProp(node
, BAD_CAST
"schemaLocation");
2215 if (schemaLocation
!= NULL
) {
2216 check
= xmlParseURI((const char *) schemaLocation
);
2217 if (check
== NULL
) {
2218 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2219 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2220 ctxt
->error(ctxt
->userData
,
2221 "Import schemaLocation attribute is not an URI: %s\n",
2223 if (namespace != NULL
)
2225 xmlFree(schemaLocation
);
2231 if (schema
->schemasImports
== NULL
) {
2232 schema
->schemasImports
= xmlHashCreate(10);
2233 if (schema
->schemasImports
== NULL
) {
2234 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2235 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2236 ctxt
->error(ctxt
->userData
,
2237 "Internal: failed to build import table\n");
2238 if (namespace != NULL
)
2240 if (schemaLocation
!= NULL
)
2241 xmlFree(schemaLocation
);
2245 if (namespace == NULL
) {
2246 previous
= xmlHashLookup(schema
->schemasImports
,
2247 XML_SCHEMAS_DEFAULT_NAMESPACE
);
2248 if (schemaLocation
!= NULL
) {
2249 if (previous
!= NULL
) {
2250 if (!xmlStrEqual(schemaLocation
, previous
)) {
2251 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2252 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2253 ctxt
->error(ctxt
->userData
,
2254 "Redefining import for default namespace with a different URI: %s\n",
2258 xmlHashAddEntry(schema
->schemasImports
,
2259 XML_SCHEMAS_DEFAULT_NAMESPACE
, schemaLocation
);
2263 previous
= xmlHashLookup(schema
->schemasImports
, namespace);
2264 if (schemaLocation
!= NULL
) {
2265 if (previous
!= NULL
) {
2266 if (!xmlStrEqual(schemaLocation
, previous
)) {
2267 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2268 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2269 ctxt
->error(ctxt
->userData
,
2270 "Redefining import for namespace %s with a different URI: %s\n",
2271 namespace, schemaLocation
);
2274 xmlHashAddEntry(schema
->schemasImports
,
2275 namespace, schemaLocation
);
2280 child
= node
->children
;
2281 while (IS_SCHEMA(child
, "annotation")) {
2283 * the annotations here are simply discarded ...
2285 child
= child
->next
;
2287 if (child
!= NULL
) {
2288 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2289 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2290 ctxt
->error(ctxt
->userData
,
2291 "Import has unexpected content\n");
2298 * xmlSchemaParseChoice:
2299 * @ctxt: a schema validation context
2300 * @schema: the schema being built
2301 * @node: a subtree containing XML Schema informations
2303 * parse a XML schema Choice definition
2304 * *WARNING* this interface is highly subject to change
2306 * Returns -1 in case of error, 0 if the declaration is inproper and
2307 * 1 in case of success.
2309 static xmlSchemaTypePtr
2310 xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
2313 xmlSchemaTypePtr type
, subtype
, last
= NULL
;
2314 xmlNodePtr child
= NULL
;
2317 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
2321 snprintf((char *)name
, 30, "choice %d", ctxt
->counter
++ + 1);
2322 type
= xmlSchemaAddType(ctxt
, schema
, name
);
2326 type
->type
= XML_SCHEMA_TYPE_CHOICE
;
2327 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
2328 type
->minOccurs
= xmlGetMinOccurs(ctxt
, node
);
2329 type
->maxOccurs
= xmlGetMaxOccurs(ctxt
, node
);
2331 child
= node
->children
;
2332 if (IS_SCHEMA(child
, "annotation")) {
2333 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2334 child
= child
->next
;
2336 while ((IS_SCHEMA(child
, "element")) ||
2337 (IS_SCHEMA(child
, "group")) ||
2338 (IS_SCHEMA(child
, "any")) ||
2339 (IS_SCHEMA(child
, "choice")) ||
2340 (IS_SCHEMA(child
, "sequence"))) {
2342 if (IS_SCHEMA(child
, "element")) {
2343 subtype
= (xmlSchemaTypePtr
)
2344 xmlSchemaParseElement(ctxt
, schema
, child
, 0);
2345 } else if (IS_SCHEMA(child
, "group")) {
2346 subtype
= xmlSchemaParseGroup(ctxt
, schema
, child
);
2347 } else if (IS_SCHEMA(child
, "any")) {
2348 subtype
= xmlSchemaParseAny(ctxt
, schema
, child
);
2349 } else if (IS_SCHEMA(child
, "sequence")) {
2350 subtype
= xmlSchemaParseSequence(ctxt
, schema
, child
);
2351 } else if (IS_SCHEMA(child
, "choice")) {
2352 subtype
= xmlSchemaParseChoice(ctxt
, schema
, child
);
2354 if (subtype
!= NULL
) {
2356 type
->subtypes
= subtype
;
2359 last
->next
= subtype
;
2364 child
= child
->next
;
2366 if (child
!= NULL
) {
2367 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2368 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2369 ctxt
->error(ctxt
->userData
,
2370 "Choice %s has unexpected content\n",
2378 * xmlSchemaParseSequence:
2379 * @ctxt: a schema validation context
2380 * @schema: the schema being built
2381 * @node: a subtree containing XML Schema informations
2383 * parse a XML schema Sequence definition
2384 * *WARNING* this interface is highly subject to change
2386 * Returns -1 in case of error, 0 if the declaration is inproper and
2387 * 1 in case of success.
2389 static xmlSchemaTypePtr
2390 xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
2393 xmlSchemaTypePtr type
, subtype
, last
= NULL
;
2394 xmlNodePtr child
= NULL
;
2397 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
2401 snprintf((char *)name
, 30, "sequence %d", ctxt
->counter
++ + 1);
2402 type
= xmlSchemaAddType(ctxt
, schema
, name
);
2406 type
->type
= XML_SCHEMA_TYPE_SEQUENCE
;
2407 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
2408 type
->minOccurs
= xmlGetMinOccurs(ctxt
, node
);
2409 type
->maxOccurs
= xmlGetMaxOccurs(ctxt
, node
);
2411 child
= node
->children
;
2412 if (IS_SCHEMA(child
, "annotation")) {
2413 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2414 child
= child
->next
;
2416 while ((IS_SCHEMA(child
, "element")) ||
2417 (IS_SCHEMA(child
, "group")) ||
2418 (IS_SCHEMA(child
, "any")) ||
2419 (IS_SCHEMA(child
, "choice")) ||
2420 (IS_SCHEMA(child
, "sequence"))) {
2422 if (IS_SCHEMA(child
, "element")) {
2423 subtype
= (xmlSchemaTypePtr
)
2424 xmlSchemaParseElement(ctxt
, schema
, child
, 0);
2425 } else if (IS_SCHEMA(child
, "group")) {
2426 subtype
= xmlSchemaParseGroup(ctxt
, schema
, child
);
2427 } else if (IS_SCHEMA(child
, "any")) {
2428 subtype
= xmlSchemaParseAny(ctxt
, schema
, child
);
2429 } else if (IS_SCHEMA(child
, "choice")) {
2430 subtype
= xmlSchemaParseChoice(ctxt
, schema
, child
);
2431 } else if (IS_SCHEMA(child
, "sequence")) {
2432 subtype
= xmlSchemaParseSequence(ctxt
, schema
, child
);
2434 if (subtype
!= NULL
) {
2436 type
->subtypes
= subtype
;
2439 last
->next
= subtype
;
2444 child
= child
->next
;
2446 if (child
!= NULL
) {
2447 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2448 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2449 ctxt
->error(ctxt
->userData
,
2450 "Sequence %s has unexpected content\n",
2458 * xmlSchemaParseRestriction:
2459 * @ctxt: a schema validation context
2460 * @schema: the schema being built
2461 * @node: a subtree containing XML Schema informations
2462 * @simple: is that part of a simple type.
2464 * parse a XML schema Restriction definition
2465 * *WARNING* this interface is highly subject to change
2467 * Returns the type definition or NULL in case of error
2469 static xmlSchemaTypePtr
2470 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
2471 xmlNodePtr node
, int simple
)
2473 xmlSchemaTypePtr type
, subtype
;
2474 xmlSchemaFacetPtr facet
, lastfacet
= NULL
;
2475 xmlNodePtr child
= NULL
;
2477 xmlChar
*oldcontainer
;
2479 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
2482 oldcontainer
= ctxt
->container
;
2484 snprintf((char *)name
, 30, "restriction %d", ctxt
->counter
++ + 1);
2485 type
= xmlSchemaAddType(ctxt
, schema
, name
);
2489 type
->type
= XML_SCHEMA_TYPE_RESTRICTION
;
2490 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
2491 type
->base
= xmlGetQNameProp(ctxt
, node
, "base", &(type
->baseNs
));
2492 if ((!simple
) && (type
->base
== NULL
)) {
2493 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2494 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2495 ctxt
->error(ctxt
->userData
,
2496 "Restriction %s has no base\n",
2499 ctxt
->container
= name
;
2501 child
= node
->children
;
2502 if (IS_SCHEMA(child
, "annotation")) {
2503 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2504 child
= child
->next
;
2508 if (IS_SCHEMA(child
, "all")) {
2509 subtype
= (xmlSchemaTypePtr
)
2510 xmlSchemaParseAll(ctxt
, schema
, child
);
2511 child
= child
->next
;
2512 type
->subtypes
= subtype
;
2513 } else if (IS_SCHEMA(child
, "choice")) {
2514 subtype
= xmlSchemaParseChoice(ctxt
, schema
, child
);
2515 child
= child
->next
;
2516 type
->subtypes
= subtype
;
2517 } else if (IS_SCHEMA(child
, "sequence")) {
2518 subtype
= (xmlSchemaTypePtr
)
2519 xmlSchemaParseSequence(ctxt
, schema
, child
);
2520 child
= child
->next
;
2521 type
->subtypes
= subtype
;
2522 } else if (IS_SCHEMA(child
, "group")) {
2523 subtype
= (xmlSchemaTypePtr
)
2524 xmlSchemaParseGroup(ctxt
, schema
, child
);
2525 child
= child
->next
;
2526 type
->subtypes
= subtype
;
2528 if (IS_SCHEMA(child
, "simpleType")) {
2529 subtype
= (xmlSchemaTypePtr
)
2530 xmlSchemaParseSimpleType(ctxt
, schema
, child
);
2531 child
= child
->next
;
2532 type
->baseType
= subtype
;
2537 while ((IS_SCHEMA(child
, "minInclusive")) ||
2538 (IS_SCHEMA(child
, "minExclusive")) ||
2539 (IS_SCHEMA(child
, "maxInclusive")) ||
2540 (IS_SCHEMA(child
, "maxExclusive")) ||
2541 (IS_SCHEMA(child
, "totalDigits")) ||
2542 (IS_SCHEMA(child
, "fractionDigits")) ||
2543 (IS_SCHEMA(child
, "pattern")) ||
2544 (IS_SCHEMA(child
, "enumeration")) ||
2545 (IS_SCHEMA(child
, "whiteSpace")) ||
2546 (IS_SCHEMA(child
, "length")) ||
2547 (IS_SCHEMA(child
, "maxLength")) ||
2548 (IS_SCHEMA(child
, "minLength"))) {
2549 facet
= xmlSchemaParseFacet(ctxt
, schema
, child
);
2550 if (facet
!= NULL
) {
2551 if (lastfacet
== NULL
) {
2552 type
->facets
= facet
;
2555 lastfacet
->next
= facet
;
2558 lastfacet
->next
= NULL
;
2560 child
= child
->next
;
2563 child
= xmlSchemaParseAttrDecls(ctxt
, schema
, child
, type
);
2564 if (child
!= NULL
) {
2565 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2566 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2567 ctxt
->error(ctxt
->userData
,
2568 "Restriction %s has unexpected content\n",
2571 ctxt
->container
= oldcontainer
;
2576 * xmlSchemaParseExtension:
2577 * @ctxt: a schema validation context
2578 * @schema: the schema being built
2579 * @node: a subtree containing XML Schema informations
2581 * parse a XML schema Extension definition
2582 * *WARNING* this interface is highly subject to change
2584 * Returns the type definition or NULL in case of error
2586 static xmlSchemaTypePtr
2587 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
2590 xmlSchemaTypePtr type
, subtype
;
2591 xmlNodePtr child
= NULL
;
2593 xmlChar
*oldcontainer
;
2595 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
2598 oldcontainer
= ctxt
->container
;
2600 snprintf((char *)name
, 30, "extension %d", ctxt
->counter
++ + 1);
2601 type
= xmlSchemaAddType(ctxt
, schema
, name
);
2605 type
->type
= XML_SCHEMA_TYPE_EXTENSION
;
2606 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
2607 ctxt
->container
= name
;
2609 type
->base
= xmlGetQNameProp(ctxt
, node
, "base", &(type
->baseNs
));
2610 if (type
->base
== NULL
) {
2611 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2612 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2613 ctxt
->error(ctxt
->userData
,
2614 "Extension %s has no base\n",
2617 child
= node
->children
;
2618 if (IS_SCHEMA(child
, "annotation")) {
2619 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2620 child
= child
->next
;
2624 if (IS_SCHEMA(child
, "all")) {
2625 subtype
= xmlSchemaParseAll(ctxt
, schema
, child
);
2626 child
= child
->next
;
2627 } else if (IS_SCHEMA(child
, "choice")) {
2628 subtype
= xmlSchemaParseChoice(ctxt
, schema
, child
);
2629 child
= child
->next
;
2630 } else if (IS_SCHEMA(child
, "sequence")) {
2631 subtype
= xmlSchemaParseSequence(ctxt
, schema
, child
);
2632 child
= child
->next
;
2633 } else if (IS_SCHEMA(child
, "group")) {
2634 subtype
= xmlSchemaParseGroup(ctxt
, schema
, child
);
2635 child
= child
->next
;
2637 if (subtype
!= NULL
)
2638 type
->subtypes
= subtype
;
2639 child
= xmlSchemaParseAttrDecls(ctxt
, schema
, child
, type
);
2640 if (child
!= NULL
) {
2641 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2642 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2643 ctxt
->error(ctxt
->userData
,
2644 "Extension %s has unexpected content\n",
2647 ctxt
->container
= oldcontainer
;
2652 * xmlSchemaParseSimpleContent:
2653 * @ctxt: a schema validation context
2654 * @schema: the schema being built
2655 * @node: a subtree containing XML Schema informations
2657 * parse a XML schema SimpleContent definition
2658 * *WARNING* this interface is highly subject to change
2660 * Returns the type definition or NULL in case of error
2662 static xmlSchemaTypePtr
2663 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
2666 xmlSchemaTypePtr type
, subtype
;
2667 xmlNodePtr child
= NULL
;
2670 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
2674 snprintf((char *)name
, 30, "complexContent %d", ctxt
->counter
++ + 1);
2675 type
= xmlSchemaAddType(ctxt
, schema
, name
);
2679 type
->type
= XML_SCHEMA_TYPE_SIMPLE_CONTENT
;
2680 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
2682 child
= node
->children
;
2683 if (IS_SCHEMA(child
, "annotation")) {
2684 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2685 child
= child
->next
;
2688 if (IS_SCHEMA(child
, "restriction")) {
2689 subtype
= (xmlSchemaTypePtr
)
2690 xmlSchemaParseRestriction(ctxt
, schema
, child
, 0);
2691 child
= child
->next
;
2692 } else if (IS_SCHEMA(child
, "extension")) {
2693 subtype
= (xmlSchemaTypePtr
)
2694 xmlSchemaParseExtension(ctxt
, schema
, child
);
2695 child
= child
->next
;
2697 type
->subtypes
= subtype
;
2698 if (child
!= NULL
) {
2699 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2700 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2701 ctxt
->error(ctxt
->userData
,
2702 "SimpleContent %s has unexpected content\n",
2709 * xmlSchemaParseComplexContent:
2710 * @ctxt: a schema validation context
2711 * @schema: the schema being built
2712 * @node: a subtree containing XML Schema informations
2714 * parse a XML schema ComplexContent definition
2715 * *WARNING* this interface is highly subject to change
2717 * Returns the type definition or NULL in case of error
2719 static xmlSchemaTypePtr
2720 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
2723 xmlSchemaTypePtr type
, subtype
;
2724 xmlNodePtr child
= NULL
;
2727 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
2731 snprintf((char *)name
, 30, "complexContent %d", ctxt
->counter
++ + 1);
2732 type
= xmlSchemaAddType(ctxt
, schema
, name
);
2736 type
->type
= XML_SCHEMA_TYPE_COMPLEX_CONTENT
;
2737 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
2739 child
= node
->children
;
2740 if (IS_SCHEMA(child
, "annotation")) {
2741 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2742 child
= child
->next
;
2745 if (IS_SCHEMA(child
, "restriction")) {
2746 subtype
= (xmlSchemaTypePtr
)
2747 xmlSchemaParseRestriction(ctxt
, schema
, child
, 0);
2748 child
= child
->next
;
2749 } else if (IS_SCHEMA(child
, "extension")) {
2750 subtype
= (xmlSchemaTypePtr
)
2751 xmlSchemaParseExtension(ctxt
, schema
, child
);
2752 child
= child
->next
;
2754 type
->subtypes
= subtype
;
2755 if (child
!= NULL
) {
2756 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2757 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2758 ctxt
->error(ctxt
->userData
,
2759 "ComplexContent %s has unexpected content\n",
2766 * xmlSchemaParseComplexType:
2767 * @ctxt: a schema validation context
2768 * @schema: the schema being built
2769 * @node: a subtree containing XML Schema informations
2771 * parse a XML schema Complex Type definition
2772 * *WARNING* this interface is highly subject to change
2774 * Returns the type definition or NULL in case of error
2776 static xmlSchemaTypePtr
2777 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
2780 xmlSchemaTypePtr type
, subtype
;
2781 xmlNodePtr child
= NULL
;
2783 xmlChar
*oldcontainer
;
2785 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
2788 oldcontainer
= ctxt
->container
;
2789 name
= xmlGetProp(node
, (const xmlChar
*) "name");
2793 snprintf(buf
, 99, "anontype%d", ctxt
->counter
++ + 1);
2794 name
= xmlStrdup((xmlChar
*) buf
);
2797 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2798 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2799 ctxt
->error(ctxt
->userData
, "complexType has no name\n");
2802 type
= xmlSchemaAddType(ctxt
, schema
, name
);
2808 type
->type
= XML_SCHEMA_TYPE_COMPLEX
;
2809 type
->id
= xmlGetProp(node
, BAD_CAST
"id");
2810 ctxt
->container
= name
;
2812 child
= node
->children
;
2813 if (IS_SCHEMA(child
, "annotation")) {
2814 type
->annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2815 child
= child
->next
;
2817 if (IS_SCHEMA(child
, "simpleContent")) {
2818 type
->subtypes
= xmlSchemaParseSimpleContent(ctxt
, schema
, child
);
2819 child
= child
->next
;
2820 } else if (IS_SCHEMA(child
, "complexContent")) {
2821 type
->subtypes
= xmlSchemaParseComplexContent(ctxt
, schema
, child
);
2822 child
= child
->next
;
2826 if (IS_SCHEMA(child
, "all")) {
2827 subtype
= xmlSchemaParseAll(ctxt
, schema
, child
);
2828 child
= child
->next
;
2829 } else if (IS_SCHEMA(child
, "choice")) {
2830 subtype
= xmlSchemaParseChoice(ctxt
, schema
, child
);
2831 child
= child
->next
;
2832 } else if (IS_SCHEMA(child
, "sequence")) {
2833 subtype
= xmlSchemaParseSequence(ctxt
, schema
, child
);
2834 child
= child
->next
;
2835 } else if (IS_SCHEMA(child
, "group")) {
2836 subtype
= xmlSchemaParseGroup(ctxt
, schema
, child
);
2837 child
= child
->next
;
2839 if (subtype
!= NULL
)
2840 type
->subtypes
= subtype
;
2841 child
= xmlSchemaParseAttrDecls(ctxt
, schema
, child
, type
);
2843 if (child
!= NULL
) {
2844 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2845 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2846 ctxt
->error(ctxt
->userData
,
2847 "ComplexType %s has unexpected content\n",
2850 ctxt
->container
= oldcontainer
;
2857 * xmlSchemaParseSchema:
2858 * @ctxt: a schema validation context
2859 * @node: a subtree containing XML Schema informations
2861 * parse a XML schema definition from a node set
2862 * *WARNING* this interface is highly subject to change
2864 * Returns the internal XML Schema structure built from the resource or
2865 * NULL in case of error
2868 xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
)
2870 xmlSchemaPtr schema
= NULL
;
2871 xmlSchemaAnnotPtr annot
;
2872 xmlNodePtr child
= NULL
;
2875 if ((ctxt
== NULL
) || (node
== NULL
))
2878 if (IS_SCHEMA(node
, "schema")) {
2879 schema
= xmlSchemaNewSchema(ctxt
);
2882 schema
->targetNamespace
= xmlGetProp(node
, BAD_CAST
"targetNamespace");
2883 schema
->id
= xmlGetProp(node
, BAD_CAST
"id");
2884 schema
->version
= xmlGetProp(node
, BAD_CAST
"version");
2885 val
= xmlGetProp(node
, BAD_CAST
"elementFormDefault");
2887 if (xmlStrEqual(val
, BAD_CAST
"qualified"))
2888 schema
->flags
|= XML_SCHEMAS_QUALIF_ELEM
;
2889 else if (!xmlStrEqual(val
, BAD_CAST
"unqualified")) {
2890 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2891 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
)) {
2892 ctxt
->error(ctxt
->userData
,
2893 "Invalid value %s for elementFormDefault\n",
2899 val
= xmlGetProp(node
, BAD_CAST
"attributeFormDefault");
2901 if (xmlStrEqual(val
, BAD_CAST
"qualified"))
2902 schema
->flags
|= XML_SCHEMAS_QUALIF_ATTR
;
2903 else if (!xmlStrEqual(val
, BAD_CAST
"unqualified")) {
2904 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2905 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
)) {
2906 ctxt
->error(ctxt
->userData
,
2907 "Invalid value %s for elementFormDefault\n",
2914 child
= node
->children
;
2915 while ((IS_SCHEMA(child
, "include")) ||
2916 (IS_SCHEMA(child
, "import")) ||
2917 (IS_SCHEMA(child
, "redefine")) ||
2918 (IS_SCHEMA(child
, "annotation"))) {
2919 if (IS_SCHEMA(child
, "annotation")) {
2920 annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2921 if (schema
->annot
== NULL
)
2922 schema
->annot
= annot
;
2924 xmlSchemaFreeAnnot(annot
);
2925 } else if (IS_SCHEMA(child
, "include")) {
2927 } else if (IS_SCHEMA(child
, "import")) {
2928 xmlSchemaParseImport(ctxt
, schema
, child
);
2929 } else if (IS_SCHEMA(child
, "redefine")) {
2932 child
= child
->next
;
2934 while (child
!= NULL
) {
2935 if (IS_SCHEMA(child
, "complexType")) {
2936 xmlSchemaParseComplexType(ctxt
, schema
, child
);
2937 child
= child
->next
;
2938 } else if (IS_SCHEMA(child
, "simpleType")) {
2939 xmlSchemaParseSimpleType(ctxt
, schema
, child
);
2940 child
= child
->next
;
2941 } else if (IS_SCHEMA(child
, "element")) {
2942 xmlSchemaParseElement(ctxt
, schema
, child
, 1);
2943 child
= child
->next
;
2944 } else if (IS_SCHEMA(child
, "attribute")) {
2945 xmlSchemaParseAttribute(ctxt
, schema
, child
);
2946 child
= child
->next
;
2947 } else if (IS_SCHEMA(child
, "attributeGroup")) {
2948 xmlSchemaParseAttributeGroup(ctxt
, schema
, child
);
2949 child
= child
->next
;
2950 } else if (IS_SCHEMA(child
, "group")) {
2951 xmlSchemaParseGroup(ctxt
, schema
, child
);
2952 child
= child
->next
;
2953 } else if (IS_SCHEMA(child
, "notation")) {
2954 xmlSchemaParseNotation(ctxt
, schema
, child
);
2955 child
= child
->next
;
2957 xmlSchemaErrorContext(ctxt
, schema
, node
, child
);
2958 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
2959 ctxt
->error(ctxt
->userData
,
2960 "Schemas: unexpected element %s here \n",
2962 child
= child
->next
;
2964 while (IS_SCHEMA(child
, "annotation")) {
2965 annot
= xmlSchemaParseAnnotation(ctxt
, schema
, child
);
2966 if (schema
->annot
== NULL
)
2967 schema
->annot
= annot
;
2969 xmlSchemaFreeAnnot(annot
);
2970 child
= child
->next
;
2976 xmlGenericError(xmlGenericErrorContext
,
2977 "xmlSchemaParse() failed\n");
2983 /************************************************************************
2985 * Validating using Schemas *
2987 ************************************************************************/
2989 /************************************************************************
2991 * Reading/Writing Schemas *
2993 ************************************************************************/
2996 * xmlSchemaNewParserCtxt:
2997 * @URL: the location of the schema
2999 * Create an XML Schemas parse context for that file/resource expected
3000 * to contain an XML Schemas file.
3002 * Returns the parser context or NULL in case of error
3004 xmlSchemaParserCtxtPtr
3005 xmlSchemaNewParserCtxt(const char *URL
) {
3006 xmlSchemaParserCtxtPtr ret
;
3011 ret
= (xmlSchemaParserCtxtPtr
) xmlMalloc(sizeof(xmlSchemaParserCtxt
));
3013 xmlGenericError(xmlGenericErrorContext
,
3014 "Failed to allocate new schama parser context for %s\n", URL
);
3017 memset(ret
, 0, sizeof(xmlSchemaParserCtxt
));
3018 ret
->URL
= xmlStrdup((const xmlChar
*)URL
);
3023 * xmlSchemaNewMemParserCtxt:
3024 * @buffer: a pointer to a char array containing the schemas
3025 * @size: the size of the array
3027 * Create an XML Schemas parse context for that memory buffer expected
3028 * to contain an XML Schemas file.
3030 * Returns the parser context or NULL in case of error
3032 xmlSchemaParserCtxtPtr
3033 xmlSchemaNewMemParserCtxt(const char *buffer
, int size
) {
3034 xmlSchemaParserCtxtPtr ret
;
3036 if ((buffer
== NULL
) || (size
<= 0))
3039 ret
= (xmlSchemaParserCtxtPtr
) xmlMalloc(sizeof(xmlSchemaParserCtxt
));
3041 xmlGenericError(xmlGenericErrorContext
,
3042 "Failed to allocate new schama parser context\n");
3045 memset(ret
, 0, sizeof(xmlSchemaParserCtxt
));
3046 ret
->buffer
= buffer
;
3052 * xmlSchemaFreeParserCtxt:
3053 * @ctxt: the schema parser context
3055 * Free the resources associated to the schema parser context
3058 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt
) {
3061 if (ctxt
->URL
!= NULL
)
3063 if (ctxt
->doc
!= NULL
)
3064 xmlFreeDoc(ctxt
->doc
);
3068 /************************************************************************
3070 * Building the content models *
3072 ************************************************************************/
3074 * xmlSchemaBuildAContentModel:
3075 * @type: the schema type definition
3076 * @ctxt: the schema parser context
3077 * @name: the element name whose content is being built
3079 * Generate the automata sequence needed for that type
3082 xmlSchemaBuildAContentModel(xmlSchemaTypePtr type
,
3083 xmlSchemaParserCtxtPtr ctxt
,
3084 const xmlChar
*name
) {
3086 xmlGenericError(xmlGenericErrorContext
,
3087 "Found unexpected type = NULL in %s content model\n",
3091 switch (type
->type
) {
3092 case XML_SCHEMA_TYPE_ANY
:
3093 /* TODO : handle the namespace too */
3094 /* TODO : make that a specific transition type */
3096 ctxt
->state
= xmlAutomataNewTransition(ctxt
->am
, ctxt
->state
,
3097 NULL
, BAD_CAST
"*", NULL
);
3099 case XML_SCHEMA_TYPE_ELEMENT
: {
3100 xmlSchemaElementPtr elem
= (xmlSchemaElementPtr
) type
;
3101 /* TODO : handle the namespace too */
3102 xmlAutomataStatePtr oldstate
= ctxt
->state
;
3103 if (elem
->maxOccurs
>= UNBOUNDED
) {
3104 if (elem
->minOccurs
> 1) {
3105 xmlAutomataStatePtr tmp
;
3108 ctxt
->state
= xmlAutomataNewEpsilon(ctxt
->am
,
3110 oldstate
= ctxt
->state
;
3112 counter
= xmlAutomataNewCounter(ctxt
->am
,
3113 elem
->minOccurs
- 1, UNBOUNDED
);
3115 if (elem
->refDecl
!= NULL
) {
3116 xmlSchemaBuildAContentModel(
3117 (xmlSchemaTypePtr
) elem
->refDecl
,
3118 ctxt
, elem
->refDecl
->name
);
3120 ctxt
->state
= xmlAutomataNewTransition(ctxt
->am
,
3121 ctxt
->state
, NULL
, elem
->name
, type
);
3124 xmlAutomataNewCountedTrans(ctxt
->am
, tmp
, oldstate
,
3126 ctxt
->state
= xmlAutomataNewCounterTrans(ctxt
->am
, tmp
,
3130 if (elem
->refDecl
!= NULL
) {
3131 xmlSchemaBuildAContentModel(
3132 (xmlSchemaTypePtr
) elem
->refDecl
,
3133 ctxt
, elem
->refDecl
->name
);
3135 ctxt
->state
= xmlAutomataNewTransition(ctxt
->am
,
3136 ctxt
->state
, NULL
, elem
->name
, type
);
3138 xmlAutomataNewEpsilon(ctxt
->am
, ctxt
->state
, oldstate
);
3139 if (elem
->minOccurs
== 0) {
3140 /* basically an elem* */
3141 xmlAutomataNewEpsilon(ctxt
->am
, oldstate
, ctxt
->state
);
3144 } else if ((elem
->maxOccurs
> 1) || (elem
->minOccurs
> 1)) {
3145 xmlAutomataStatePtr tmp
;
3148 ctxt
->state
= xmlAutomataNewEpsilon(ctxt
->am
,
3150 oldstate
= ctxt
->state
;
3152 counter
= xmlAutomataNewCounter(ctxt
->am
,
3153 elem
->minOccurs
- 1, elem
->maxOccurs
- 1);
3155 if (elem
->refDecl
!= NULL
) {
3156 xmlSchemaBuildAContentModel(
3157 (xmlSchemaTypePtr
) elem
->refDecl
,
3158 ctxt
, elem
->refDecl
->name
);
3160 ctxt
->state
= xmlAutomataNewTransition(ctxt
->am
,
3161 ctxt
->state
, NULL
, elem
->name
, type
);
3164 xmlAutomataNewCountedTrans(ctxt
->am
, tmp
, oldstate
,
3166 ctxt
->state
= xmlAutomataNewCounterTrans(ctxt
->am
, tmp
,
3168 if (elem
->minOccurs
== 0) {
3169 /* basically an elem? */
3170 xmlAutomataNewEpsilon(ctxt
->am
, oldstate
, ctxt
->state
);
3174 if (elem
->refDecl
!= NULL
) {
3175 xmlSchemaBuildAContentModel(
3176 (xmlSchemaTypePtr
) elem
->refDecl
,
3177 ctxt
, elem
->refDecl
->name
);
3179 ctxt
->state
= xmlAutomataNewTransition(ctxt
->am
,
3180 ctxt
->state
, NULL
, elem
->name
, type
);
3182 if (elem
->minOccurs
== 0) {
3183 /* basically an elem? */
3184 xmlAutomataNewEpsilon(ctxt
->am
, oldstate
, ctxt
->state
);
3189 case XML_SCHEMA_TYPE_SEQUENCE
: {
3190 xmlSchemaTypePtr subtypes
;
3193 * If max and min occurances are default (1) then
3194 * simply iterate over the subtypes
3196 if ((type
->minOccurs
== 1 ) && (type
->maxOccurs
== 1)) {
3197 subtypes
= type
->subtypes
;
3198 while (subtypes
!= NULL
) {
3199 xmlSchemaBuildAContentModel(subtypes
, ctxt
, name
);
3200 subtypes
= subtypes
->next
;
3203 xmlAutomataStatePtr oldstate
= ctxt
->state
;
3204 if (type
->maxOccurs
>= UNBOUNDED
) {
3205 if (type
->minOccurs
> 1) {
3206 xmlAutomataStatePtr tmp
;
3209 ctxt
->state
= xmlAutomataNewEpsilon(ctxt
->am
,
3211 oldstate
= ctxt
->state
;
3213 counter
= xmlAutomataNewCounter(ctxt
->am
,
3214 type
->minOccurs
- 1, UNBOUNDED
);
3216 subtypes
= type
->subtypes
;
3217 while (subtypes
!= NULL
) {
3218 xmlSchemaBuildAContentModel(subtypes
, ctxt
, name
);
3219 subtypes
= subtypes
->next
;
3222 xmlAutomataNewCountedTrans(ctxt
->am
, tmp
, oldstate
,
3224 ctxt
->state
= xmlAutomataNewCounterTrans(ctxt
->am
, tmp
,
3228 subtypes
= type
->subtypes
;
3229 while (subtypes
!= NULL
) {
3230 xmlSchemaBuildAContentModel(subtypes
, ctxt
, name
);
3231 subtypes
= subtypes
->next
;
3233 xmlAutomataNewEpsilon(ctxt
->am
, ctxt
->state
, oldstate
);
3234 if (type
->minOccurs
== 0) {
3235 xmlAutomataNewEpsilon(ctxt
->am
, oldstate
,
3239 } else if ((type
->maxOccurs
> 1) || (type
->minOccurs
> 1)) {
3240 xmlAutomataStatePtr tmp
;
3243 ctxt
->state
= xmlAutomataNewEpsilon(ctxt
->am
,
3245 oldstate
= ctxt
->state
;
3247 counter
= xmlAutomataNewCounter(ctxt
->am
,
3248 type
->minOccurs
- 1, type
->maxOccurs
- 1);
3250 subtypes
= type
->subtypes
;
3251 while (subtypes
!= NULL
) {
3252 xmlSchemaBuildAContentModel(subtypes
, ctxt
, name
);
3253 subtypes
= subtypes
->next
;
3256 xmlAutomataNewCountedTrans(ctxt
->am
, tmp
, oldstate
,
3258 ctxt
->state
= xmlAutomataNewCounterTrans(ctxt
->am
, tmp
,
3260 if (type
->minOccurs
== 0) {
3261 xmlAutomataNewEpsilon(ctxt
->am
, oldstate
, ctxt
->state
);
3265 subtypes
= type
->subtypes
;
3266 while (subtypes
!= NULL
) {
3267 xmlSchemaBuildAContentModel(subtypes
, ctxt
, name
);
3268 subtypes
= subtypes
->next
;
3270 if (type
->minOccurs
== 0) {
3271 xmlAutomataNewEpsilon(ctxt
->am
, oldstate
, ctxt
->state
);
3277 case XML_SCHEMA_TYPE_CHOICE
: {
3278 xmlSchemaTypePtr subtypes
;
3279 xmlAutomataStatePtr start
, end
;
3281 start
= ctxt
->state
;
3282 end
= xmlAutomataNewState(ctxt
->am
);
3285 * iterate over the subtypes and remerge the end with an
3286 * epsilon transition
3288 if (type
->maxOccurs
== 1) {
3289 subtypes
= type
->subtypes
;
3290 while (subtypes
!= NULL
) {
3291 ctxt
->state
= start
;
3292 xmlSchemaBuildAContentModel(subtypes
, ctxt
, name
);
3293 xmlAutomataNewEpsilon(ctxt
->am
, ctxt
->state
, end
);
3294 subtypes
= subtypes
->next
;
3298 xmlAutomataStatePtr hop
;
3299 int maxOccurs
= type
->maxOccurs
== UNBOUNDED
?
3300 UNBOUNDED
: type
->maxOccurs
- 1;
3301 int minOccurs
= type
->minOccurs
< 1 ? 0 : type
->minOccurs
- 1;
3304 * use a counter to keep track of the number of transtions
3305 * which went through the choice.
3307 counter
= xmlAutomataNewCounter(ctxt
->am
, minOccurs
, maxOccurs
);
3308 hop
= xmlAutomataNewState(ctxt
->am
);
3310 subtypes
= type
->subtypes
;
3311 while (subtypes
!= NULL
) {
3312 ctxt
->state
= start
;
3313 xmlSchemaBuildAContentModel(subtypes
, ctxt
, name
);
3314 xmlAutomataNewEpsilon(ctxt
->am
, ctxt
->state
, hop
);
3315 subtypes
= subtypes
->next
;
3317 xmlAutomataNewCountedTrans(ctxt
->am
, hop
, start
, counter
);
3318 xmlAutomataNewCounterTrans(ctxt
->am
, hop
, end
, counter
);
3320 if (type
->minOccurs
== 0) {
3321 xmlAutomataNewEpsilon(ctxt
->am
, start
, end
);
3326 case XML_SCHEMA_TYPE_ALL
: {
3327 xmlAutomataStatePtr start
;
3328 xmlSchemaTypePtr subtypes
;
3329 xmlSchemaElementPtr elem
= (xmlSchemaElementPtr
) type
;
3332 subtypes
= type
->subtypes
;
3333 if (subtypes
== NULL
)
3335 start
= ctxt
->state
;
3336 while (subtypes
!= NULL
) {
3337 ctxt
->state
= start
;
3338 elem
= (xmlSchemaElementPtr
) subtypes
;
3340 /* TODO : handle the namespace too */
3341 xmlAutomataNewOnceTrans(ctxt
->am
, ctxt
->state
, ctxt
->state
,
3342 elem
->name
, elem
->minOccurs
, elem
->maxOccurs
,
3344 subtypes
= subtypes
->next
;
3346 lax
= type
->minOccurs
== 0;
3347 ctxt
->state
= xmlAutomataNewAllTrans(ctxt
->am
, ctxt
->state
, NULL
,
3351 case XML_SCHEMA_TYPE_RESTRICTION
:
3352 if (type
->subtypes
!= NULL
)
3353 xmlSchemaBuildAContentModel(type
->subtypes
, ctxt
, name
);
3355 case XML_SCHEMA_TYPE_EXTENSION
:
3356 if (type
->baseType
!= NULL
) {
3357 xmlSchemaTypePtr subtypes
;
3359 xmlSchemaBuildAContentModel(type
->baseType
, ctxt
, name
);
3360 subtypes
= type
->subtypes
;
3361 while (subtypes
!= NULL
) {
3362 xmlSchemaBuildAContentModel(subtypes
, ctxt
, name
);
3363 subtypes
= subtypes
->next
;
3365 } else if (type
->subtypes
!= NULL
)
3366 xmlSchemaBuildAContentModel(type
->subtypes
, ctxt
, name
);
3368 case XML_SCHEMA_TYPE_GROUP
:
3369 case XML_SCHEMA_TYPE_COMPLEX
:
3370 case XML_SCHEMA_TYPE_COMPLEX_CONTENT
:
3371 if (type
->subtypes
!= NULL
)
3372 xmlSchemaBuildAContentModel(type
->subtypes
, ctxt
, name
);
3375 xmlGenericError(xmlGenericErrorContext
,
3376 "Found unexpected type %d in %s content model\n",
3382 * xmlSchemaBuildContentModel:
3383 * @typeDecl: the schema type definition
3384 * @ctxt: the schema parser context
3386 * Fixes the content model of the element.
3389 xmlSchemaBuildContentModel(xmlSchemaElementPtr elem
,
3390 xmlSchemaParserCtxtPtr ctxt
,
3391 const xmlChar
*name
) {
3392 xmlAutomataStatePtr start
;
3394 if (elem
->contModel
!= NULL
)
3396 if (elem
->subtypes
== NULL
) {
3397 elem
->contentType
= XML_SCHEMA_CONTENT_ANY
;
3400 if (elem
->subtypes
->type
!= XML_SCHEMA_TYPE_COMPLEX
)
3402 if (elem
->subtypes
->contentType
== XML_SCHEMA_CONTENT_BASIC
)
3405 #ifdef DEBUG_CONTENT
3406 xmlGenericError(xmlGenericErrorContext
,
3407 "Building content model for %s\n", name
);
3410 ctxt
->am
= xmlNewAutomata();
3411 if (ctxt
->am
== NULL
) {
3412 xmlGenericError(xmlGenericErrorContext
,
3413 "Cannot create automata for elem %s\n", name
);
3416 start
= ctxt
->state
= xmlAutomataGetInitState(ctxt
->am
);
3417 xmlSchemaBuildAContentModel(elem
->subtypes
, ctxt
, name
);
3418 xmlAutomataSetFinalState(ctxt
->am
, ctxt
->state
);
3419 elem
->contModel
= xmlAutomataCompile(ctxt
->am
);
3420 if (!xmlAutomataIsDeterminist(ctxt
->am
)) {
3421 xmlGenericError(xmlGenericErrorContext
,
3422 "Content model of %s is not determinist:\n", name
);
3423 ctxt
->err
= XML_SCHEMAS_ERR_NOTDETERMINIST
;
3426 #ifdef DEBUG_CONTENT_REGEXP
3427 xmlGenericError(xmlGenericErrorContext
,
3428 "Content model of %s:\n", name
);
3429 xmlRegexpPrint(stderr
, elem
->contModel
);
3433 xmlFreeAutomata(ctxt
->am
);
3438 * xmlSchemaRefFixupCallback:
3439 * @elem: the schema element context
3440 * @ctxt: the schema parser context
3442 * Free the resources associated to the schema parser context
3445 xmlSchemaRefFixupCallback(xmlSchemaElementPtr elem
,
3446 xmlSchemaParserCtxtPtr ctxt
,
3447 const xmlChar
*name
,
3448 const xmlChar
*context ATTRIBUTE_UNUSED
,
3449 const xmlChar
*namespace ATTRIBUTE_UNUSED
)
3451 if ((ctxt
== NULL
) || (elem
== NULL
))
3453 if (elem
->ref
!= NULL
) {
3454 xmlSchemaElementPtr elemDecl
;
3456 if (elem
->subtypes
!= NULL
) {
3457 xmlSchemaErrorContext(ctxt
, NULL
, elem
->node
, NULL
);
3458 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3459 ctxt
->error(ctxt
->userData
,
3460 "Schemas: element %s have both ref and subtype\n",
3464 elemDecl
= xmlHashLookup2(ctxt
->schema
->elemDecl
,
3465 elem
->ref
, elem
->refNs
);
3467 if (elemDecl
== NULL
) {
3468 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3469 ctxt
->error(ctxt
->userData
,
3470 "Schemas: element %s ref to %s not found\n",
3474 elem
->refDecl
= elemDecl
;
3475 } else if (elem
->namedType
!= NULL
) {
3476 xmlSchemaTypePtr typeDecl
;
3478 if (elem
->subtypes
!= NULL
) {
3479 xmlSchemaErrorContext(ctxt
, NULL
, elem
->node
, NULL
);
3480 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3481 ctxt
->error(ctxt
->userData
,
3482 "Schemas: element %s have both type and subtype\n",
3486 typeDecl
= xmlSchemaGetType(ctxt
->schema
, elem
->namedType
,
3489 if (typeDecl
== NULL
) {
3490 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3491 ctxt
->error(ctxt
->userData
,
3492 "Schemas: element %s type %s not found\n",
3493 name
, elem
->namedType
);
3496 elem
->subtypes
= typeDecl
;
3501 * xmlSchemaTypeFixup:
3502 * @typeDecl: the schema type definition
3503 * @ctxt: the schema parser context
3505 * Fixes the content model of the type.
3508 xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl
,
3509 xmlSchemaParserCtxtPtr ctxt
,
3510 const xmlChar
*name
)
3513 name
= typeDecl
->name
;
3514 if (typeDecl
->contentType
== XML_SCHEMA_CONTENT_UNKNOWN
) {
3515 switch (typeDecl
->type
) {
3516 case XML_SCHEMA_TYPE_SIMPLE_CONTENT
: {
3517 xmlSchemaTypeFixup(typeDecl
->subtypes
, ctxt
, NULL
);
3518 typeDecl
->contentType
= typeDecl
->subtypes
->contentType
;
3521 case XML_SCHEMA_TYPE_RESTRICTION
: {
3522 if (typeDecl
->subtypes
!= NULL
)
3523 xmlSchemaTypeFixup(typeDecl
->subtypes
, ctxt
, NULL
);
3525 if (typeDecl
->base
!= NULL
) {
3526 xmlSchemaTypePtr baseType
;
3528 baseType
= xmlSchemaGetType(ctxt
->schema
, typeDecl
->base
,
3530 if (baseType
== NULL
) {
3531 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3532 ctxt
->error(ctxt
->userData
,
3533 "Schemas: type %s base type %s not found\n",
3534 name
, typeDecl
->base
);
3536 typeDecl
->baseType
= baseType
;
3538 if (typeDecl
->subtypes
== NULL
)
3540 typeDecl
->contentType
= XML_SCHEMA_CONTENT_EMPTY
;
3541 else if ((typeDecl
->subtypes
->subtypes
== NULL
) &&
3542 ((typeDecl
->subtypes
->type
== XML_SCHEMA_TYPE_ALL
) ||
3543 (typeDecl
->subtypes
->type
== XML_SCHEMA_TYPE_SEQUENCE
)))
3545 typeDecl
->contentType
= XML_SCHEMA_CONTENT_EMPTY
;
3546 else if ((typeDecl
->subtypes
->type
== XML_SCHEMA_TYPE_CHOICE
) &&
3547 (typeDecl
->subtypes
->subtypes
== NULL
))
3549 typeDecl
->contentType
= XML_SCHEMA_CONTENT_EMPTY
;
3551 /* 1.2 and 2.X are applied at the other layer */
3552 typeDecl
->contentType
= XML_SCHEMA_CONTENT_ELEMENTS
;
3556 case XML_SCHEMA_TYPE_EXTENSION
: {
3557 xmlSchemaContentType explicitContentType
;
3558 xmlSchemaTypePtr base
;
3560 if (typeDecl
->base
!= NULL
) {
3561 xmlSchemaTypePtr baseType
;
3563 baseType
= xmlSchemaGetType(ctxt
->schema
, typeDecl
->base
,
3565 if (baseType
== NULL
) {
3566 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3567 ctxt
->error(ctxt
->userData
,
3568 "Schemas: type %s base type %s not found\n",
3569 name
, typeDecl
->base
);
3571 typeDecl
->baseType
= baseType
;
3573 if (typeDecl
->subtypes
!= NULL
)
3574 xmlSchemaTypeFixup(typeDecl
->subtypes
, ctxt
, NULL
);
3576 explicitContentType
= XML_SCHEMA_CONTENT_ELEMENTS
;
3577 if (typeDecl
->subtypes
== NULL
)
3579 explicitContentType
= XML_SCHEMA_CONTENT_EMPTY
;
3580 else if ((typeDecl
->subtypes
->subtypes
== NULL
) &&
3581 ((typeDecl
->subtypes
->type
== XML_SCHEMA_TYPE_ALL
) ||
3582 (typeDecl
->subtypes
->type
== XML_SCHEMA_TYPE_SEQUENCE
)))
3584 explicitContentType
= XML_SCHEMA_CONTENT_EMPTY
;
3585 else if ((typeDecl
->subtypes
->type
== XML_SCHEMA_TYPE_CHOICE
) &&
3586 (typeDecl
->subtypes
->subtypes
== NULL
))
3588 explicitContentType
= XML_SCHEMA_CONTENT_EMPTY
;
3590 base
= xmlSchemaGetType(ctxt
->schema
, typeDecl
->base
,
3593 xmlSchemaErrorContext(ctxt
, NULL
, typeDecl
->node
, NULL
);
3594 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3595 ctxt
->error(ctxt
->userData
,
3596 "Schemas: base type %s of type %s not found\n",
3597 typeDecl
->base
, name
);
3600 xmlSchemaTypeFixup(base
, ctxt
, NULL
);
3601 if (explicitContentType
== XML_SCHEMA_CONTENT_EMPTY
) {
3603 typeDecl
->contentType
= base
->contentType
;
3604 } else if (base
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
3605 /* 2.2 imbitable ! */
3606 typeDecl
->contentType
= XML_SCHEMA_CONTENT_ELEMENTS
;
3608 /* 2.3 imbitable pareil ! */
3609 typeDecl
->contentType
= XML_SCHEMA_CONTENT_ELEMENTS
;
3613 case XML_SCHEMA_TYPE_COMPLEX
: {
3614 if (typeDecl
->subtypes
== NULL
) {
3615 typeDecl
->contentType
= XML_SCHEMA_CONTENT_EMPTY
;
3617 if (typeDecl
->flags
& XML_SCHEMAS_TYPE_MIXED
)
3618 typeDecl
->contentType
= XML_SCHEMA_CONTENT_MIXED
;
3620 xmlSchemaTypeFixup(typeDecl
->subtypes
, ctxt
, NULL
);
3621 typeDecl
->contentType
= typeDecl
->subtypes
->contentType
;
3626 case XML_SCHEMA_TYPE_COMPLEX_CONTENT
: {
3627 if (typeDecl
->subtypes
== NULL
) {
3628 typeDecl
->contentType
= XML_SCHEMA_CONTENT_EMPTY
;
3630 if (typeDecl
->flags
& XML_SCHEMAS_TYPE_MIXED
)
3631 typeDecl
->contentType
= XML_SCHEMA_CONTENT_MIXED
;
3633 xmlSchemaTypeFixup(typeDecl
->subtypes
, ctxt
, NULL
);
3634 typeDecl
->contentType
= typeDecl
->subtypes
->contentType
;
3639 case XML_SCHEMA_TYPE_SEQUENCE
:
3640 case XML_SCHEMA_TYPE_GROUP
:
3641 case XML_SCHEMA_TYPE_ALL
:
3642 case XML_SCHEMA_TYPE_CHOICE
:
3643 typeDecl
->contentType
= XML_SCHEMA_CONTENT_ELEMENTS
;
3645 case XML_SCHEMA_TYPE_BASIC
:
3646 case XML_SCHEMA_TYPE_ANY
:
3647 case XML_SCHEMA_TYPE_FACET
:
3648 case XML_SCHEMA_TYPE_SIMPLE
:
3649 case XML_SCHEMA_TYPE_UR
:
3650 case XML_SCHEMA_TYPE_ELEMENT
:
3651 case XML_SCHEMA_TYPE_ATTRIBUTE
:
3652 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
3653 case XML_SCHEMA_TYPE_NOTATION
:
3654 case XML_SCHEMA_TYPE_LIST
:
3655 case XML_SCHEMA_TYPE_UNION
:
3656 case XML_SCHEMA_FACET_MININCLUSIVE
:
3657 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
3658 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
3659 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
3660 case XML_SCHEMA_FACET_TOTALDIGITS
:
3661 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
3662 case XML_SCHEMA_FACET_PATTERN
:
3663 case XML_SCHEMA_FACET_ENUMERATION
:
3664 case XML_SCHEMA_FACET_WHITESPACE
:
3665 case XML_SCHEMA_FACET_LENGTH
:
3666 case XML_SCHEMA_FACET_MAXLENGTH
:
3667 case XML_SCHEMA_FACET_MINLENGTH
:
3668 typeDecl
->contentType
= XML_SCHEMA_CONTENT_SIMPLE
;
3673 if (typeDecl
->node
!= NULL
) {
3674 xmlGenericError(xmlGenericErrorContext
,
3675 "Type of %s : %s:%d :", name
, typeDecl
->node
->doc
->URL
,
3676 xmlGetLineNo(typeDecl
->node
));
3678 xmlGenericError(xmlGenericErrorContext
,
3679 "Type of %s :", name
);
3681 switch (typeDecl
->contentType
) {
3682 case XML_SCHEMA_CONTENT_SIMPLE
:
3683 xmlGenericError(xmlGenericErrorContext
,
3685 case XML_SCHEMA_CONTENT_ELEMENTS
:
3686 xmlGenericError(xmlGenericErrorContext
,
3687 "elements\n"); break;
3688 case XML_SCHEMA_CONTENT_UNKNOWN
:
3689 xmlGenericError(xmlGenericErrorContext
,
3690 "unknown !!!\n"); break;
3691 case XML_SCHEMA_CONTENT_EMPTY
:
3692 xmlGenericError(xmlGenericErrorContext
,
3694 case XML_SCHEMA_CONTENT_MIXED
:
3695 xmlGenericError(xmlGenericErrorContext
,
3697 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS
:
3698 xmlGenericError(xmlGenericErrorContext
,
3699 "mixed or elems\n"); break;
3700 case XML_SCHEMA_CONTENT_BASIC
:
3701 xmlGenericError(xmlGenericErrorContext
,
3704 xmlGenericError(xmlGenericErrorContext
,
3705 "not registered !!!\n"); break;
3711 * xmlSchemaCheckDefaults:
3712 * @typeDecl: the schema type definition
3713 * @ctxt: the schema parser context
3715 * Checks the default values types, especially for facets
3718 xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl
,
3719 xmlSchemaParserCtxtPtr ctxt
,
3720 const xmlChar
*name
)
3722 static xmlSchemaTypePtr nonNegativeIntegerType
= NULL
;
3724 name
= typeDecl
->name
;
3725 if (nonNegativeIntegerType
== NULL
) {
3726 nonNegativeIntegerType
= xmlSchemaGetPredefinedType(
3727 BAD_CAST
"nonNegativeInteger", xmlSchemaNs
);
3729 if (typeDecl
->type
== XML_SCHEMA_TYPE_RESTRICTION
) {
3730 if (typeDecl
->facets
!= NULL
) {
3731 xmlSchemaFacetPtr facet
= typeDecl
->facets
;
3732 while (facet
!= NULL
) {
3733 switch (facet
->type
) {
3734 case XML_SCHEMA_FACET_MININCLUSIVE
:
3735 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
3736 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
3737 case XML_SCHEMA_FACET_MAXEXCLUSIVE
: {
3739 * Okay we need to validate the value
3742 xmlSchemaValidCtxtPtr vctxt
;
3744 vctxt
= xmlSchemaNewValidCtxt(NULL
);
3747 xmlSchemaValidateSimpleValue(vctxt
, typeDecl
,
3749 facet
->val
= vctxt
->value
;
3750 vctxt
->value
= NULL
;
3751 if (facet
->val
== NULL
) {
3753 xmlSchemaErrorContext(ctxt
, NULL
,
3755 ctxt
->error(ctxt
->userData
,
3756 "Schemas: type %s facet value %s invalid\n",
3757 name
, facet
->value
);
3759 xmlSchemaFreeValidCtxt(vctxt
);
3762 case XML_SCHEMA_FACET_ENUMERATION
: {
3764 * Okay we need to validate the value
3767 xmlSchemaValidCtxtPtr vctxt
;
3770 vctxt
= xmlSchemaNewValidCtxt(NULL
);
3773 ret
= xmlSchemaValidateSimpleValue(vctxt
, typeDecl
,
3776 xmlSchemaErrorContext(ctxt
, NULL
,
3778 ctxt
->error(ctxt
->userData
,
3779 "Schemas: type %s enumeration value %s invalid\n",
3780 name
, facet
->value
);
3782 xmlSchemaFreeValidCtxt(vctxt
);
3785 case XML_SCHEMA_FACET_PATTERN
:
3786 facet
->regexp
= xmlRegexpCompile(facet
->value
);
3787 if (facet
->regexp
== NULL
) {
3789 ctxt
->error(ctxt
->userData
,
3790 "Schemas: type %s facet regexp %s invalid\n",
3791 name
, facet
->value
);
3794 case XML_SCHEMA_FACET_TOTALDIGITS
:
3795 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
3796 case XML_SCHEMA_FACET_LENGTH
:
3797 case XML_SCHEMA_FACET_MAXLENGTH
:
3798 case XML_SCHEMA_FACET_MINLENGTH
: {
3801 ret
= xmlSchemaValidatePredefinedType(
3802 nonNegativeIntegerType
, facet
->value
,
3806 xmlSchemaErrorContext(ctxt
, NULL
,
3808 ctxt
->error(ctxt
->userData
,
3809 "Schemas: type %s facet value %s invalid\n",
3810 name
, facet
->value
);
3814 case XML_SCHEMA_FACET_WHITESPACE
: {
3815 if (xmlStrEqual(facet
->value
, BAD_CAST
"preserve")) {
3816 facet
->whitespace
= XML_SCHEMAS_FACET_PRESERVE
;
3817 } else if (xmlStrEqual(facet
->value
,
3818 BAD_CAST
"replace")) {
3819 facet
->whitespace
= XML_SCHEMAS_FACET_REPLACE
;
3820 } else if (xmlStrEqual(facet
->value
,
3821 BAD_CAST
"collapse")) {
3822 facet
->whitespace
= XML_SCHEMAS_FACET_COLLAPSE
;
3824 xmlSchemaErrorContext(ctxt
, NULL
,
3826 ctxt
->error(ctxt
->userData
,
3827 "Schemas: type %s whiteSpace value %s invalid\n",
3828 name
, facet
->value
);
3834 facet
= facet
->next
;
3841 * xmlSchemaAttrGrpFixup:
3842 * @attrgrpDecl: the schema attribute definition
3843 * @ctxt: the schema parser context
3844 * @name: the attribute name
3846 * Fixes finish doing the computations on the attributes definitions
3849 xmlSchemaAttrGrpFixup(xmlSchemaAttributeGroupPtr attrgrpDecl
,
3850 xmlSchemaParserCtxtPtr ctxt
,
3851 const xmlChar
*name
)
3854 name
= attrgrpDecl
->name
;
3855 if (attrgrpDecl
->attributes
!= NULL
)
3857 if (attrgrpDecl
->ref
!= NULL
) {
3858 xmlSchemaAttributeGroupPtr ref
;
3860 ref
= xmlHashLookup2(ctxt
->schema
->attrgrpDecl
, attrgrpDecl
->ref
,
3861 attrgrpDecl
->refNs
);
3863 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3864 ctxt
->error(ctxt
->userData
,
3865 "Schemas: attribute group %s reference %s not found\n",
3866 name
, attrgrpDecl
->ref
);
3869 xmlSchemaAttrGrpFixup(ref
, ctxt
, NULL
);
3870 attrgrpDecl
->attributes
= ref
->attributes
;
3872 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3873 ctxt
->error(ctxt
->userData
,
3874 "Schemas: attribute %s has no attributes nor reference\n",
3880 * xmlSchemaAttrFixup:
3881 * @attrDecl: the schema attribute definition
3882 * @ctxt: the schema parser context
3883 * @name: the attribute name
3885 * Fixes finish doing the computations on the attributes definitions
3888 xmlSchemaAttrFixup(xmlSchemaAttributePtr attrDecl
,
3889 xmlSchemaParserCtxtPtr ctxt
,
3890 const xmlChar
*name
)
3893 name
= attrDecl
->name
;
3894 if (attrDecl
->subtypes
!= NULL
)
3896 if (attrDecl
->typeName
!= NULL
) {
3897 xmlSchemaTypePtr type
;
3899 type
= xmlSchemaGetType(ctxt
->schema
, attrDecl
->typeName
,
3902 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3903 ctxt
->error(ctxt
->userData
,
3904 "Schemas: attribute %s type %s not found\n",
3905 name
, attrDecl
->typeName
);
3907 attrDecl
->subtypes
= type
;
3908 } else if (attrDecl
->ref
!= NULL
) {
3909 xmlSchemaAttributePtr ref
;
3911 ref
= xmlHashLookup2(ctxt
->schema
->attrDecl
, attrDecl
->ref
,
3914 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3915 ctxt
->error(ctxt
->userData
,
3916 "Schemas: attribute %s reference %s not found\n",
3917 name
, attrDecl
->ref
);
3920 xmlSchemaAttrFixup(ref
, ctxt
, NULL
);
3921 attrDecl
->subtypes
= ref
->subtypes
;
3923 if ((ctxt
!= NULL
) && (ctxt
->error
!= NULL
))
3924 ctxt
->error(ctxt
->userData
,
3925 "Schemas: attribute %s has no type nor reference\n",
3932 * @ctxt: a schema validation context
3933 * @URL: the location of the schema
3935 * Load, XML parse a schema definition resource and build an internal
3936 * XML Shema struture which can be used to validate instances.
3937 * *WARNING* this interface is highly subject to change
3939 * Returns the internal XML Schema structure built from the resource or
3940 * NULL in case of error
3943 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt
)
3945 xmlSchemaPtr ret
= NULL
;
3947 xmlNodePtr root
, cur
, delete;
3949 xmlSchemaInitTypes();
3955 ctxt
->container
= NULL
;
3958 * First step is to parse the input document into an DOM/Infoset
3960 if (ctxt
->URL
!= NULL
) {
3961 doc
= xmlParseFile((const char *) ctxt
->URL
);
3963 if (ctxt
->error
!= NULL
)
3964 ctxt
->error(ctxt
->userData
,
3965 "xmlSchemaParse: could not load %s\n", ctxt
->URL
);
3968 } else if (ctxt
->buffer
!= NULL
) {
3969 doc
= xmlParseMemory(ctxt
->buffer
, ctxt
->size
);
3971 if (ctxt
->error
!= NULL
)
3972 ctxt
->error(ctxt
->userData
,
3973 "xmlSchemaParse: could not parse schemas\n");
3976 doc
->URL
= xmlStrdup(BAD_CAST
"in_memory_buffer");
3977 ctxt
->URL
= xmlStrdup(BAD_CAST
"in_memory_buffer");
3979 if (ctxt
->error
!= NULL
)
3980 ctxt
->error(ctxt
->userData
,
3981 "xmlSchemaParse: nothing to parse\n");
3986 * Then extract the root and Schema parse it
3988 root
= xmlDocGetRootElement(doc
);
3990 if (ctxt
->error
!= NULL
)
3991 ctxt
->error(ctxt
->userData
, "xmlSchemaParse: %s is empty\n",
3997 * Remove all the blank text nodes
4001 while (cur
!= NULL
) {
4002 if (delete != NULL
) {
4003 xmlUnlinkNode(delete);
4004 xmlFreeNode(delete);
4007 if (cur
->type
== XML_TEXT_NODE
) {
4008 if (IS_BLANK_NODE(cur
)) {
4009 if (xmlNodeGetSpacePreserve(cur
) != 1) {
4013 } else if ((cur
->type
!= XML_ELEMENT_NODE
) &&
4014 (cur
->type
!= XML_CDATA_SECTION_NODE
)) {
4022 if (cur
->children
!= NULL
) {
4023 if ((cur
->children
->type
!= XML_ENTITY_DECL
) &&
4024 (cur
->children
->type
!= XML_ENTITY_REF_NODE
) &&
4025 (cur
->children
->type
!= XML_ENTITY_NODE
)) {
4026 cur
= cur
->children
;
4031 if (cur
->next
!= NULL
) {
4044 if (cur
->next
!= NULL
) {
4048 } while (cur
!= NULL
);
4050 if (delete != NULL
) {
4051 xmlUnlinkNode(delete);
4052 xmlFreeNode(delete);
4057 * Then do the parsing for good
4059 ret
= xmlSchemaParseSchema(ctxt
, root
);
4065 * Then fix all the references.
4068 xmlHashScanFull(ret
->elemDecl
,
4069 (xmlHashScannerFull
) xmlSchemaRefFixupCallback
, ctxt
);
4072 * Then fixup all types properties
4074 xmlHashScan(ret
->typeDecl
, (xmlHashScanner
) xmlSchemaTypeFixup
, ctxt
);
4077 * Then build the content model for all elements
4079 xmlHashScan(ret
->elemDecl
,
4080 (xmlHashScanner
) xmlSchemaBuildContentModel
, ctxt
);
4083 * Then check the defaults part of the type like facets values
4085 xmlHashScan(ret
->typeDecl
, (xmlHashScanner
) xmlSchemaCheckDefaults
, ctxt
);
4088 * Then fixup all attributes declarations
4090 xmlHashScan(ret
->attrDecl
, (xmlHashScanner
) xmlSchemaAttrFixup
, ctxt
);
4093 * Then fixup all attributes group declarations
4095 xmlHashScan(ret
->attrgrpDecl
, (xmlHashScanner
) xmlSchemaAttrGrpFixup
, ctxt
);
4102 * @ctxt: a schema validation context
4103 * @URL: the location of the schema
4105 * Load, XML parse a schema definition resource and build an internal
4106 * XML Shema struture which can be used to validate instances.
4107 * *WARNING* this interface is highly subject to change
4109 * Returns the internal XML Schema structure built from the resource or
4110 * NULL in case of error
4113 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt
,
4114 xmlSchemaValidityErrorFunc err
,
4115 xmlSchemaValidityWarningFunc warn
, void *ctx
) {
4119 ctxt
->warning
= warn
;
4120 ctxt
->userData
= ctx
;
4123 /************************************************************************
4125 * Simple type validation *
4127 ************************************************************************/
4130 * xmlSchemaValidateSimpleValue:
4131 * @ctxt: a schema validation context
4132 * @type: the type declaration
4133 * @value: the value to validate
4135 * Validate a value against a simple type
4137 * Returns 0 if the value is valid, a positive error code
4138 * number otherwise and -1 in case of internal or API error.
4141 xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt
,
4142 xmlSchemaTypePtr type
,
4146 * First normalize the value accordingly to Schema Datatype
4147 * 4.3.6 whiteSpace definition of the whiteSpace facet of type
4150 * Then check the normalized value against the lexical space of the
4153 if (type
->type
== XML_SCHEMA_TYPE_BASIC
) {
4154 if (ctxt
->value
!= NULL
) {
4155 xmlSchemaFreeValue(ctxt
->value
);
4158 ret
= xmlSchemaValidatePredefinedType(type
, value
, &(ctxt
->value
));
4159 } else if (type
->type
== XML_SCHEMA_TYPE_RESTRICTION
) {
4160 xmlSchemaTypePtr base
;
4161 xmlSchemaFacetPtr facet
;
4164 base
= type
->baseType
;
4166 ret
= xmlSchemaValidateSimpleValue(ctxt
, base
, value
);
4167 } else if (type
->subtypes
!= NULL
) {
4171 * Do not validate facets when working on building the Schemas
4173 if (ctxt
->schema
!= NULL
) {
4175 facet
= type
->facets
;
4176 if ((type
->type
== XML_SCHEMA_TYPE_RESTRICTION
) &&
4178 (facet
->type
== XML_SCHEMA_FACET_ENUMERATION
)) {
4179 while (facet
!= NULL
) {
4182 tmp
= xmlSchemaValidateFacet(base
, facet
, value
,
4188 facet
= facet
->next
;
4191 while (facet
!= NULL
) {
4192 tmp
= xmlSchemaValidateFacet(base
, facet
, value
,
4196 facet
= facet
->next
;
4201 } else if (type
->type
== XML_SCHEMA_TYPE_SIMPLE
) {
4202 xmlSchemaTypePtr base
;
4204 base
= type
->subtypes
;
4206 ret
= xmlSchemaValidateSimpleValue(ctxt
, base
, value
);
4210 } else if (type
->type
== XML_SCHEMA_TYPE_LIST
) {
4211 xmlSchemaTypePtr base
;
4212 xmlChar
*cur
, *end
, tmp
;
4215 base
= type
->subtypes
;
4217 ctxt
->err
= XML_SCHEMAS_ERR_INTERNAL
;
4218 if (ctxt
->error
!= NULL
) {
4219 xmlSchemaErrorContext(NULL
, ctxt
->schema
, type
->node
, NULL
);
4220 ctxt
->error(ctxt
->userData
,
4221 "Internal: List type %s has no base type\n",
4228 while (IS_BLANK(*cur
)) cur
++;
4230 while ((*end
!= 0) && (!(IS_BLANK(*end
)))) end
++;
4235 ret2
= xmlSchemaValidateSimpleValue(ctxt
, base
, cur
);
4240 } while (*cur
!= 0);
4247 /************************************************************************
4249 * DOM Validation code *
4251 ************************************************************************/
4253 static int xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt
,
4255 static int xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt
,
4256 xmlNodePtr elem
, xmlSchemaAttributePtr attributes
);
4257 static int xmlSchemaValidateType(xmlSchemaValidCtxtPtr ctxt
,
4258 xmlNodePtr elem
, xmlSchemaElementPtr elemDecl
, xmlSchemaTypePtr type
);
4261 * xmlSchemaRegisterAttributes:
4262 * @ctxt: a schema validation context
4263 * @attrs: a list of attributes
4265 * Register the list of attributes as the set to be validated on that element
4267 * Returns -1 in case of error, 0 otherwise
4270 xmlSchemaRegisterAttributes(xmlSchemaValidCtxtPtr ctxt
,
4272 while (attrs
!= NULL
) {
4273 if ((attrs
->ns
!= NULL
) &&
4274 (xmlStrEqual(attrs
->ns
->href
, xmlSchemaInstanceNs
))) {
4275 attrs
= attrs
->next
;
4278 if (ctxt
->attrNr
>= ctxt
->attrMax
) {
4279 xmlSchemaAttrStatePtr tmp
;
4282 tmp
= (xmlSchemaAttrStatePtr
)
4283 xmlRealloc(ctxt
->attr
, ctxt
->attrMax
*
4284 sizeof(xmlSchemaAttrState
));
4291 ctxt
->attr
[ctxt
->attrNr
].attr
= attrs
;
4292 ctxt
->attr
[ctxt
->attrNr
].state
= XML_SCHEMAS_ATTR_UNKNOWN
;
4294 attrs
= attrs
->next
;
4300 * xmlSchemaCheckAttributes:
4301 * @ctxt: a schema validation context
4302 * @node: the node carrying it.
4304 * Check that the registered set of attributes on the current node
4305 * has been properly validated.
4307 * Returns 0 if validity constraints are met, 1 otherwise.
4310 xmlSchemaCheckAttributes(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr node
) {
4314 for (i
= ctxt
->attrBase
;i
< ctxt
->attrNr
;i
++) {
4315 if (ctxt
->attr
[i
].attr
== NULL
)
4317 if (ctxt
->attr
[i
].state
== XML_SCHEMAS_ATTR_UNKNOWN
) {
4319 ctxt
->err
= XML_SCHEMAS_ERR_ATTRUNKNOWN
;
4320 if (ctxt
->error
!= NULL
)
4321 ctxt
->error(ctxt
->userData
,
4322 "Attribute %s on %s is unknown\n",
4323 ctxt
->attr
[i
].attr
->name
,
4331 * xmlSchemaValidateSimpleContent:
4332 * @ctxt: a schema validation context
4334 * @type: the type declaration
4336 * Validate the content of an element expected to be a simple type
4338 * Returns 0 if the element is schemas valid, a positive error code
4339 * number otherwise and -1 in case of internal or API error.
4342 xmlSchemaValidateSimpleContent(xmlSchemaValidCtxtPtr ctxt
,
4343 xmlNodePtr node ATTRIBUTE_UNUSED
) {
4345 xmlSchemaTypePtr type
, base
;
4353 * Validation Rule: Element Locally Valid (Type): 3.1.3
4355 value
= xmlNodeGetContent(child
);
4356 /* xmlSchemaValidateSimpleValue(ctxt, type, value); */
4357 switch (type
->type
) {
4358 case XML_SCHEMA_TYPE_RESTRICTION
: {
4359 xmlSchemaFacetPtr facet
;
4361 base
= type
->baseType
;
4363 ret
= xmlSchemaValidateSimpleValue(ctxt
, base
, value
);
4368 facet
= type
->facets
;
4369 while (facet
!= NULL
) {
4370 tmp
= xmlSchemaValidateFacet(base
, facet
, value
,
4374 facet
= facet
->next
;
4389 * xmlSchemaValidateCheckNodeList
4390 * @nodelist: the list of nodes
4392 * Check the node list is only made of text nodes and entities pointing
4395 * Returns 1 if true, 0 if false and -1 in case of error
4398 xmlSchemaValidateCheckNodeList(xmlNodePtr nodelist
) {
4399 while (nodelist
!= NULL
) {
4400 if (nodelist
->type
== XML_ENTITY_REF_NODE
) {
4401 TODO
/* implement recursion in the entity content */
4403 if ((nodelist
->type
!= XML_TEXT_NODE
) &&
4404 (nodelist
->type
!= XML_COMMENT_NODE
) &&
4405 (nodelist
->type
!= XML_PI_NODE
) &&
4406 (nodelist
->type
!= XML_PI_NODE
)) {
4409 nodelist
= nodelist
->next
;
4415 * xmlSchemaSkipIgnored:
4416 * @ctxt: a schema validation context
4417 * @type: the current type context
4418 * @node: the top node.
4420 * Skip ignorable nodes in that context
4422 * Returns the new sibling
4423 * number otherwise and -1 in case of internal or API error.
4426 xmlSchemaSkipIgnored(xmlSchemaValidCtxtPtr ctxt ATTRIBUTE_UNUSED
,
4427 xmlSchemaTypePtr type
,
4431 * TODO complete and handle entities
4433 mixed
= ((type
->contentType
== XML_SCHEMA_CONTENT_MIXED
) ||
4434 (type
->contentType
== XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS
));
4435 while ((node
!= NULL
) &&
4436 ((node
->type
== XML_COMMENT_NODE
) ||
4437 ((mixed
== 1) && (node
->type
== XML_TEXT_NODE
)) ||
4438 (((type
->contentType
== XML_SCHEMA_CONTENT_ELEMENTS
) &&
4439 (node
->type
== XML_TEXT_NODE
) &&
4440 (IS_BLANK_NODE(node
)))))) {
4447 * xmlSchemaValidateCallback:
4448 * @ctxt: a schema validation context
4449 * @name: the name of the element detected (might be NULL)
4452 * A transition has been made in the automata associated to an element
4456 xmlSchemaValidateCallback(xmlSchemaValidCtxtPtr ctxt
,
4457 const xmlChar
*name ATTRIBUTE_UNUSED
,
4458 xmlSchemaTypePtr type
,
4460 xmlSchemaTypePtr oldtype
= ctxt
->type
;
4461 xmlNodePtr oldnode
= ctxt
->node
;
4462 #ifdef DEBUG_CONTENT
4463 xmlGenericError(xmlGenericErrorContext
,
4464 "xmlSchemaValidateCallback: %s, %s, %s\n",
4465 name
, type
->name
, node
->name
);
4469 xmlSchemaValidateContent(ctxt
, node
);
4470 ctxt
->type
= oldtype
;
4471 ctxt
->node
= oldnode
;
4477 * xmlSchemaValidateSimpleRestrictionType:
4478 * @ctxt: a schema validation context
4479 * @node: the top node.
4481 * Validate the content of a restriction type.
4483 * Returns 0 if the element is schemas valid, a positive error code
4484 * number otherwise and -1 in case of internal or API error.
4487 xmlSchemaValidateSimpleRestrictionType(xmlSchemaValidCtxtPtr ctxt
,
4491 xmlSchemaTypePtr type
;
4497 if ((ctxt
== NULL
) || (type
== NULL
)) {
4498 ctxt
->err
= XML_SCHEMAS_ERR_INTERNAL
;
4499 if (ctxt
->error
!= NULL
)
4500 ctxt
->error(ctxt
->userData
,
4501 "Internal error: xmlSchemaValidateSimpleRestrictionType %s\n",
4506 * Only text and text based entities references shall be found there
4508 ret
= xmlSchemaValidateCheckNodeList(child
);
4510 ctxt
->err
= XML_SCHEMAS_ERR_INTERNAL
;
4511 if (ctxt
->error
!= NULL
)
4512 ctxt
->error(ctxt
->userData
,
4513 "Internal error: xmlSchemaValidateSimpleType %s content\n",
4516 } else if (ret
== 0) {
4517 ctxt
->err
= XML_SCHEMAS_ERR_NOTSIMPLE
;
4518 if (ctxt
->error
!= NULL
)
4519 ctxt
->error(ctxt
->userData
,
4520 "Element %s content is not a simple type\n",
4524 ctxt
->type
= type
->subtypes
;
4525 xmlSchemaValidateContent(ctxt
, node
);
4532 * xmlSchemaValidateSimpleType:
4533 * @ctxt: a schema validation context
4534 * @node: the top node.
4536 * Validate the content of an simple type.
4538 * Returns 0 if the element is schemas valid, a positive error code
4539 * number otherwise and -1 in case of internal or API error.
4542 xmlSchemaValidateSimpleType(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr node
) {
4544 xmlSchemaTypePtr type
;
4551 if ((ctxt
== NULL
) || (type
== NULL
)) {
4552 ctxt
->err
= XML_SCHEMAS_ERR_INTERNAL
;
4553 if (ctxt
->error
!= NULL
)
4554 ctxt
->error(ctxt
->userData
,
4555 "Internal error: xmlSchemaValidateSimpleType %s\n",
4560 * Only text and text based entities references shall be found there
4562 ret
= xmlSchemaValidateCheckNodeList(child
);
4564 ctxt
->err
= XML_SCHEMAS_ERR_INTERNAL
;
4565 if (ctxt
->error
!= NULL
)
4566 ctxt
->error(ctxt
->userData
,
4567 "Internal error: xmlSchemaValidateSimpleType %s content\n",
4570 } else if (ret
== 0) {
4571 ctxt
->err
= XML_SCHEMAS_ERR_NOTSIMPLE
;
4572 if (ctxt
->error
!= NULL
)
4573 ctxt
->error(ctxt
->userData
,
4574 "Element %s content is not a simple type\n",
4579 * Validation Rule: Element Locally Valid (Type): 3.1.1
4581 attr
= node
->properties
;
4582 while (attr
!= NULL
) {
4583 if ((attr
->ns
== NULL
) ||
4584 (!xmlStrEqual(attr
->ns
->href
, xmlSchemaInstanceNs
)) ||
4585 ((!xmlStrEqual(attr
->name
, BAD_CAST
"type")) &&
4586 (!xmlStrEqual(attr
->name
, BAD_CAST
"nil")) &&
4587 (!xmlStrEqual(attr
->name
, BAD_CAST
"schemasLocation")) &&
4588 (!xmlStrEqual(attr
->name
, BAD_CAST
"noNamespaceSchemaLocation")))) {
4589 ctxt
->err
= XML_SCHEMAS_ERR_INVALIDATTR
;
4590 if (ctxt
->error
!= NULL
)
4591 ctxt
->error(ctxt
->userData
,
4592 "Element %s: attribute %s should not be present\n",
4593 child
->name
, attr
->name
);
4598 ctxt
->type
= type
->subtypes
;
4599 ret
= xmlSchemaValidateSimpleContent(ctxt
, node
);
4605 * xmlSchemaValidateElementType:
4606 * @ctxt: a schema validation context
4607 * @node: the top node.
4609 * Validate the content of an element type.
4610 * Validation Rule: Element Locally Valid (Complex Type)
4612 * Returns 0 if the element is schemas valid, a positive error code
4613 * number otherwise and -1 in case of internal or API error.
4616 xmlSchemaValidateElementType(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr node
) {
4618 xmlSchemaTypePtr type
;
4619 xmlRegExecCtxtPtr oldregexp
; /* cont model of the parent */
4620 xmlSchemaElementPtr decl
;
4623 oldregexp
= ctxt
->regexp
;
4628 if ((ctxt
== NULL
) || (type
== NULL
)) {
4629 ctxt
->err
= XML_SCHEMAS_ERR_INTERNAL
;
4630 if (ctxt
->error
!= NULL
)
4631 ctxt
->error(ctxt
->userData
,
4632 "Internal error: xmlSchemaValidateElementType\n",
4636 if (child
== NULL
) {
4637 if (type
->minOccurs
> 0) {
4638 ctxt
->err
= XML_SCHEMAS_ERR_MISSING
;
4639 if (ctxt
->error
!= NULL
)
4640 ctxt
->error(ctxt
->userData
,
4641 "Element %s: missing child %s\n",
4642 node
->name
, type
->name
);
4648 * Verify the element matches
4650 if (!xmlStrEqual(child
->name
, type
->name
)) {
4651 ctxt
->err
= XML_SCHEMAS_ERR_WRONGELEM
;
4652 if (ctxt
->error
!= NULL
)
4653 ctxt
->error(ctxt
->userData
,
4654 "Element %s: missing child %s found %s\n",
4655 node
->name
, type
->name
, child
->name
);
4659 * Verify the attributes
4661 attrBase
= ctxt
->attrBase
;
4662 ctxt
->attrBase
= ctxt
->attrNr
;
4663 xmlSchemaRegisterAttributes(ctxt
, child
->properties
);
4664 xmlSchemaValidateAttributes(ctxt
, child
, type
->attributes
);
4666 * Verify the element content recursively
4668 decl
= (xmlSchemaElementPtr
) type
;
4669 oldregexp
= ctxt
->regexp
;
4670 if (decl
->contModel
!= NULL
) {
4671 ctxt
->regexp
= xmlRegNewExecCtxt(decl
->contModel
,
4672 (xmlRegExecCallbacks
) xmlSchemaValidateCallback
,
4674 #ifdef DEBUG_AUTOMATA
4675 xmlGenericError(xmlGenericErrorContext
,
4676 "====> %s\n", node
->name
);
4679 xmlSchemaValidateType(ctxt
, child
, (xmlSchemaElementPtr
)type
,
4682 if (decl
->contModel
!= NULL
) {
4683 ret
= xmlRegExecPushString(ctxt
->regexp
, NULL
, NULL
);
4684 #ifdef DEBUG_AUTOMATA
4685 xmlGenericError(xmlGenericErrorContext
,
4686 "====> %s : %d\n", node
->name
, ret
);
4689 ctxt
->err
= XML_SCHEMAS_ERR_ELEMCONT
;
4690 if (ctxt
->error
!= NULL
)
4691 ctxt
->error(ctxt
->userData
, "Element %s content check failed\n",
4693 } else if (ret
< 0) {
4694 ctxt
->err
= XML_SCHEMAS_ERR_ELEMCONT
;
4695 if (ctxt
->error
!= NULL
)
4696 ctxt
->error(ctxt
->userData
, "Element %s content check failure\n",
4698 #ifdef DEBUG_CONTENT
4700 xmlGenericError(xmlGenericErrorContext
,
4701 "Element %s content check succeeded\n", node
->name
);
4705 xmlRegFreeExecCtxt(ctxt
->regexp
);
4708 * Verify that all attributes were Schemas-validated
4710 xmlSchemaCheckAttributes(ctxt
, node
);
4711 ctxt
->attrNr
= ctxt
->attrBase
;
4712 ctxt
->attrBase
= attrBase
;
4714 ctxt
->regexp
= oldregexp
;
4722 * xmlSchemaValidateBasicType:
4723 * @ctxt: a schema validation context
4724 * @node: the top node.
4726 * Validate the content of an element expected to be a basic type type
4728 * Returns 0 if the element is schemas valid, a positive error code
4729 * number otherwise and -1 in case of internal or API error.
4732 xmlSchemaValidateBasicType(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr node
) {
4734 xmlNodePtr child
, cur
;
4735 xmlSchemaTypePtr type
;
4736 xmlChar
*value
; /* lexical representation */
4741 if ((ctxt
== NULL
) || (type
== NULL
)) {
4742 ctxt
->err
= XML_SCHEMAS_ERR_INTERNAL
;
4743 if (ctxt
->error
!= NULL
)
4744 ctxt
->error(ctxt
->userData
,
4745 "Internal error: xmlSchemaValidateBasicType\n",
4750 * First check the content model of the node.
4753 while (cur
!= NULL
) {
4754 switch (cur
->type
) {
4756 case XML_CDATA_SECTION_NODE
:
4758 case XML_COMMENT_NODE
:
4759 case XML_XINCLUDE_START
:
4760 case XML_XINCLUDE_END
:
4762 case XML_ENTITY_REF_NODE
:
4763 case XML_ENTITY_NODE
:
4766 case XML_ELEMENT_NODE
:
4767 ctxt
->err
= XML_SCHEMAS_ERR_INVALIDELEM
;
4768 if (ctxt
->error
!= NULL
)
4769 ctxt
->error(ctxt
->userData
,
4770 "Element %s: child %s should not be present\n",
4771 node
->name
, cur
->name
);
4773 case XML_ATTRIBUTE_NODE
:
4774 case XML_DOCUMENT_NODE
:
4775 case XML_DOCUMENT_TYPE_NODE
:
4776 case XML_DOCUMENT_FRAG_NODE
:
4777 case XML_NOTATION_NODE
:
4778 case XML_HTML_DOCUMENT_NODE
:
4780 case XML_ELEMENT_DECL
:
4781 case XML_ATTRIBUTE_DECL
:
4782 case XML_ENTITY_DECL
:
4783 case XML_NAMESPACE_DECL
:
4784 #ifdef LIBXML_DOCB_ENABLED
4785 case XML_DOCB_DOCUMENT_NODE
:
4787 ctxt
->err
= XML_SCHEMAS_ERR_INVALIDELEM
;
4788 if (ctxt
->error
!= NULL
)
4789 ctxt
->error(ctxt
->userData
,
4790 "Element %s: node type %d unexpected here\n",
4791 node
->name
, cur
->type
);
4799 value
= xmlNodeGetContent(child
->parent
);
4801 if (ctxt
->value
!= NULL
) {
4802 xmlSchemaFreeValue(ctxt
->value
);
4805 ret
= xmlSchemaValidatePredefinedType(type
, value
, &(ctxt
->value
));
4809 ctxt
->error(ctxt
->userData
,
4810 "Element %s: failed to validate basic type %s\n",
4811 node
->name
, type
->name
);
4817 * xmlSchemaValidateComplexType:
4818 * @ctxt: a schema validation context
4819 * @node: the top node.
4821 * Validate the content of an element expected to be a complex type type
4822 * xmlschema-1.html#cvc-complex-type
4823 * Validation Rule: Element Locally Valid (Complex Type)
4825 * Returns 0 if the element is schemas valid, a positive error code
4826 * number otherwise and -1 in case of internal or API error.
4829 xmlSchemaValidateComplexType(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr node
) {
4831 xmlSchemaTypePtr type
, subtype
;
4837 switch (type
->contentType
) {
4838 case XML_SCHEMA_CONTENT_EMPTY
:
4839 if (child
!= NULL
) {
4840 if (ctxt
->error
!= NULL
)
4841 ctxt
->error(ctxt
->userData
,
4842 "Element %s is supposed to be empty\n",
4845 if (type
->attributes
!= NULL
) {
4846 xmlSchemaValidateAttributes(ctxt
, node
, type
->attributes
);
4848 subtype
= type
->subtypes
;
4849 while (subtype
!= NULL
) {
4850 ctxt
->type
= subtype
;
4851 xmlSchemaValidateComplexType(ctxt
, node
);
4852 subtype
= subtype
->next
;
4855 case XML_SCHEMA_CONTENT_ELEMENTS
:
4856 case XML_SCHEMA_CONTENT_MIXED
:
4857 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS
:
4859 * Skip ignorable nodes in that context
4861 child
= xmlSchemaSkipIgnored(ctxt
, type
, child
);
4862 while (child
!= NULL
) {
4863 if (child
->type
== XML_ELEMENT_NODE
) {
4864 ret
= xmlRegExecPushString(ctxt
->regexp
,
4865 child
->name
, child
);
4866 #ifdef DEBUG_AUTOMATA
4868 xmlGenericError(xmlGenericErrorContext
,
4869 " --> %s Error\n", child
->name
);
4871 xmlGenericError(xmlGenericErrorContext
,
4872 " --> %s\n", child
->name
);
4875 child
= child
->next
;
4877 * Skip ignorable nodes in that context
4879 child
= xmlSchemaSkipIgnored(ctxt
, type
, child
);
4882 case XML_SCHEMA_CONTENT_BASIC
: {
4883 if (type
->subtypes
!= NULL
) {
4884 ctxt
->type
= type
->subtypes
;
4885 xmlSchemaValidateComplexType(ctxt
, node
);
4887 if (type
->baseType
!= NULL
) {
4888 ctxt
->type
= type
->baseType
;
4889 xmlSchemaValidateBasicType(ctxt
, node
);
4891 if (type
->attributes
!= NULL
) {
4892 xmlSchemaValidateAttributes(ctxt
, node
, type
->attributes
);
4899 xmlGenericError(xmlGenericErrorContext
,
4900 "unimplemented content type %d\n",
4907 * xmlSchemaValidateContent:
4908 * @ctxt: a schema validation context
4910 * @type: the type declaration
4912 * Validate the content of an element against the type.
4914 * Returns 0 if the element is schemas valid, a positive error code
4915 * number otherwise and -1 in case of internal or API error.
4918 xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr node
) {
4920 xmlSchemaTypePtr type
;
4925 xmlSchemaValidateAttributes(ctxt
, node
, type
->attributes
);
4927 switch (type
->type
) {
4928 case XML_SCHEMA_TYPE_ANY
:
4929 /* Any type will do it, fine */
4930 TODO
/* handle recursivity */
4932 case XML_SCHEMA_TYPE_COMPLEX
:
4933 xmlSchemaValidateComplexType(ctxt
, node
);
4935 case XML_SCHEMA_TYPE_ELEMENT
: {
4936 xmlSchemaElementPtr decl
= (xmlSchemaElementPtr
) type
;
4938 * Handle element reference here
4940 if (decl
->ref
!= NULL
) {
4941 if (decl
->refDecl
== NULL
) {
4942 ctxt
->err
= XML_SCHEMAS_ERR_INTERNAL
;
4943 if (ctxt
->error
!= NULL
)
4944 ctxt
->error(ctxt
->userData
,
4945 "Internal error: element reference %s not resolved\n",
4949 ctxt
->type
= (xmlSchemaTypePtr
) decl
->refDecl
;
4950 decl
= decl
->refDecl
;
4952 xmlSchemaValidateElementType(ctxt
, node
);
4956 case XML_SCHEMA_TYPE_BASIC
:
4957 xmlSchemaValidateBasicType(ctxt
, node
);
4959 case XML_SCHEMA_TYPE_FACET
:
4962 case XML_SCHEMA_TYPE_SIMPLE
:
4963 xmlSchemaValidateSimpleType(ctxt
, node
);
4965 case XML_SCHEMA_TYPE_SEQUENCE
:
4968 case XML_SCHEMA_TYPE_CHOICE
:
4971 case XML_SCHEMA_TYPE_ALL
:
4974 case XML_SCHEMA_TYPE_SIMPLE_CONTENT
:
4977 case XML_SCHEMA_TYPE_COMPLEX_CONTENT
:
4980 case XML_SCHEMA_TYPE_UR
:
4983 case XML_SCHEMA_TYPE_RESTRICTION
:
4984 /*xmlSchemaValidateRestrictionType(ctxt, node); */
4987 case XML_SCHEMA_TYPE_EXTENSION
:
4990 case XML_SCHEMA_TYPE_ATTRIBUTE
:
4993 case XML_SCHEMA_TYPE_GROUP
:
4996 case XML_SCHEMA_TYPE_NOTATION
:
4999 case XML_SCHEMA_TYPE_LIST
:
5002 case XML_SCHEMA_TYPE_UNION
:
5005 case XML_SCHEMA_FACET_MININCLUSIVE
:
5008 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
5011 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
5014 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
5017 case XML_SCHEMA_FACET_TOTALDIGITS
:
5020 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
5023 case XML_SCHEMA_FACET_PATTERN
:
5026 case XML_SCHEMA_FACET_ENUMERATION
:
5029 case XML_SCHEMA_FACET_WHITESPACE
:
5032 case XML_SCHEMA_FACET_LENGTH
:
5035 case XML_SCHEMA_FACET_MAXLENGTH
:
5038 case XML_SCHEMA_FACET_MINLENGTH
:
5041 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
5045 xmlSchemaValidateAttributes(ctxt
, node
, type
->attributes
);
5047 if (ctxt
->node
== NULL
)
5049 ctxt
->node
= ctxt
->node
->next
;
5050 ctxt
->type
= type
->next
;
5055 * xmlSchemaValidateType:
5056 * @ctxt: a schema validation context
5058 * @type: the list of type declarations
5060 * Validate the content of an element against the types.
5062 * Returns 0 if the element is schemas valid, a positive error code
5063 * number otherwise and -1 in case of internal or API error.
5066 xmlSchemaValidateType(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr elem
,
5067 xmlSchemaElementPtr elemDecl
,
5068 xmlSchemaTypePtr type
) {
5071 if ((elem
->content
== NULL
) || (type
== NULL
) || (elemDecl
== NULL
))
5076 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
) {
5077 ctxt
->err
= XML_SCHEMAS_ERR_ISABSTRACT
;
5078 if (ctxt
->error
!= NULL
)
5079 ctxt
->error(ctxt
->userData
, "Element %s is abstract\n", elem
->name
);
5085 nil
= xmlGetNsProp(elem
, BAD_CAST
"nil", xmlSchemaInstanceNs
);
5086 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_NILLABLE
) {
5088 if (xmlStrEqual(nil
, BAD_CAST
"true")) {
5089 if (elem
->children
!= NULL
) {
5090 ctxt
->err
= XML_SCHEMAS_ERR_NOTEMPTY
;
5091 if (ctxt
->error
!= NULL
)
5092 ctxt
->error(ctxt
->userData
, "Element %s is not empty\n",
5096 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_FIXED
) &&
5097 (elemDecl
->value
!= NULL
)) {
5098 ctxt
->err
= XML_SCHEMAS_ERR_HAVEDEFAULT
;
5099 if (ctxt
->error
!= NULL
)
5100 ctxt
->error(ctxt
->userData
,
5101 "Empty element %s cannot get a fixed value\n",
5109 ctxt
->err
= XML_SCHEMAS_ERR_NOTNILLABLE
;
5110 if (ctxt
->error
!= NULL
)
5111 ctxt
->error(ctxt
->userData
,
5112 "Element %s with xs:nil but not nillable\n",
5119 /* TODO 3.3.4: 4 if the element carries xs:type*/
5121 ctxt
->type
= elemDecl
->subtypes
;
5122 ctxt
->node
= elem
->children
;
5123 xmlSchemaValidateContent(ctxt
, elem
);
5124 xmlSchemaValidateAttributes(ctxt
, elem
, elemDecl
->attributes
);
5131 * xmlSchemaValidateAttributes:
5132 * @ctxt: a schema validation context
5134 * @attributes: the list of attribute declarations
5136 * Validate the attributes of an element.
5138 * Returns 0 if the element is schemas valid, a positive error code
5139 * number otherwise and -1 in case of internal or API error.
5142 xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr elem
,
5143 xmlSchemaAttributePtr attributes
) {
5147 xmlSchemaAttributeGroupPtr group
= NULL
;
5149 if (attributes
== NULL
)
5151 while (attributes
!= NULL
) {
5153 * Handle attribute groups
5155 if (attributes
->type
== XML_SCHEMA_TYPE_ATTRIBUTEGROUP
) {
5156 group
= (xmlSchemaAttributeGroupPtr
) attributes
;
5157 xmlSchemaValidateAttributes(ctxt
, elem
, group
->attributes
);
5158 attributes
= group
->next
;
5161 for (i
= ctxt
->attrBase
;i
< ctxt
->attrNr
;i
++) {
5162 attr
= ctxt
->attr
[i
].attr
;
5165 if (!xmlStrEqual(attr
->name
, attributes
->name
))
5168 * TODO: handle the mess about namespaces here.
5170 if ((attr
->ns
!= NULL
) /* || (attributes->ns != NULL) */) {
5173 if (attributes
->subtypes
== NULL
) {
5174 ctxt
->err
= XML_SCHEMAS_ERR_INTERNAL
;
5175 if (ctxt
->error
!= NULL
)
5176 ctxt
->error(ctxt
->userData
,
5177 "Internal error: attribute %s type not resolved\n",
5181 value
= xmlNodeListGetString(elem
->doc
, attr
->children
, 1);
5182 ret
= xmlSchemaValidateSimpleValue(ctxt
, attributes
->subtypes
,
5185 ctxt
->err
= XML_SCHEMAS_ERR_ATTRINVALID
;
5186 if (ctxt
->error
!= NULL
)
5187 ctxt
->error(ctxt
->userData
,
5188 "attribute %s on %s does not match type\n",
5189 attr
->name
, elem
->name
);
5191 ctxt
->attr
[i
].state
= XML_SCHEMAS_ATTR_CHECKED
;
5193 if (value
!= NULL
) {
5197 attributes
= attributes
->next
;
5203 * xmlSchemaValidateElement:
5204 * @ctxt: a schema validation context
5207 * Validate an element in a tree
5209 * Returns 0 if the element is schemas valid, a positive error code
5210 * number otherwise and -1 in case of internal or API error.
5213 xmlSchemaValidateElement(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr elem
) {
5214 xmlSchemaElementPtr elemDecl
;
5217 if (elem
->ns
!= NULL
)
5218 elemDecl
= xmlHashLookup3(ctxt
->schema
->elemDecl
,
5219 elem
->name
, elem
->ns
->href
, NULL
);
5221 elemDecl
= xmlHashLookup3(ctxt
->schema
->elemDecl
,
5222 elem
->name
, NULL
, NULL
);
5226 if (elemDecl
== NULL
) {
5227 ctxt
->err
= XML_SCHEMAS_ERR_UNDECLAREDELEM
;
5228 if (ctxt
->error
!= NULL
)
5229 ctxt
->error(ctxt
->userData
, "Element %s not declared\n",
5233 if (elemDecl
->subtypes
== NULL
) {
5234 ctxt
->err
= XML_SCHEMAS_ERR_NOTYPE
;
5235 if (ctxt
->error
!= NULL
)
5236 ctxt
->error(ctxt
->userData
, "Element %s has no type\n",
5241 * Verify the attributes
5243 attrBase
= ctxt
->attrBase
;
5244 ctxt
->attrBase
= ctxt
->attrNr
;
5245 xmlSchemaRegisterAttributes(ctxt
, elem
->properties
);
5246 xmlSchemaValidateAttributes(ctxt
, elem
, elemDecl
->attributes
);
5248 * Verify the element content recursively
5250 if (elemDecl
->contModel
!= NULL
) {
5251 ctxt
->regexp
= xmlRegNewExecCtxt(elemDecl
->contModel
,
5252 (xmlRegExecCallbacks
) xmlSchemaValidateCallback
,
5254 #ifdef DEBUG_AUTOMATA
5255 xmlGenericError(xmlGenericErrorContext
,
5256 "====> %s\n", elem
->name
);
5259 xmlSchemaValidateType(ctxt
, elem
, elemDecl
, elemDecl
->subtypes
);
5260 if (elemDecl
->contModel
!= NULL
) {
5261 ret
= xmlRegExecPushString(ctxt
->regexp
, NULL
, NULL
);
5262 #ifdef DEBUG_AUTOMATA
5263 xmlGenericError(xmlGenericErrorContext
,
5264 "====> %s : %d\n", elem
->name
, ret
);
5267 ctxt
->err
= XML_SCHEMAS_ERR_ELEMCONT
;
5268 if (ctxt
->error
!= NULL
)
5269 ctxt
->error(ctxt
->userData
, "Element %s content check failed\n",
5271 } else if (ret
< 0) {
5272 ctxt
->err
= XML_SCHEMAS_ERR_ELEMCONT
;
5273 if (ctxt
->error
!= NULL
)
5274 ctxt
->error(ctxt
->userData
, "Element %s content check failed\n",
5276 #ifdef DEBUG_CONTENT
5278 xmlGenericError(xmlGenericErrorContext
,
5279 "Element %s content check succeeded\n", elem
->name
);
5283 xmlRegFreeExecCtxt(ctxt
->regexp
);
5286 * Verify that all attributes were Schemas-validated
5288 xmlSchemaCheckAttributes(ctxt
, elem
);
5289 ctxt
->attrNr
= ctxt
->attrBase
;
5290 ctxt
->attrBase
= attrBase
;
5296 * xmlSchemaValidateDocument:
5297 * @ctxt: a schema validation context
5298 * @doc: a parsed document tree
5300 * Validate a document tree in memory.
5302 * Returns 0 if the document is schemas valid, a positive error code
5303 * number otherwise and -1 in case of internal or API error.
5306 xmlSchemaValidateDocument(xmlSchemaValidCtxtPtr ctxt
, xmlDocPtr doc
) {
5308 xmlSchemaElementPtr elemDecl
;
5310 root
= xmlDocGetRootElement(doc
);
5312 ctxt
->err
= XML_SCHEMAS_ERR_NOROOT
;
5313 if (ctxt
->error
!= NULL
)
5314 ctxt
->error(ctxt
->userData
, "document has no root\n");
5317 if (root
->ns
!= NULL
)
5318 elemDecl
= xmlHashLookup3(ctxt
->schema
->elemDecl
,
5319 root
->name
, root
->ns
->href
, NULL
);
5321 elemDecl
= xmlHashLookup3(ctxt
->schema
->elemDecl
,
5322 root
->name
, NULL
, NULL
);
5323 if (elemDecl
== NULL
) {
5324 ctxt
->err
= XML_SCHEMAS_ERR_UNDECLAREDELEM
;
5325 if (ctxt
->error
!= NULL
)
5326 ctxt
->error(ctxt
->userData
, "Element %s not declared\n",
5328 } else if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_TOPLEVEL
) == 0) {
5329 ctxt
->err
= XML_SCHEMAS_ERR_NOTTOPLEVEL
;
5330 if (ctxt
->error
!= NULL
)
5331 ctxt
->error(ctxt
->userData
, "Root element %s not toplevel\n",
5335 * Okay, start the recursive validation
5337 xmlSchemaValidateElement(ctxt
, root
);
5342 /************************************************************************
5344 * SAX Validation code *
5346 ************************************************************************/
5348 /************************************************************************
5350 * Validation interfaces *
5352 ************************************************************************/
5355 * xmlSchemaNewValidCtxt:
5356 * @schema: a precompiled XML Schemas
5358 * Create an XML Schemas validation context based on the given schema
5360 * Returns the validation context or NULL in case of error
5362 xmlSchemaValidCtxtPtr
5363 xmlSchemaNewValidCtxt(xmlSchemaPtr schema
) {
5364 xmlSchemaValidCtxtPtr ret
;
5366 ret
= (xmlSchemaValidCtxtPtr
) xmlMalloc(sizeof(xmlSchemaValidCtxt
));
5368 xmlGenericError(xmlGenericErrorContext
,
5369 "Failed to allocate new schama validation context\n");
5372 memset(ret
, 0, sizeof(xmlSchemaValidCtxt
));
5373 ret
->schema
= schema
;
5376 ret
->attr
= (xmlSchemaAttrStatePtr
) xmlMalloc(ret
->attrMax
*
5377 sizeof(xmlSchemaAttrState
));
5378 if (ret
->attr
== NULL
) {
5382 memset(ret
->attr
, 0, ret
->attrMax
* sizeof(xmlSchemaAttrState
));
5387 * xmlSchemaFreeValidCtxt:
5388 * @ctxt: the schema validation context
5390 * Free the resources associated to the schema validation context
5393 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt
) {
5396 if (ctxt
->attr
!= NULL
)
5397 xmlFree(ctxt
->attr
);
5398 if (ctxt
->value
!= NULL
)
5399 xmlSchemaFreeValue(ctxt
->value
);
5404 * xmlSchemaSetValidErrors:
5405 * @ctxt: a schema validation context
5406 * @err: the error function
5407 * @warn: the warning function
5408 * @ctxt: the functions context
5410 * Set the error and warning callback informations
5413 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt
,
5414 xmlSchemaValidityErrorFunc err
,
5415 xmlSchemaValidityWarningFunc warn
, void *ctx
) {
5419 ctxt
->warning
= warn
;
5420 ctxt
->userData
= ctx
;
5424 * xmlSchemaValidateDoc:
5425 * @ctxt: a schema validation context
5426 * @doc: a parsed document tree
5428 * Validate a document tree in memory.
5430 * Returns 0 if the document is schemas valid, a positive error code
5431 * number otherwise and -1 in case of internal or API error.
5434 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt
, xmlDocPtr doc
) {
5437 if ((ctxt
== NULL
) || (doc
== NULL
))
5441 ret
= xmlSchemaValidateDocument(ctxt
, doc
);
5446 * xmlSchemaValidateStream:
5447 * @ctxt: a schema validation context
5448 * @input: the input to use for reading the data
5449 * @enc: an optional encoding information
5450 * @sax: a SAX handler for the resulting events
5451 * @user_data: the context to provide to the SAX handler.
5453 * Validate a document tree in memory.
5455 * Returns 0 if the document is schemas valid, a positive error code
5456 * number otherwise and -1 in case of internal or API error.
5459 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt
,
5460 xmlParserInputBufferPtr input
, xmlCharEncoding enc
,
5461 xmlSAXHandlerPtr sax
, void *user_data
) {
5462 if ((ctxt
== NULL
) || (input
== NULL
))
5464 ctxt
->input
= input
;
5467 ctxt
->user_data
= user_data
;
5472 #endif /* LIBXML_SCHEMAS_ENABLED */