move the TODO as comments as the function while not finished are usable

* xmlsave.c: move the TODO as comments as the function while not
  finished are usable as-is
* xmlschemas.c include/libxml/xmlerror.h: patch from Kasimier Buchcik
  implementing union
* test/schemas/union_0_0.x* result/schemas/union_0_0*: added example
* python/Makefile.am: applied fix from Mike Hommey
Daniel
This commit is contained in:
Daniel Veillard 2004-04-16 16:30:05 +00:00
parent a0c48addfc
commit 377e1a9059
9 changed files with 251 additions and 12 deletions

View File

@ -1,3 +1,12 @@
Fri Apr 16 18:22:25 CEST 2004 Daniel Veillard <daniel@veillard.com>
* xmlsave.c: move the TODO as comments as the function while not
finished are usable as-is
* xmlschemas.c include/libxml/xmlerror.h: patch from Kasimier Buchcik
implementing union
* test/schemas/union_0_0.x* result/schemas/union_0_0*: added example
* python/Makefile.am: applied fix from Mike Hommey
Fri Apr 16 23:58:42 HKT 2004 William Brack <wbrack@mmm.com.hk>
* parser.c: fixed problem with detecting external dtd

View File

@ -544,6 +544,7 @@ typedef enum {
XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI, /* 1769 */
XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI, /* 1770 */
XML_SCHEMAP_NOT_SCHEMA, /* 1771 */
XML_SCHEMAP_UNKNOWN_MEMBER_TYPE, /* 1772 */
XML_SCHEMAV_NOROOT = 1800,
XML_SCHEMAV_UNDECLAREDELEM, /* 1801 */
XML_SCHEMAV_NOTTOPLEVEL, /* 1802 */

View File

@ -51,9 +51,12 @@ GENERATE = generator.py
API_DESC = $(top_srcdir)/doc/libxml2-api.xml $(srcdir)/libxml2-python-api.xml
GENERATED= $(srcdir)/libxml2class.py \
$(srcdir)/libxml2-export.c \
$(srcdir)/libxml2class.txt \
$(srcdir)/libxml2-py.c \
$(srcdir)/libxml2-py.h
CLEANFILES= $(GENERATED) gen_prog libxml2.py
$(GENERATED): gen_prog
gen_prog: $(srcdir)/$(GENERATE) $(API_DESC)
@ -68,6 +71,3 @@ endif
tests test: all
cd tests && $(MAKE) tests
clean:
rm -f $(GENERATED) *.o _libxml.so *.pyc libxml2.py gen_prog

1
result/schemas/union_0_0 Normal file
View File

@ -0,0 +1 @@
./test/schemas/union_0_0.xml validates

View File

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<foo xmlns="http://foo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<em>EMP0090</em>
<em>EMP0099</em>
</foo>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://foo"
xmlns="http://foo"
xmlns:a="http://foo">
<xsd:element name="foo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="em" type="emType" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="emp0001_3Type">
<xsd:restriction base="xsd:ID">
<xsd:enumeration value="EMP0040"/>
<xsd:enumeration value="EMP0003"/>
<xsd:enumeration value="EMP0004"/>
<xsd:enumeration value="EMP0005"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="emp0004_5Type">
<xsd:restriction base="xsd:ID">
<xsd:enumeration value="EMP0002"/>
<xsd:enumeration value="EMP0090"/>
<xsd:enumeration value="EMP0007"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="unboundedEmType">
<xsd:union memberTypes="a:emp0001_3Type emp0004_5Type">
<xsd:simpleType>
<xsd:restriction base="xsd:ID">
<xsd:enumeration value="EMP0099"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
<xsd:simpleType name="emType">
<xsd:restriction base="unboundedEmType">
<xsd:pattern value="EMP[0-9]*"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@ -1265,6 +1265,8 @@ xmlSaveToIO(xmlOutputWriteCallback iowrite,
* @doc: a document
*
* Save a full document to a saving context
* TODO: The function is not fully implemented yet as it does not return the
* byte count but 0 instead
*
* Returns the number of byte written or -1 in case of error
*/
@ -1274,7 +1276,6 @@ xmlSaveDoc(xmlSaveCtxtPtr ctxt, xmlDocPtr doc)
long ret = 0;
xmlDocContentDumpOutput(ctxt, doc);
TODO /* compute ret */
return(ret);
}
@ -1284,6 +1285,8 @@ xmlSaveDoc(xmlSaveCtxtPtr ctxt, xmlDocPtr doc)
* @node: a document
*
* Save a subtree starting at the node parameter to a saving context
* TODO: The function is not fully implemented yet as it does not return the
* byte count but 0 instead
*
* Returns the number of byte written or -1 in case of error
*/
@ -1293,7 +1296,6 @@ xmlSaveTree(xmlSaveCtxtPtr ctxt, xmlNodePtr node)
long ret = 0;
xmlNodeDumpOutputInternal(ctxt, node);
TODO /* compute ret */
return(ret);
}

View File

@ -2279,7 +2279,7 @@ xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_LIST;
type->type = XML_SCHEMA_TYPE_UNION;
type->id = xmlSchemaGetProp(ctxt, node, "id");
type->ref = xmlSchemaGetProp(ctxt, node, "memberTypes");
@ -4358,6 +4358,57 @@ xmlSchemaRefFixupCallback(xmlSchemaElementPtr elem,
}
}
static void
xmlSchemaParseUnionRefCheck(xmlSchemaTypePtr typeDecl,
xmlSchemaParserCtxtPtr ctxt)
{
const xmlChar *cur, *end, *prefix, *ncName, *namespace;
xmlChar *tmp;
xmlSchemaTypePtr subtype;
xmlNsPtr ns;
int len;
if ((typeDecl->type != XML_SCHEMA_TYPE_UNION) || (typeDecl->ref == NULL))
return;
cur = typeDecl->ref;
do {
while (IS_BLANK_CH(*cur))
cur++;
end = cur;
while ((*end != 0) && (!(IS_BLANK_CH(*end))))
end++;
if (end == cur)
break;
tmp = xmlStrndup(cur, end - cur);
ncName = xmlSplitQName3(tmp, &len);
if (ncName != NULL) {
prefix = xmlDictLookup(ctxt->dict, tmp, len);
} else {
prefix = NULL;
ncName = tmp;
}
ns = xmlSearchNs(typeDecl->node->doc, typeDecl->node, prefix);
if (ns == NULL) {
xmlSchemaPErr(ctxt, typeDecl->node, XML_SCHEMAP_PREFIX_UNDEFINED,
"Union %s: the namespace of member type %s is undefined\n",
typeDecl->name, (const char *) tmp);
} else {
namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
}
/* Lookup the referenced type */
subtype = xmlSchemaGetType(ctxt->schema, ncName, namespace);
if (subtype == NULL) {
xmlSchemaPErr(ctxt, typeDecl->node, XML_SCHEMAP_UNKNOWN_MEMBER_TYPE,
"Union %s references an unknown member type >%s<\n",
typeDecl->name, (const char *) tmp);
}
xmlFree(tmp);
cur = end;
} while (*cur != 0);
}
/**
* xmlSchemaTypeFixup:
* @typeDecl: the schema type definition
@ -4553,6 +4604,7 @@ xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl,
case XML_SCHEMA_TYPE_NOTATION:
case XML_SCHEMA_TYPE_LIST:
case XML_SCHEMA_TYPE_UNION:
xmlSchemaParseUnionRefCheck(typeDecl, ctxt);
case XML_SCHEMA_FACET_MININCLUSIVE:
case XML_SCHEMA_FACET_MINEXCLUSIVE:
case XML_SCHEMA_FACET_MAXINCLUSIVE:
@ -5076,6 +5128,28 @@ static int
xmlSchemaValidateFacets(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaTypePtr base,
xmlSchemaFacetPtr facets, const xmlChar * value)
{
return(xmlSchemaValidateFacetsInternal(ctxt, base, facets, value, 1));
}
/**
* xmlSchemaValidateFacetsInternal:
* @ctxt: a schema validation context
* @base: the base type
* @facets: the list of facets to check
* @value: the lexical repr of the value to validate
* @val: the precomputed value
* @fireErrors: if 0, only internal errors will be fired; otherwise all errors will be fired.
*
* Check a value against all facet conditions
*
* Returns 0 if the element is schemas valid, a positive error code
* number otherwise and -1 in case of internal or API error.
*/
static int
xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaTypePtr base,
xmlSchemaFacetPtr facets, const xmlChar * value, int fireErrors)
{
int ret = 0;
int tmp = 0;
@ -5101,7 +5175,8 @@ xmlSchemaValidateFacets(xmlSchemaValidCtxtPtr ctxt,
if (tmp != 0) {
ret = tmp;
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_FACET, "Failed to validate type with facet %s\n", (const xmlChar *) xmlSchemaFacetTypeToString(type), NULL);
if (fireErrors)
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_FACET, "Failed to validate type with facet %s\n", (const xmlChar *) xmlSchemaFacetTypeToString(type), NULL);
}
if (facet != NULL)
facet = facet->next;
@ -5115,6 +5190,76 @@ xmlSchemaValidateFacets(xmlSchemaValidCtxtPtr ctxt,
* *
************************************************************************/
/**
* xmlSchemaValidateSimpleValueUnion:
* @ctxt: a schema validation context
* @type: the type declaration
* @value: the value to validate
*
* Validates a value against a union.
*
* Returns 0 if the value is valid, a positive error code
* number otherwise and -1 in case of internal or API error.
*/
static int
xmlSchemaValidateSimpleValueUnion(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaTypePtr type, const xmlChar * value)
{
int ret = 0;
const xmlChar *cur, *end, *prefix, *ncName;
xmlChar *tmp;
xmlSchemaTypePtr subtype;
xmlNsPtr ns;
int len;
/* Process referenced memberTypes. */
cur = type->ref;
do {
while (IS_BLANK_CH(*cur))
cur++;
end = cur;
while ((*end != 0) && (!(IS_BLANK_CH(*end))))
end++;
if (end == cur)
break;
tmp = xmlStrndup(cur, end - cur);
ncName = xmlSplitQName3(tmp, &len);
if (ncName != NULL) {
prefix = xmlStrndup(tmp, len);
/* prefix = xmlDictLookup(ctxt->doc->dict, tmp, len); */
} else {
prefix = NULL;
ncName = tmp;
}
/* We won't do additional checks here, since they have been performed during parsing. */
ns = xmlSearchNs(type->node->doc, type->node, prefix);
/* namespace = xmlDictLookup(ctxt->doc->dict, ns->href, -1); */
subtype = xmlSchemaGetType(ctxt->schema, ncName, ns->href);
if (tmp != NULL)
xmlFree(tmp);
if (prefix != NULL)
xmlFree(prefix);
ret = xmlSchemaValidateSimpleValueInternal(ctxt, subtype, value, 0);
if ((ret == 0) || (ret == -1)) {
return (ret);
}
cur = end;
} while (*cur != 0);
if (type->subtypes != NULL) {
subtype = type->subtypes;
do {
ret = xmlSchemaValidateSimpleValueInternal(ctxt, subtype, value, 0);
if ((ret == 0) || (ret == -1)) {
return (ret);
}
subtype = subtype->next;
} while (subtype != NULL);
}
return (ret);
}
/**
* xmlSchemaValidateSimpleValue:
* @ctxt: a schema validation context
@ -5129,6 +5274,25 @@ xmlSchemaValidateFacets(xmlSchemaValidCtxtPtr ctxt,
static int
xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaTypePtr type, const xmlChar * value)
{
return (xmlSchemaValidateSimpleValueInternal(ctxt, type, value, 1));
}
/**
* xmlSchemaValidateSimpleValue:
* @ctxt: a schema validation context
* @type: the type declaration
* @value: the value to validate
* @fireErrors: if 0, only internal errors will be fired; otherwise all errors will be fired.
*
* Validate a value against a simple type
*
* Returns 0 if the value is valid, a positive error code
* number otherwise and -1 in case of internal or API error.
*/
static int
xmlSchemaValidateSimpleValueInternal(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaTypePtr type, const xmlChar * value, int fireErrors)
{
int ret = 0;
@ -5147,7 +5311,7 @@ xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
}
ret = xmlSchemaValPredefTypeNode(type, value, &(ctxt->value),
ctxt->cur);
if (ret != 0) {
if ((fireErrors) && (ret != 0)) {
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_VALUE, "Failed to validate basic type %s\n", type->name, NULL);
}
} else if (type->type == XML_SCHEMA_TYPE_RESTRICTION) {
@ -5156,7 +5320,7 @@ xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
base = type->baseType;
if (base != NULL) {
ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
ret = xmlSchemaValidateSimpleValueInternal(ctxt, base, value, fireErrors);
} else if (type->subtypes != NULL) {
TODO
}
@ -5168,7 +5332,7 @@ xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
if (ctxt->schema != NULL) {
if (ret == 0) {
facet = type->facets;
ret = xmlSchemaValidateFacets(ctxt, base, facet, value);
ret = xmlSchemaValidateFacetsInternal(ctxt, base, facet, value, fireErrors);
}
}
} else if (type->type == XML_SCHEMA_TYPE_SIMPLE) {
@ -5176,7 +5340,7 @@ xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
base = type->subtypes;
if (base != NULL) {
ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
ret = xmlSchemaValidateSimpleValueInternal(ctxt, base, value, fireErrors);
} else {
TODO}
} else if (type->type == XML_SCHEMA_TYPE_LIST) {
@ -5202,12 +5366,17 @@ xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
if (end == cur)
break;
tmp = xmlStrndup(cur, end - cur);
ret2 = xmlSchemaValidateSimpleValue(ctxt, base, tmp);
ret2 = xmlSchemaValidateSimpleValueInternal(ctxt, base, tmp, fireErrors);
xmlFree(tmp);
if (ret2 != 0)
ret = 1;
cur = end;
} while (*cur != 0);
} else if (type->type == XML_SCHEMA_TYPE_UNION) {
ret = xmlSchemaValidateSimpleValueUnion(ctxt, type, value);
if ((fireErrors) && (ret != 0)) {
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_VALUE, "Failed to validate type %s\n", type->name, NULL);
}
} else {
TODO
}