aboutsummaryrefslogtreecommitdiffstats
path: root/xmlschemastypes.c
diff options
context:
space:
mode:
authorKasimier T. Buchcik <kbuchcik@src.gnome.org>2005-04-18 10:57:04 +0000
committerKasimier T. Buchcik <kbuchcik@src.gnome.org>2005-04-18 10:57:04 +0000
commitc872afbd82e904c45f2f7f6b929b5f9beeefc07b (patch)
treeaed822f491e9faa34c563604e8eefa8128f35d26 /xmlschemastypes.c
parentd6e347e865b473f06fd431be926183c77596194a (diff)
downloadandroid_external_libxml2-c872afbd82e904c45f2f7f6b929b5f9beeefc07b.tar.gz
android_external_libxml2-c872afbd82e904c45f2f7f6b929b5f9beeefc07b.tar.bz2
android_external_libxml2-c872afbd82e904c45f2f7f6b929b5f9beeefc07b.zip
Added output of canonical values in identity-constraint error messages.
* xmlschemas.c: Added output of canonical values in identity-constraint error messages. * xmlschemastypes.c include/libxml/xmlschemastypes.h: Added xmlSchemaGetCanonValueWhtsp() to the API. Further enhancement of the canonical value conversion. * test/schemas/changelog093_0.*: Added test with an XSD submitted by Randy J. Ray.
Diffstat (limited to 'xmlschemastypes.c')
-rw-r--r--xmlschemastypes.c548
1 files changed, 517 insertions, 31 deletions
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index 52dceaae..2b629bd2 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -28,6 +28,9 @@
#ifdef HAVE_MATH_H
#include <math.h>
#endif
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
#define DEBUG
@@ -1550,7 +1553,7 @@ xmlSchemaValidateDuration (xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
break; /* exit loop */
}
/* no date designators found? */
- if (++seq == 3)
+ if ((++seq == 3) || (seq == 6))
goto error;
}
cur++;
@@ -1907,25 +1910,36 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
* and note the position of any decimal point.
*/
len = 0;
- while (len < 24) {
- if ((*cur >= '0') && (*cur <= '9')) {
- *cptr++ = *cur;
- len++;
- } else if (*cur == '.') {
- if (dec != -1)
- goto return1; /* multiple decimal points */
- if (!len) { /* num starts with '.' */
- *cptr++ = '0';
- len++;
- }
- dec = len++;
- } else
- break;
+ /*
+ * Skip leading zeroes.
+ */
+ while (*cur == '0')
cur++;
+ if (*cur != 0) {
+ while (len < 24) {
+ if ((*cur >= '0') && (*cur <= '9')) {
+ *cptr++ = *cur++;
+ len++;
+ } else if (*cur == '.') {
+ if (dec != -1)
+ goto return1; /* multiple decimal points */
+ cur++;
+ if ((*cur == 0) && (cur -1 == value))
+ goto return1;
+
+ dec = len;
+ while ((len < 24) && (*cur >= '0') &&
+ (*cur <= '9')) {
+ *cptr++ = *cur++;
+ len++;
+ }
+ break;
+ } else
+ break;
+ }
}
if (*cur != 0)
goto return1; /* error if any extraneous chars */
-
if (val != NULL) {
v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL);
if (v != NULL) {
@@ -1943,17 +1957,23 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
/*
* Now evaluate the significant digits of the number
*/
- xmlSchemaParseUInt((const xmlChar **)&cptr,
+ if (*cptr != 0)
+ xmlSchemaParseUInt((const xmlChar **)&cptr,
&v->value.decimal.lo,
&v->value.decimal.mi,
&v->value.decimal.hi);
+ /*
+ * Set the total digits to 1 if a zero value.
+ */
+ if (len == 0)
+ len++;
v->value.decimal.sign = neg;
if (dec == -1) {
v->value.decimal.frac = 0;
v->value.decimal.total = len;
} else {
- v->value.decimal.frac = len - dec - 1;
- v->value.decimal.total = len - 1;
+ v->value.decimal.frac = len - dec;
+ v->value.decimal.total = len;
}
*val = v;
}
@@ -2675,6 +2695,8 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
if (val != NULL) {
v = xmlSchemaNewValue(type->builtInType);
if (v != NULL) {
+ if (ret == 0)
+ ret++;
v->value.decimal.lo = lo;
v->value.decimal.mi = mi;
v->value.decimal.hi = hi;
@@ -3364,7 +3386,8 @@ xmlSchemaDateNormalize (xmlSchemaValPtr dt, double offset)
return NULL;
if (((dt->type != XML_SCHEMAS_TIME) &&
- (dt->type != XML_SCHEMAS_DATETIME)) || (dt->value.date.tzo == 0))
+ (dt->type != XML_SCHEMAS_DATETIME) &&
+ (dt->type != XML_SCHEMAS_DATE)) || (dt->value.date.tzo == 0))
return xmlSchemaDupVal(dt);
dur = xmlSchemaNewValue(XML_SCHEMAS_DURATION);
@@ -4213,7 +4236,6 @@ xmlSchemaCompareValuesInternal(xmlSchemaValType xtype,
case XML_SCHEMAS_ID:
case XML_SCHEMAS_IDREF:
case XML_SCHEMAS_ENTITY:
- case XML_SCHEMAS_NOTATION:
case XML_SCHEMAS_ANYURI:
{
const xmlChar *xv, *yv;
@@ -4286,9 +4308,11 @@ xmlSchemaCompareValuesInternal(xmlSchemaValType xtype,
return (-2);
}
case XML_SCHEMAS_QNAME:
+ case XML_SCHEMAS_NOTATION:
if ((x == NULL) || (y == NULL))
return(-2);
- if (ytype == XML_SCHEMAS_QNAME) {
+ if ((ytype == XML_SCHEMAS_QNAME) ||
+ (ytype == XML_SCHEMAS_NOTATION)) {
if ((xmlStrEqual(x->value.qname.name, y->value.qname.name)) &&
(xmlStrEqual(x->value.qname.uri, y->value.qname.uri)))
return(0);
@@ -5003,18 +5027,104 @@ xmlSchemaValidateFacetWhtsp(xmlSchemaFacetPtr facet,
value, val, ws));
}
+#if 0
+#ifndef DBL_DIG
+#define DBL_DIG 16
+#endif
+#ifndef DBL_EPSILON
+#define DBL_EPSILON 1E-9
+#endif
+
+#define INTEGER_DIGITS DBL_DIG
+#define FRACTION_DIGITS (DBL_DIG + 1)
+#define EXPONENT_DIGITS (3 + 2)
+
+/**
+ * xmlXPathFormatNumber:
+ * @number: number to format
+ * @buffer: output buffer
+ * @buffersize: size of output buffer
+ *
+ * Convert the number into a string representation.
+ */
+static void
+xmlSchemaFormatFloat(double number, char buffer[], int buffersize)
+{
+ switch (xmlXPathIsInf(number)) {
+ case 1:
+ if (buffersize > (int)sizeof("INF"))
+ snprintf(buffer, buffersize, "INF");
+ break;
+ case -1:
+ if (buffersize > (int)sizeof("-INF"))
+ snprintf(buffer, buffersize, "-INF");
+ break;
+ default:
+ if (xmlXPathIsNaN(number)) {
+ if (buffersize > (int)sizeof("NaN"))
+ snprintf(buffer, buffersize, "NaN");
+ } else if (number == 0) {
+ snprintf(buffer, buffersize, "0.0E0");
+ } else {
+ /* 3 is sign, decimal point, and terminating zero */
+ char work[DBL_DIG + EXPONENT_DIGITS + 3];
+ int integer_place, fraction_place;
+ char *ptr;
+ char *after_fraction;
+ double absolute_value;
+ int size;
+
+ absolute_value = fabs(number);
+
+ /*
+ * Result is in work, and after_fraction points
+ * just past the fractional part.
+ * Use scientific notation
+ */
+ integer_place = DBL_DIG + EXPONENT_DIGITS + 1;
+ fraction_place = DBL_DIG - 1;
+ snprintf(work, sizeof(work),"%*.*e",
+ integer_place, fraction_place, number);
+ after_fraction = strchr(work + DBL_DIG, 'e');
+ /* Remove fractional trailing zeroes */
+ ptr = after_fraction;
+ while (*(--ptr) == '0')
+ ;
+ if (*ptr != '.')
+ ptr++;
+ while ((*ptr++ = *after_fraction++) != 0);
+
+ /* Finally copy result back to caller */
+ size = strlen(work) + 1;
+ if (size > buffersize) {
+ work[buffersize - 1] = 0;
+ size = buffersize;
+ }
+ memmove(buffer, work, size);
+ }
+ break;
+ }
+}
+#endif
+
/**
* xmlSchemaGetCanonValue:
* @val: the precomputed value
* @retValue: the returned value
*
* Get a the cononical lexical representation of the value.
- * The caller has to free the returned retValue.
+ * The caller has to FREE the returned retValue.
+ *
* WARNING: Some value types are not supported yet, resulting
* in a @retValue of "???".
+ *
+ * TODO: XML Schema 1.0 does not define canonical representations
+ * for: duration, gYearMonth, gYear, gMonthDay, gMonth, gDay,
+ * anyURI, QName, NOTATION. This will be fixed in XML Schema 1.1.
+ *
*
- * Returns 0 if the value could be built and -1 in case of
- * API errors.
+ * Returns 0 if the value could be built, 1 if the value type is
+ * not supported yet and -1 in case of API errors.
*/
int
xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue)
@@ -5049,8 +5159,8 @@ xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue)
case XML_SCHEMAS_ID:
case XML_SCHEMAS_IDREF:
case XML_SCHEMAS_ENTITY:
- case XML_SCHEMAS_NOTATION:
- case XML_SCHEMAS_ANYURI:
+ case XML_SCHEMAS_NOTATION: /* Unclear */
+ case XML_SCHEMAS_ANYURI: /* Unclear */
if (val->value.str == NULL)
return (-1);
*retValue =
@@ -5060,9 +5170,7 @@ xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue)
BAD_CAST xmlStrdup((const xmlChar *) val->value.str);
break;
case XML_SCHEMAS_QNAME:
- /*
- * TODO: What exactly to do with QNames?
- */
+ /* TODO: Unclear in XML Schema 1.0. */
if (val->value.qname.uri == NULL) {
*retValue = BAD_CAST xmlStrdup(BAD_CAST val->value.qname.name);
return (0);
@@ -5076,14 +5184,392 @@ xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue)
BAD_CAST val->value.qname.uri);
}
break;
+ case XML_SCHEMAS_DECIMAL:
+ /*
+ * TODO: Lookout for a more simple implementation.
+ */
+ if ((val->value.decimal.total == 1) &&
+ (val->value.decimal.lo == 0)) {
+ *retValue = xmlStrdup(BAD_CAST "0.0");
+ } else {
+ xmlSchemaValDecimal dec = val->value.decimal;
+ int bufsize;
+ char *buf = NULL, *offs;
+
+ /* Add room for the decimal point as well. */
+ bufsize = dec.total + 2;
+ if (dec.sign)
+ bufsize++;
+ /* Add room for leading/trailing zero. */
+ if ((dec.frac == 0) || (dec.frac == dec.total))
+ bufsize++;
+ buf = xmlMalloc(bufsize);
+ offs = buf;
+ if (dec.sign)
+ *offs++ = '-';
+ if (dec.frac == dec.total) {
+ *offs++ = '0';
+ *offs++ = '.';
+ }
+ if (dec.hi != 0)
+ snprintf(offs, bufsize - (offs - buf),
+ "%lu%lu%lu", dec.hi, dec.mi, dec.lo);
+ else if (dec.mi != 0)
+ snprintf(offs, bufsize - (offs - buf),
+ "%lu%lu", dec.mi, dec.lo);
+ else
+ snprintf(offs, bufsize - (offs - buf),
+ "%lu", dec.lo);
+
+ if (dec.frac != 0) {
+ if (dec.frac != dec.total) {
+ int diff = dec.total - dec.frac;
+ /*
+ * Insert the decimal point.
+ */
+ memmove(offs + diff + 1, offs + diff, dec.frac +1);
+ offs[diff] = '.';
+ } else {
+ unsigned int i = 0;
+ /*
+ * Insert missing zeroes behind the decimal point.
+ */
+ while (*(offs + i) != 0)
+ i++;
+ if (i < dec.total) {
+ memmove(offs + (dec.total - i), offs, i +1);
+ memset(offs, '0', dec.total - i);
+ }
+ }
+ } else {
+ /*
+ * Append decimal point and zero.
+ */
+ offs = buf + bufsize - 1;
+ *offs-- = 0;
+ *offs-- = '0';
+ *offs-- = '.';
+ }
+ *retValue = BAD_CAST buf;
+ }
+ break;
+ case XML_SCHEMAS_INTEGER:
+ case XML_SCHEMAS_PINTEGER:
+ case XML_SCHEMAS_NPINTEGER:
+ case XML_SCHEMAS_NINTEGER:
+ case XML_SCHEMAS_NNINTEGER:
+ case XML_SCHEMAS_LONG:
+ case XML_SCHEMAS_BYTE:
+ case XML_SCHEMAS_SHORT:
+ case XML_SCHEMAS_INT:
+ case XML_SCHEMAS_UINT:
+ case XML_SCHEMAS_ULONG:
+ case XML_SCHEMAS_USHORT:
+ case XML_SCHEMAS_UBYTE:
+ if ((val->value.decimal.total == 1) &&
+ (val->value.decimal.lo == 0))
+ *retValue = xmlStrdup(BAD_CAST "0");
+ else {
+ xmlSchemaValDecimal dec = val->value.decimal;
+ int bufsize = dec.total + 1;
+
+ /* Add room for the decimal point as well. */
+ if (dec.sign)
+ bufsize++;
+ *retValue = xmlMalloc(bufsize);
+ if (dec.hi != 0) {
+ if (dec.sign)
+ snprintf((char *) *retValue, bufsize,
+ "-%lu%lu%lu", dec.hi, dec.mi, dec.lo);
+ else
+ snprintf((char *) *retValue, bufsize,
+ "%lu%lu%lu", dec.hi, dec.mi, dec.lo);
+ } else if (dec.mi != 0) {
+ if (dec.sign)
+ snprintf((char *) *retValue, bufsize,
+ "-%lu%lu", dec.mi, dec.lo);
+ else
+ snprintf((char *) *retValue, bufsize,
+ "%lu%lu", dec.mi, dec.lo);
+ } else {
+ if (dec.sign)
+ snprintf((char *) *retValue, bufsize, "-%lu", dec.lo);
+ else
+ snprintf((char *) *retValue, bufsize, "%lu", dec.lo);
+ }
+ }
+ break;
+ case XML_SCHEMAS_BOOLEAN:
+ if (val->value.b)
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST "true");
+ else
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST "false");
+ break;
+ case XML_SCHEMAS_DURATION: {
+ char buf[100];
+ unsigned long year;
+ unsigned long mon, day, hour = 0, min = 0;
+ double sec = 0, left;
+
+ /* TODO: Unclear in XML Schema 1.0 */
+ /*
+ * TODO: This results in a normalized output of the value
+ * - which is NOT conformant to the spec -
+ * since the exact values of each property are not
+ * recoverable. Think about extending the structure to
+ * provide a field for every property.
+ */
+ year = (unsigned long) FQUOTIENT(labs(val->value.dur.mon), 12);
+ mon = labs(val->value.dur.mon) - 12 * year;
+
+ day = (unsigned long) FQUOTIENT(fabs(val->value.dur.sec), 86400);
+ left = fabs(val->value.dur.sec) - day * 86400;
+ if (left > 0) {
+ hour = (unsigned long) FQUOTIENT(left, 3600);
+ left = left - (hour * 3600);
+ if (left > 0) {
+ min = (unsigned long) FQUOTIENT(left, 60);
+ sec = left - (min * 60);
+ }
+ }
+ if ((val->value.dur.mon < 0) || (val->value.dur.sec < 0))
+ snprintf(buf, 100, "P%luY%luM%luDT%luH%luM%.14gS",
+ year, mon, day, hour, min, sec);
+ else
+ snprintf(buf, 100, "-P%luY%luM%luDT%luH%luM%.14gS",
+ year, mon, day, hour, min, sec);
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+ }
+ break;
+ case XML_SCHEMAS_GYEAR: {
+ char buf[30];
+ /* TODO: Unclear in XML Schema 1.0 */
+ /* TODO: What to do with the timezone? */
+ snprintf(buf, 30, "%04ld", val->value.date.year);
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+ }
+ break;
+ case XML_SCHEMAS_GMONTH: {
+ /* TODO: Unclear in XML Schema 1.0 */
+ /* TODO: What to do with the timezone? */
+ *retValue = xmlMalloc(5);
+ snprintf((char *) *retValue, 6, "--%02u",
+ val->value.date.mon);
+ }
+ break;
+ case XML_SCHEMAS_GDAY: {
+ /* TODO: Unclear in XML Schema 1.0 */
+ /* TODO: What to do with the timezone? */
+ *retValue = xmlMalloc(6);
+ snprintf((char *) *retValue, 6, "---%02u",
+ val->value.date.day);
+ }
+ break;
+ case XML_SCHEMAS_GMONTHDAY: {
+ /* TODO: Unclear in XML Schema 1.0 */
+ /* TODO: What to do with the timezone? */
+ *retValue = xmlMalloc(8);
+ snprintf((char *) *retValue, 8, "--%02u-%02u",
+ val->value.date.mon, val->value.date.day);
+ }
+ break;
+ case XML_SCHEMAS_GYEARMONTH: {
+ char buf[35];
+ /* TODO: Unclear in XML Schema 1.0 */
+ /* TODO: What to do with the timezone? */
+ if (val->value.date.year < 0)
+ snprintf(buf, 35, "-%04ld-%02u",
+ labs(val->value.date.year),
+ val->value.date.mon);
+ else
+ snprintf(buf, 35, "%04ld-%02u",
+ val->value.date.year, val->value.date.mon);
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+ }
+ break;
+ case XML_SCHEMAS_TIME:
+ {
+ char buf[30];
+
+ if (val->value.date.tz_flag) {
+ xmlSchemaValPtr norm;
+
+ norm = xmlSchemaDateNormalize(val, 0);
+ if (norm == NULL)
+ return (-1);
+ /*
+ * TODO: Check if "%.14g" is portable.
+ */
+ snprintf(buf, 30,
+ "%02u:%02u:%02.14gZ",
+ norm->value.date.hour,
+ norm->value.date.min,
+ norm->value.date.sec);
+ xmlSchemaFreeValue(norm);
+ } else {
+ snprintf(buf, 30,
+ "%02u:%02u:%02.14g",
+ val->value.date.hour,
+ val->value.date.min,
+ val->value.date.sec);
+ }
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+ }
+ break;
+ case XML_SCHEMAS_DATE:
+ {
+ char buf[30];
+
+ if (val->value.date.tz_flag) {
+ xmlSchemaValPtr norm;
+
+ norm = xmlSchemaDateNormalize(val, 0);
+ if (norm == NULL)
+ return (-1);
+ /*
+ * TODO: Append the canonical value of the
+ * recoverable timezone and not "Z".
+ */
+ snprintf(buf, 30,
+ "%04ld:%02u:%02uZ",
+ norm->value.date.year, norm->value.date.mon,
+ norm->value.date.day);
+ xmlSchemaFreeValue(norm);
+ } else {
+ snprintf(buf, 30,
+ "%04ld:%02u:%02u",
+ val->value.date.year, val->value.date.mon,
+ val->value.date.day);
+ }
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+ }
+ break;
+ case XML_SCHEMAS_DATETIME:
+ {
+ char buf[50];
+
+ if (val->value.date.tz_flag) {
+ xmlSchemaValPtr norm;
+
+ norm = xmlSchemaDateNormalize(val, 0);
+ if (norm == NULL)
+ return (-1);
+ /*
+ * TODO: Check if "%.14g" is portable.
+ */
+ snprintf(buf, 50,
+ "%04ld:%02u:%02uT%02u:%02u:%02.14gZ",
+ norm->value.date.year, norm->value.date.mon,
+ norm->value.date.day, norm->value.date.hour,
+ norm->value.date.min, norm->value.date.sec);
+ xmlSchemaFreeValue(norm);
+ } else {
+ snprintf(buf, 50,
+ "%04ld:%02u:%02uT%02u:%02u:%02.14g",
+ val->value.date.year, val->value.date.mon,
+ val->value.date.day, val->value.date.hour,
+ val->value.date.min, val->value.date.sec);
+ }
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+ }
+ break;
+ case XML_SCHEMAS_HEXBINARY:
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST val->value.hex.str);
+ break;
+ case XML_SCHEMAS_BASE64BINARY:
+ /*
+ * TODO: Is the following spec piece implemented?:
+ * SPEC: "Note: For some values the canonical form defined
+ * above does not conform to [RFC 2045], which requires breaking
+ * with linefeeds at appropriate intervals."
+ */
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST val->value.base64.str);
+ break;
+ case XML_SCHEMAS_FLOAT: {
+ char buf[30];
+ /*
+ * |m| < 16777216, -149 <= e <= 104.
+ * TODO: Handle, NaN, INF, -INF. The format is not
+ * yet conformant. The c type float does not cover
+ * the whole range.
+ */
+ snprintf(buf, 30, "%01.14e", val->value.f);
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+ }
+ break;
+ case XML_SCHEMAS_DOUBLE: {
+ char buf[40];
+ /* |m| < 9007199254740992, -1075 <= e <= 970 */
+ /*
+ * TODO: Handle, NaN, INF, -INF. The format is not
+ * yet conformant. The c type float does not cover
+ * the whole range.
+ */
+ snprintf(buf, 40, "%01.14e", val->value.d);
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+ }
+ break;
default:
*retValue = BAD_CAST xmlStrdup(BAD_CAST "???");
- break;
+ return (1);
}
return (0);
}
/**
+ * xmlSchemaGetCanonValueWhtsp:
+ * @val: the precomputed value
+ * @retValue: the returned value
+ * @ws: the whitespace type of the value
+ *
+ * Get a the cononical representation of the value.
+ * The caller has to free the returned @retValue.
+ *
+ * Returns 0 if the value could be built, 1 if the value type is
+ * not supported yet and -1 in case of API errors.
+ */
+int
+xmlSchemaGetCanonValueWhtsp(xmlSchemaValPtr val,
+ const xmlChar **retValue,
+ xmlSchemaWhitespaceValueType ws)
+{
+ if ((retValue == NULL) || (val == NULL))
+ return (-1);
+ if ((ws == XML_SCHEMA_WHITESPACE_UNKNOWN) ||
+ (ws > XML_SCHEMA_WHITESPACE_COLLAPSE))
+ return (-1);
+
+ *retValue = NULL;
+ switch (val->type) {
+ case XML_SCHEMAS_STRING:
+ if (val->value.str == NULL)
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST "");
+ else if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+ *retValue = xmlSchemaCollapseString(val->value.str);
+ else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
+ *retValue = xmlSchemaWhiteSpaceReplace(val->value.str);
+ if ((*retValue) == NULL)
+ *retValue = BAD_CAST xmlStrdup(val->value.str);
+ break;
+ case XML_SCHEMAS_NORMSTRING:
+ if (val->value.str == NULL)
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST "");
+ else {
+ if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+ *retValue = xmlSchemaCollapseString(val->value.str);
+ else
+ *retValue = xmlSchemaWhiteSpaceReplace(val->value.str);
+ if ((*retValue) == NULL)
+ *retValue = BAD_CAST xmlStrdup(val->value.str);
+ }
+ break;
+ default:
+ return (xmlSchemaGetCanonValue(val, retValue));
+ }
+ return (0);
+}
+
+/**
* xmlSchemaGetValType:
* @val: a schemas value
*