fixed validation of attribute groups. added an example from the primer
* xmlschemas.c: fixed validation of attribute groups.
* test/schemas result/schemas: added an example from the primer
Daniel
diff --git a/ChangeLog b/ChangeLog
index 661a51c..5160be6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Apr 23 19:50:40 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+ * xmlschemas.c: fixed validation of attribute groups.
+ * test/schemas result/schemas: added an example from the primer
+
Tue Apr 23 09:11:37 CEST 2002 Daniel Veillard <daniel@veillard.com>
* Makefile.am xmlschemas.c xmlschemastypes.c: more work on Schemas
diff --git a/include/libxml/schemasInternals.h b/include/libxml/schemasInternals.h
index e59e157..bb8c9a4 100644
--- a/include/libxml/schemasInternals.h
+++ b/include/libxml/schemasInternals.h
@@ -44,6 +44,7 @@
XML_SCHEMA_TYPE_EXTENSION,
XML_SCHEMA_TYPE_ELEMENT,
XML_SCHEMA_TYPE_ATTRIBUTE,
+ XML_SCHEMA_TYPE_ATTRIBUTEGROUP,
XML_SCHEMA_TYPE_GROUP,
XML_SCHEMA_TYPE_NOTATION,
XML_SCHEMA_TYPE_LIST,
diff --git a/result/schemas/item_1_0 b/result/schemas/item_1_0
new file mode 100644
index 0000000..90fa561
--- /dev/null
+++ b/result/schemas/item_1_0
@@ -0,0 +1 @@
+./test/schemas/item_0.xml validates
diff --git a/result/schemas/item_1_0.err b/result/schemas/item_1_0.err
new file mode 100644
index 0000000..1c5674e
--- /dev/null
+++ b/result/schemas/item_1_0.err
@@ -0,0 +1,39 @@
+Type of sequence 3 : ./test/schemas/item_1.xsd:12 :elements
+Type of restriction 5 : ./test/schemas/item_1.xsd:16 :empty
+Type of simpletype4 : ./test/schemas/item_1.xsd:15 :simple
+Type of SKU : ./test/schemas/item_1.xsd:5 :simple
+Type of restriction 9 : ./test/schemas/item_1.xsd:34 :empty
+Type of simpletype8 : ./test/schemas/item_1.xsd:33 :simple
+Type of restriction 1 : ./test/schemas/item_1.xsd:6 :empty
+Type of sequence 3 : ./test/schemas/item_1.xsd:12 :elements
+Type of anontype2 : ./test/schemas/item_1.xsd:11 :elements
+Building content model for Item
+Content model of Item:
+ regexp: '(null)'
+5 atoms:
+ 00 atom: string once 'productName'
+ 01 atom: string once 'quantity'
+ 02 atom: string once 'USPrice'
+ 03 atom: string once 'comment'
+ 04 atom: string once 'shipDate'
+6 states:
+ state: 0, 1 transitions:
+ trans: atom 0, to 1
+ state: 1, 1 transitions:
+ trans: atom 1, to 2
+ state: 2, 1 transitions:
+ trans: atom 2, to 3
+ state: FINAL 3, 3 transitions:
+ trans: atom 3, to 4
+ trans: removed
+ trans: atom 4, to 5
+ state: FINAL 4, 2 transitions:
+ trans: atom 4, to 5
+ trans: removed
+ state: FINAL 5, 0 transitions:
+0 counters:
+xmlSchemaValidateCallback: productName, productName, productName
+xmlSchemaValidateCallback: quantity, quantity, quantity
+xmlSchemaValidateCallback: USPrice, USPrice, USPrice
+xmlSchemaValidateCallback: comment, comment, comment
+Element Item content check succeeded
diff --git a/test/schemas/item_1.xsd b/test/schemas/item_1.xsd
new file mode 100644
index 0000000..cea1f01
--- /dev/null
+++ b/test/schemas/item_1.xsd
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:element name="comment" type="xsd:string"/>
+<!-- Stock Keeping Unit, a code for identifying products -->
+ <xsd:simpleType name="SKU">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="\d{3}-[A-Z]{2}"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:element name="Item" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="productName" type="xsd:string"/>
+ <xsd:element name="quantity">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:positiveInteger">
+ <xsd:maxExclusive value="100"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+ <xsd:element name="USPrice" type="xsd:decimal"/>
+ <xsd:element ref="comment" minOccurs="0"/>
+ <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
+ </xsd:sequence>
+<!-- attributeGroup replaces individual declarations -->
+ <xsd:attributeGroup ref="ItemDelivery"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:attributeGroup name="ItemDelivery">
+ <xsd:attribute name="partNum" type="SKU" use="required"/>
+ <xsd:attribute name="weightKg" type="xsd:decimal"/>
+ <xsd:attribute name="shipBy">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="air"/>
+ <xsd:enumeration value="land"/>
+ <xsd:enumeration value="any"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:attributeGroup>
+</xsd:schema>
diff --git a/xmlschemas.c b/xmlschemas.c
index 86359ce..38b92d3 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -1662,6 +1662,7 @@
}
ret->ref = ref;
ret->refNs = refNs;
+ ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
child = node->children;
ctxt->container = name;
if (IS_SCHEMA(child, "annotation")) {
@@ -3554,6 +3555,45 @@
}
/**
+ * xmlSchemaAttrGrpFixup:
+ * @attrgrpDecl: the schema attribute definition
+ * @ctxt: the schema parser context
+ * @name: the attribute name
+ *
+ * Fixes finish doing the computations on the attributes definitions
+ */
+static void
+xmlSchemaAttrGrpFixup(xmlSchemaAttributeGroupPtr attrgrpDecl,
+ xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar *name)
+{
+ if (name == NULL)
+ name = attrgrpDecl->name;
+ if (attrgrpDecl->attributes != NULL)
+ return;
+ if (attrgrpDecl->ref != NULL) {
+ xmlSchemaAttributeGroupPtr ref;
+
+ ref = xmlHashLookup2(ctxt->schema->attrgrpDecl, attrgrpDecl->ref,
+ attrgrpDecl->refNs);
+ if (ref == NULL) {
+ if ((ctxt != NULL) && (ctxt->error != NULL))
+ ctxt->error(ctxt->userData,
+ "Schemas: attribute group %s reference %s not found\n",
+ name, attrgrpDecl->ref);
+ return;
+ }
+ xmlSchemaAttrGrpFixup(ref, ctxt, NULL);
+ attrgrpDecl->attributes = ref->attributes;
+ } else {
+ if ((ctxt != NULL) && (ctxt->error != NULL))
+ ctxt->error(ctxt->userData,
+ "Schemas: attribute %s has no attributes nor reference\n",
+ name);
+ }
+}
+
+/**
* xmlSchemaAttrFixup:
* @attrDecl: the schema attribute definition
* @ctxt: the schema parser context
@@ -3749,6 +3789,11 @@
*/
xmlHashScan(ret->attrDecl, (xmlHashScanner) xmlSchemaAttrFixup, ctxt);
+ /*
+ * Then fixup all attributes group declarations
+ */
+ xmlHashScan(ret->attrgrpDecl, (xmlHashScanner) xmlSchemaAttrGrpFixup, ctxt);
+
return (ret);
}
@@ -4796,10 +4841,20 @@
int i, ret;
xmlAttrPtr attr;
xmlChar *value;
+ xmlSchemaAttributeGroupPtr group = NULL;
if (attributes == NULL)
return(0);
while (attributes != NULL) {
+ /*
+ * Handle attribute groups
+ */
+ if (attributes->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
+ group = (xmlSchemaAttributeGroupPtr) attributes;
+ xmlSchemaValidateAttributes(ctxt, elem, group->attributes);
+ attributes = group->next;
+ continue;
+ }
for (i = ctxt->attrBase;i < ctxt->attrNr;i++) {
attr = ctxt->attr[i].attr;
if (attr == NULL)
@@ -4822,7 +4877,7 @@
}
value = xmlNodeListGetString(elem->doc, attr->children, 1);
ret = xmlSchemaValidateSimpleValue(ctxt, attributes->subtypes,
- value);
+ value);
if (ret != 0) {
ctxt->err = XML_SCHEMAS_ERR_ATTRINVALID;
if (ctxt->error != NULL)