Fixed comparison for default/fixed attribute values, if the type was
* xmlschemas.c: Fixed comparison for default/fixed attribute
values, if the type was 'xsd:string'. Changed the comparison
for IDCs to use the whitespace aware comparison function.
* xmlschemastypes.c include/libxml/xmlschemastypes.h:
Added xmlSchemaGetCanonValue, xmlSchemaNewStringValue and
xmlSchemaCompareValuesWhtsp to the API. Added functions
to compare strings with whitespace combinations of "preserve",
"replace" and "collapse".
diff --git a/ChangeLog b/ChangeLog
index e54a26a..f108bbe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Thu Feb 17 12:03:46 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+ * xmlschemas.c: Fixed comparison for default/fixed attribute
+ values, if the type was 'xsd:string'. Changed the comparison
+ for IDCs to use the whitespace aware comparison function.
+ * xmlschemastypes.c include/libxml/xmlschemastypes.h:
+ Added xmlSchemaGetCanonValue, xmlSchemaNewStringValue and
+ xmlSchemaCompareValuesWhtsp to the API. Added functions
+ to compare strings with whitespace combinations of "preserve",
+ "replace" and "collapse".
+
Wed Feb 16 13:24:35 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
* xmlschemas.c: Further work on IDCs, especially evaluation for
diff --git a/include/libxml/xmlschemastypes.h b/include/libxml/xmlschemastypes.h
index 86010c0..119604e 100644
--- a/include/libxml/xmlschemastypes.h
+++ b/include/libxml/xmlschemastypes.h
@@ -23,6 +23,13 @@
extern "C" {
#endif
+typedef enum {
+ XML_SCHEMA_WHITESPACE_UNKNOWN = 0,
+ XML_SCHEMA_WHITESPACE_PRESERVE = 1,
+ XML_SCHEMA_WHITESPACE_REPLACE = 2,
+ XML_SCHEMA_WHITESPACE_COLLAPSE = 3
+} xmlSchemaWhitespaceValueType;
+
XMLPUBFUN void XMLCALL
xmlSchemaInitTypes (void);
XMLPUBFUN void XMLCALL
@@ -87,6 +94,17 @@
const xmlChar *value,
xmlSchemaValPtr *val,
xmlNodePtr node);
+XMLPUBFUN int XMLCALL
+ xmlSchemaGetCanonValue (xmlSchemaValPtr val,
+ const xmlChar **retValue);
+XMLPUBFUN xmlSchemaValPtr XMLCALL
+ xmlSchemaNewStringValue (xmlSchemaValType type,
+ const xmlChar *value);
+XMLPUBFUN int XMLCALL
+ xmlSchemaCompareValuesWhtsp (xmlSchemaValPtr x,
+ xmlSchemaWhitespaceValueType xws,
+ xmlSchemaValPtr y,
+ xmlSchemaWhitespaceValueType yws);
#ifdef __cplusplus
}
diff --git a/xmlschemas.c b/xmlschemas.c
index 7aa5cbe..4852b6c 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -7,7 +7,7 @@
* Daniel Veillard <veillard@redhat.com>
*/
-/*
+/*
* TODO:
* - when types are redefined in includes, check that all
* types in the redef list are equal
@@ -54,7 +54,7 @@
#define ELEM_INFO_ENABLED 1
-/* #define IDC_ENABLED 1 */
+/* #define IDC_ENABLED 1 */
/* #define IDC_VALUE_SUPPORT 1 */
@@ -117,9 +117,11 @@
((item->type == XML_SCHEMA_TYPE_BASIC) && \
(item->builtInType != XML_SCHEMAS_ANYTYPE)))
+/*
#define XML_SCHEMAS_VAL_WTSP_PRESERVE 0
#define XML_SCHEMAS_VAL_WTSP_REPLACE 1
#define XML_SCHEMAS_VAL_WTSP_COLLAPSE 2
+*/
#define XML_SCHEMAS_PARSE_ERROR 1
@@ -384,9 +386,6 @@
xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
elements */
int sizeKeySeqs;
- xmlSchemaPSVIIDCKeyPtr **refKeySeqs;
- int nbRefKeySeqs;
- int sizeRefKeySeqs;
int targetDepth;
};
@@ -10268,7 +10267,7 @@
}
/**
- * xmlSchemaIsDerivedFromBuiltInType:
+ * xmlSchemaGetPrimitiveType:
* @type: the simpleType definition
*
* Returns the primitive type of the given type or
@@ -10286,6 +10285,25 @@
return (NULL);
}
+/**
+ * xmlSchemaGetBuiltInTypeAncestor:
+ * @type: the simpleType definition
+ *
+ * Returns the primitive type of the given type or
+ * NULL in case of error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
+{
+ while (type != NULL) {
+ if (type->type == XML_SCHEMA_TYPE_BASIC)
+ return (type);
+ type = type->baseType;
+ }
+
+ return (NULL);
+}
+
/**
* xmlSchemaBuildAttributeUsesOwned:
@@ -14763,8 +14781,6 @@
return ("Internal Error");
}
-
-
static int
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
{
@@ -14776,24 +14792,24 @@
*/
if (type->type == XML_SCHEMA_TYPE_BASIC) {
if (type->builtInType == XML_SCHEMAS_STRING)
- return(XML_SCHEMAS_VAL_WTSP_PRESERVE);
+ return(XML_SCHEMAS_FACET_PRESERVE);
else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
- return(XML_SCHEMAS_VAL_WTSP_REPLACE);
+ return(XML_SCHEMAS_FACET_REPLACE);
else {
/*
* For all ·atomic· datatypes other than string (and types ·derived·
* by ·restriction· from it) the value of whiteSpace is fixed to
* collapse
*/
- return(XML_SCHEMAS_VAL_WTSP_COLLAPSE);
+ return(XML_SCHEMAS_FACET_COLLAPSE);
}
} else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
/*
* For list types the facet "whiteSpace" is fixed to "collapse".
*/
- return (XML_SCHEMAS_VAL_WTSP_COLLAPSE);
+ return (XML_SCHEMAS_FACET_COLLAPSE);
} else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
- return (-1);
+ return (XML_SCHEMAS_FACET_UNKNOWN);
} else if (type->facetSet != NULL) {
xmlSchemaTypePtr anyST;
xmlSchemaFacetLinkPtr lin;
@@ -14815,14 +14831,7 @@
lin = type->facetSet;
do {
if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
- if (lin->facet->whitespace ==
- XML_SCHEMAS_FACET_COLLAPSE) {
- return(XML_SCHEMAS_VAL_WTSP_COLLAPSE);
- } else if (lin->facet->whitespace ==
- XML_SCHEMAS_FACET_REPLACE) {
- return(XML_SCHEMAS_VAL_WTSP_REPLACE);
- } else
- return(XML_SCHEMAS_VAL_WTSP_PRESERVE);
+ return(lin->facet->whitespace);
break;
}
lin = lin->next;
@@ -14831,7 +14840,7 @@
}
anc = anc->baseType;
} while (anc != anyST);
- return (XML_SCHEMAS_VAL_WTSP_COLLAPSE);
+ return (XML_SCHEMAS_FACET_COLLAPSE);
}
return (-1);
}
@@ -15667,11 +15676,11 @@
* Normalize the value.
*/
if (normalize &&
- (ctxt->valueWS != XML_SCHEMAS_VAL_WTSP_COLLAPSE)) {
+ (ctxt->valueWS != XML_SCHEMAS_FACET_COLLAPSE)) {
int norm = xmlSchemaGetWhiteSpaceFacetValue(type);
if ((norm != -1) && (norm > ctxt->valueWS)) {
- if (norm == XML_SCHEMAS_VAL_WTSP_COLLAPSE)
+ if (norm == XML_SCHEMAS_FACET_COLLAPSE)
normValue = xmlSchemaCollapseString(value);
else
normValue = xmlSchemaWhiteSpaceReplace(value);
@@ -15992,7 +16001,7 @@
}
mws = xmlSchemaGetWhiteSpaceFacetValue(memberLink->type);
if (mws > ctxt->valueWS) {
- if (mws == XML_SCHEMAS_VAL_WTSP_COLLAPSE)
+ if (mws == XML_SCHEMAS_FACET_COLLAPSE)
normValue = xmlSchemaCollapseString(value);
else
normValue = xmlSchemaWhiteSpaceReplace(value);
@@ -16636,7 +16645,14 @@
{
#ifdef IDC_VALUE_SUPPORT
int ret;
- ret = xmlSchemaCompareValues(a, b);
+ int aws, bws;
+
+ aws = xmlSchemaGetWhiteSpaceFacetValue(ta);
+ bws = xmlSchemaGetWhiteSpaceFacetValue(tb);
+
+ ret = xmlSchemaCompareValuesWhtsp(
+ a, (xmlSchemaWhitespaceValueType) aws,
+ b, (xmlSchemaWhitespaceValueType) bws);
if (ret == 0)
return(1);
else if (ret == -2) {
@@ -16962,11 +16978,19 @@
* Failed to provide the normalized value; maby
* the value was invalid.
*/
- xmlSchemaVErr(vctxt, NULL,
+ xmlSchemaVCustomErr(vctxt,
+ XML_SCHEMAV_CVC_IDC,
+ vctxt->nodeInfo->node,
+ (xmlSchemaTypePtr) sto->matcher->aidc->def,
+ "Warning: No precomputed value available, the value "
+ "was either invalid or something strange happend", NULL);
+ /*
+ xmlSchemaVErr(vctxt, vctxt->nodeInfo->node,
XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaXPathProcessHistory, "
"computed value not available.\n",
NULL, NULL);
+ */
sto->nbHistory--;
goto deregister_check;
} else {
@@ -18308,7 +18332,7 @@
XML_SCHEMAV_INTERNAL,
elem, actualType,
"Internal error: xmlSchemaValidateElementByDeclaration, "
- "validating a default value", NULL);
+ "calling validation by type", NULL);
return (-1);
}
/*
@@ -19083,7 +19107,6 @@
return (ret);
}
-
static int
xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaAttrStatePtr state)
@@ -19126,6 +19149,10 @@
if (xmlSchemaGetEffectiveValueConstraint(
(xmlSchemaAttributePtr) ctxt->attrInfo->decl,
&fixed, &defValue, &defVal) && (fixed == 1)) {
+
+ int ws = xmlSchemaGetWhiteSpaceFacetValue(
+ ctxt->attrInfo->typeDef);
+
/*
* cvc-au : Attribute Locally Valid (Use)
* For an attribute information item to be·valid·
@@ -19142,12 +19169,45 @@
* TODO: Use the *normalized* value and the *canonical* fixed
* value.
*/
- if (((ctxt->value != NULL) &&
- (xmlSchemaCompareValues(ctxt->value, defVal) != 0)) ||
- ((ctxt->value == NULL) &&
- (! xmlStrEqual(defValue, BAD_CAST value)))) {
+ if (ctxt->value != NULL) {
+ if (defVal == NULL) {
+ xmlSchemaTypePtr prim;
+ /*
+ * Oops, the value was not computed.
+ */
+ prim = xmlSchemaGetPrimitiveType(ctxt->attrInfo->typeDef);
+ if (prim->builtInType == XML_SCHEMAS_STRING) {
+ xmlSchemaTypePtr builtIn;
+
+ builtIn = xmlSchemaGetBuiltInTypeAncestor(
+ ctxt->attrInfo->typeDef);
+ defVal = xmlSchemaNewStringValue(
+ builtIn->builtInType, value);
+ ((xmlSchemaAttributePtr) ctxt->attrInfo->decl)->defVal =
+ defVal;
+ value = NULL;
+ } else {
+ xmlSchemaVErr(ctxt, ctxt->attrInfo->node,
+ XML_SCHEMAV_INTERNAL,
+ "Internal error: xmlSchemaCheckAttrLocallyValid, "
+ "could not aquire a precomputed vale",
+ NULL, NULL);
+ }
+ }
+ if (defVal != NULL) {
+ if (xmlSchemaCompareValuesWhtsp(ctxt->value,
+ (xmlSchemaWhitespaceValueType) ws,
+ defVal, (xmlSchemaWhitespaceValueType) ws) != 0)
+ state->state =
+ XML_SCHEMAS_ATTR_INVALID_FIXED_VALUE;
+ }
+ } else if (! xmlStrEqual(defValue, BAD_CAST value)) {
+ /*
+ * TODO: Remove this and ensure computed values to be
+ * existent.
+ */
state->state =
- XML_SCHEMAS_ATTR_INVALID_FIXED_VALUE;
+ XML_SCHEMAS_ATTR_INVALID_FIXED_VALUE;
}
}
}
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index 3ff8acf..83aaa7b 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -45,6 +45,11 @@
#define XML_SCHEMAS_NAMESPACE_NAME \
(const xmlChar *)"http://www.w3.org/2001/XMLSchema"
+#define IS_WSP_REPLACE_CH(c) ((((c) == 0x9) || ((c) == 0xa)) || \
+ ((c) == 0xd))
+
+#define IS_WSP_SPACE_CH(c) ((c) == 0x20)
+
static unsigned long powten[10] = {
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000L,
@@ -677,6 +682,34 @@
}
/**
+ * xmlSchemaNewStringValue:
+ * @type: the value type
+ *
+ * Allocate a new simple type value. The type can be
+ * of XML_SCHEMAS_STRING.
+ *
+ * Returns a pointer to the new value or NULL in case of error
+ */
+xmlSchemaValPtr
+xmlSchemaNewStringValue(xmlSchemaValType type,
+ const xmlChar *value)
+{
+ xmlSchemaValPtr val;
+
+ if (type != XML_SCHEMAS_STRING)
+ return(NULL);
+ val = (xmlSchemaValPtr) xmlMalloc(sizeof(xmlSchemaVal));
+ if (val == NULL) {
+ return(NULL);
+ }
+ memset(val, 0, sizeof(xmlSchemaVal));
+ val->type = type;
+ val->value.str = (xmlChar *) value;
+ return(val);
+}
+
+
+/**
* xmlSchemaFreeValue:
* @value: the value to free
*
@@ -2210,7 +2243,11 @@
case XML_SCHEMAS_IDREF:
ret = xmlValidateNCName(value, 1);
if ((ret == 0) && (val != NULL)) {
- TODO;
+ v = xmlSchemaNewValue(XML_SCHEMAS_IDREF);
+ if (v == NULL)
+ goto error;
+ v->value.str = xmlStrdup(value);
+ *val = v;
}
if ((ret == 0) && (node != NULL) &&
(node->type == XML_ATTRIBUTE_NODE)) {
@@ -3478,6 +3515,333 @@
}
/**
+ * xmlSchemaComparePreserveReplaceStrings:
+ * @x: a first string value
+ * @y: a second string value
+ * @invert: inverts the result if x < y or x > y.
+ *
+ * Compare 2 string for their normalized values.
+ * @x is a string with whitespace of "preserve", @y is
+ * a string with a whitespace of "replace". I.e. @x could
+ * be an "xsd:string" and @y an "xsd:normalizedString".
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaComparePreserveReplaceStrings(xmlSchemaValPtr x, xmlSchemaValPtr y,
+ int invert)
+{
+ const xmlChar *utf1;
+ const xmlChar *utf2;
+ int tmp;
+
+ if ((x == NULL) || (y == NULL))
+ return(-2);
+ utf1 = x->value.str;
+ utf2 = y->value.str;
+
+ while ((*utf1 != 0) && (*utf2 != 0)) {
+ if (IS_WSP_REPLACE_CH(*utf2)) {
+ if (! IS_WSP_SPACE_CH(*utf1)) {
+ if ((*utf1 - 0x20) < 0) {
+ if (invert)
+ return(1);
+ else
+ return(-1);
+ } else {
+ if (invert)
+ return(-1);
+ else
+ return(1);
+ }
+ }
+ } else {
+ tmp = *utf1 - *utf2;
+ if (tmp < 0) {
+ if (invert)
+ return(1);
+ else
+ return(-1);
+ }
+ if (tmp > 0) {
+ if (invert)
+ return(-1);
+ else
+ return(1);
+ }
+ }
+ utf1++;
+ utf2++;
+ }
+ if (*utf1 != 0) {
+ if (invert)
+ return(-1);
+ else
+ return(1);
+ }
+ if (*utf2 != 0) {
+ if (invert)
+ return(1);
+ else
+ return(-1);
+ }
+ return(0);
+}
+
+/**
+ * xmlSchemaComparePreserveCollapseStrings:
+ * @x: a first string value
+ * @y: a second string value
+ *
+ * Compare 2 string for their normalized values.
+ * @x is a string with whitespace of "preserve", @y is
+ * a string with a whitespace of "collapse". I.e. @x could
+ * be an "xsd:string" and @y an "xsd:normalizedString".
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaComparePreserveCollapseStrings(xmlSchemaValPtr x, xmlSchemaValPtr y,
+ int invert)
+{
+ const xmlChar *utf1;
+ const xmlChar *utf2;
+ int tmp;
+
+ if ((x == NULL) || (y == NULL))
+ return(-2);
+ utf1 = x->value.str;
+ utf2 = y->value.str;
+
+ /*
+ * Skip leading blank chars of the collapsed string.
+ */
+ while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
+ utf2++;
+
+ while ((*utf1 != 0) && (*utf2 != 0)) {
+ if (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2)) {
+ if (! IS_WSP_SPACE_CH(*utf1)) {
+ /*
+ * The utf2 character would have been replaced to 0x20.
+ */
+ if ((*utf1 - 0x20) < 0) {
+ if (invert)
+ return(1);
+ else
+ return(-1);
+ } else {
+ if (invert)
+ return(-1);
+ else
+ return(1);
+ }
+ }
+ utf1++;
+ utf2++;
+ /*
+ * Skip contiguous blank chars of the collapsed string.
+ */
+ while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
+ utf2++;
+ } else {
+ tmp = *utf1++ - *utf2++;
+ if (tmp < 0) {
+ if (invert)
+ return(1);
+ else
+ return(-1);
+ }
+ if (tmp > 0) {
+ if (invert)
+ return(-1);
+ else
+ return(1);
+ }
+ }
+ }
+ if (*utf1 != 0) {
+ if (invert)
+ return(-1);
+ else
+ return(1);
+ }
+ if (*utf2 != 0) {
+ /*
+ * Skip trailing blank chars of the collapsed string.
+ */
+ while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
+ utf2++;
+ if (*utf2 != 0) {
+ if (invert)
+ return(1);
+ else
+ return(-1);
+ }
+ }
+ return(0);
+}
+
+/**
+ * xmlSchemaComparePreserveCollapseStrings:
+ * @x: a first string value
+ * @y: a second string value
+ *
+ * Compare 2 string for their normalized values.
+ * @x is a string with whitespace of "preserve", @y is
+ * a string with a whitespace of "collapse". I.e. @x could
+ * be an "xsd:string" and @y an "xsd:normalizedString".
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaCompareReplaceCollapseStrings(xmlSchemaValPtr x, xmlSchemaValPtr y,
+ int invert)
+{
+ const xmlChar *utf1;
+ const xmlChar *utf2;
+ int tmp;
+
+ if ((x == NULL) || (y == NULL))
+ return(-2);
+ utf1 = x->value.str;
+ utf2 = y->value.str;
+
+ /*
+ * Skip leading blank chars of the collapsed string.
+ */
+ while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
+ utf2++;
+
+ while ((*utf1 != 0) && (*utf2 != 0)) {
+ if (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2)) {
+ if (! (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1))) {
+ /*
+ * The utf2 character would have been replaced to 0x20.
+ */
+ if ((*utf1 - 0x20) < 0) {
+ if (invert)
+ return(1);
+ else
+ return(-1);
+ } else {
+ if (invert)
+ return(-1);
+ else
+ return(1);
+ }
+ }
+ utf1++;
+ utf2++;
+ /*
+ * Skip contiguous blank chars of the collapsed string.
+ */
+ while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
+ utf2++;
+ } else {
+ if (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1)) {
+ /*
+ * The utf1 character would have been replaced to 0x20.
+ */
+ if ((0x20 - *utf2) < 0) {
+ if (invert)
+ return(1);
+ else
+ return(-1);
+ } else {
+ if (invert)
+ return(-1);
+ else
+ return(1);
+ }
+ }
+ tmp = *utf1++ - *utf2++;
+ if (tmp < 0)
+ return(-1);
+ if (tmp > 0)
+ return(1);
+ }
+ }
+ if (*utf1 != 0) {
+ if (invert)
+ return(-1);
+ else
+ return(1);
+ }
+ if (*utf2 != 0) {
+ /*
+ * Skip trailing blank chars of the collapsed string.
+ */
+ while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
+ utf2++;
+ if (*utf2 != 0) {
+ if (invert)
+ return(1);
+ else
+ return(-1);
+ }
+ }
+ return(0);
+}
+
+
+/**
+ * xmlSchemaCompareReplacedStrings:
+ * @x: a first string value
+ * @y: a second string value
+ *
+ * Compare 2 string for their normalized values.
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaCompareReplacedStrings(xmlSchemaValPtr x, xmlSchemaValPtr y)
+{
+ const xmlChar *utf1;
+ const xmlChar *utf2;
+ int tmp;
+
+ if ((x == NULL) || (y == NULL))
+ return(-2);
+ utf1 = x->value.str;
+ utf2 = y->value.str;
+
+ while ((*utf1 != 0) && (*utf2 != 0)) {
+ if (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2)) {
+ if (! (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1))) {
+ if ((*utf1 - 0x20) < 0)
+ return(-1);
+ else
+ return(1);
+ }
+ } else {
+ if (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1)) {
+ if ((0x20 - *utf2) < 0)
+ return(-1);
+ else
+ return(1);
+ }
+ tmp = *utf1 - *utf2;
+ if (tmp < 0)
+ return(-1);
+ if (tmp > 0)
+ return(1);
+ }
+ utf1++;
+ utf2++;
+ }
+ if (*utf1 != 0)
+ return(1);
+ if (*utf2 != 0)
+ return(-1);
+ return(0);
+}
+
+/**
* xmlSchemaCompareNormStrings:
* @x: a first string value
* @y: a second string value
@@ -3605,15 +3969,20 @@
/**
* xmlSchemaCompareValues:
* @x: a first value
+ * @xwtsp: the whitespace type
* @y: a second value
+ * @ywtsp: the whitespace type
*
* Compare 2 values
*
* Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
* case of error
*/
-int
-xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
+static int
+xmlSchemaCompareValuesInternal(xmlSchemaValPtr x,
+ xmlSchemaWhitespaceValueType xws,
+ xmlSchemaValPtr y,
+ xmlSchemaWhitespaceValueType yws) {
if ((x == NULL) || (y == NULL))
return(-2);
@@ -3676,7 +4045,8 @@
(y->type == XML_SCHEMAS_GYEARMONTH))
return (xmlSchemaCompareDates(x, y));
return (-2);
- case XML_SCHEMAS_NORMSTRING:
+ case XML_SCHEMAS_STRING:
+ case XML_SCHEMAS_NORMSTRING:
case XML_SCHEMAS_TOKEN:
case XML_SCHEMAS_LANGUAGE:
case XML_SCHEMAS_NMTOKEN:
@@ -3687,19 +4057,60 @@
case XML_SCHEMAS_ENTITY:
case XML_SCHEMAS_NOTATION:
case XML_SCHEMAS_ANYURI:
- if ((y->type == XML_SCHEMAS_NORMSTRING) ||
+ /*
+ * TODO: Compare those against QName.
+ */
+ if (y->type == XML_SCHEMAS_QNAME) {
+ TODO
+ return (-2);
+ }
+ if ((y->type == XML_SCHEMAS_STRING) ||
+ (y->type == XML_SCHEMAS_NORMSTRING) ||
(y->type == XML_SCHEMAS_TOKEN) ||
(y->type == XML_SCHEMAS_LANGUAGE) ||
(y->type == XML_SCHEMAS_NMTOKEN) ||
(y->type == XML_SCHEMAS_NAME) ||
- (y->type == XML_SCHEMAS_QNAME) ||
(y->type == XML_SCHEMAS_NCNAME) ||
(y->type == XML_SCHEMAS_ID) ||
(y->type == XML_SCHEMAS_IDREF) ||
(y->type == XML_SCHEMAS_ENTITY) ||
(y->type == XML_SCHEMAS_NOTATION) ||
- (y->type == XML_SCHEMAS_ANYURI))
- return (xmlSchemaCompareNormStrings(x, y));
+ (y->type == XML_SCHEMAS_ANYURI)) {
+
+ if (xws == XML_SCHEMA_WHITESPACE_PRESERVE) {
+
+ if (yws == XML_SCHEMA_WHITESPACE_PRESERVE) {
+ /* TODO: What about x < y or x > y. */
+ if (xmlStrEqual(x->value.str, y->value.str))
+ return (0);
+ else
+ return (2);
+ } else if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
+ return (xmlSchemaComparePreserveReplaceStrings(x, y, 0));
+ else if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+ return (xmlSchemaComparePreserveCollapseStrings(x, y, 0));
+
+ } else if (xws == XML_SCHEMA_WHITESPACE_REPLACE) {
+
+ if (yws == XML_SCHEMA_WHITESPACE_PRESERVE)
+ return (xmlSchemaComparePreserveReplaceStrings(y, x, 1));
+ if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
+ return (xmlSchemaCompareReplacedStrings(x, y));
+ if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+ return (xmlSchemaCompareReplaceCollapseStrings(x, y, 0));
+
+ } else if (xws == XML_SCHEMA_WHITESPACE_COLLAPSE) {
+
+ if (yws == XML_SCHEMA_WHITESPACE_PRESERVE)
+ return (xmlSchemaComparePreserveCollapseStrings(y, x, 1));
+ if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
+ return (xmlSchemaCompareReplaceCollapseStrings(y, x, 1));
+ if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+ return (xmlSchemaCompareNormStrings(x, y));
+ } else
+ return (-2);
+
+ }
return (-2);
case XML_SCHEMAS_QNAME:
if (y->type == XML_SCHEMAS_QNAME) {
@@ -3754,8 +4165,7 @@
else
return(-1);
}
- return (-2);
- case XML_SCHEMAS_STRING:
+ return (-2);
case XML_SCHEMAS_IDREFS:
case XML_SCHEMAS_ENTITIES:
case XML_SCHEMAS_NMTOKENS:
@@ -3766,6 +4176,57 @@
}
/**
+ * xmlSchemaCompareValues:
+ * @x: a first value
+ * @y: a second value
+ *
+ * Compare 2 values
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
+ * case of error
+ */
+int
+xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
+ xmlSchemaWhitespaceValueType xws, yws;
+
+ if (x->type == XML_SCHEMAS_STRING)
+ xws = XML_SCHEMA_WHITESPACE_PRESERVE;
+ else if (x->type == XML_SCHEMAS_NORMSTRING)
+ xws = XML_SCHEMA_WHITESPACE_REPLACE;
+ else
+ xws = XML_SCHEMA_WHITESPACE_COLLAPSE;
+
+ if (y->type == XML_SCHEMAS_STRING)
+ yws = XML_SCHEMA_WHITESPACE_PRESERVE;
+ else if (x->type == XML_SCHEMAS_NORMSTRING)
+ yws = XML_SCHEMA_WHITESPACE_REPLACE;
+ else
+ yws = XML_SCHEMA_WHITESPACE_COLLAPSE;
+
+ return(xmlSchemaCompareValuesInternal(x, xws, y, yws));
+}
+
+/**
+ * xmlSchemaCompareValuesWhtsp:
+ * @x: a first value
+ * @xws: the whitespace value of x
+ * @y: a second value
+ * @yws: the whitespace value of y
+ *
+ * Compare 2 values
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
+ * case of error
+ */
+int
+xmlSchemaCompareValuesWhtsp(xmlSchemaValPtr x,
+ xmlSchemaWhitespaceValueType xws,
+ xmlSchemaValPtr y,
+ xmlSchemaWhitespaceValueType yws) {
+ return(xmlSchemaCompareValuesInternal(x, xws, y, yws));
+}
+
+/**
* xmlSchemaNormLen:
* @value: a string
*
@@ -4138,4 +4599,51 @@
}
+/**
+ * xmlSchemaGetCanonValue:
+ * @val: the precomputed value
+ * @retValue: the returned value
+ *
+ * Returns a the cononical representation of the value.
+ * The called has to free the returned retValue.
+ *
+ * Returns 0 if the value could be built and -1 in case of
+ * API errors or if the value type is not supported yet.
+ */
+int
+xmlSchemaGetCanonValue(xmlSchemaValPtr val,
+ const xmlChar **retValue)
+{
+ if (retValue == NULL)
+ return (-1);
+ *retValue = NULL;
+ switch (val->type) {
+ case XML_SCHEMAS_STRING:
+ case XML_SCHEMAS_NORMSTRING:
+ /*
+ case XML_SCHEMAS_TOKEN:
+ case XML_SCHEMAS_LANGUAGE:
+ case XML_SCHEMAS_NMTOKEN:
+ case XML_SCHEMAS_NAME:
+ case XML_SCHEMAS_QNAME:
+ case XML_SCHEMAS_NCNAME:
+ case XML_SCHEMAS_ID:
+ case XML_SCHEMAS_IDREF:
+ case XML_SCHEMAS_ENTITY:
+ case XML_SCHEMAS_NOTATION:
+ case XML_SCHEMAS_ANYURI:
+ */
+ if (val->value.str == NULL)
+ *retValue = NULL;
+ else
+ /* TODO: This is not yet correct for non-normalized values. */
+ *retValue =
+ BAD_CAST xmlStrdup((const xmlChar *) val->value.str);
+ return (0);
+ default:
+ return (-1);
+ }
+ return (-1);
+}
+
#endif /* LIBXML_SCHEMAS_ENABLED */