mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-03-10 08:58:16 +03:00
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".
This commit is contained in:
parent
bd2a7d169b
commit
6e224f1272
11
ChangeLog
11
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
|
||||
|
@ -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 @@ XMLPUBFUN int XMLCALL
|
||||
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
|
||||
}
|
||||
|
128
xmlschemas.c
128
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 @@ static const xmlChar *xmlSchemaElemDesCT = (const xmlChar *)
|
||||
((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 @@ struct _xmlSchemaIDCMatcher {
|
||||
xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
|
||||
elements */
|
||||
int sizeKeySeqs;
|
||||
xmlSchemaPSVIIDCKeyPtr **refKeySeqs;
|
||||
int nbRefKeySeqs;
|
||||
int sizeRefKeySeqs;
|
||||
int targetDepth;
|
||||
};
|
||||
|
||||
@ -10268,7 +10267,7 @@ xmlSchemaIsDerivedFromBuiltInType(xmlSchemaParserCtxtPtr ctxt,
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlSchemaIsDerivedFromBuiltInType:
|
||||
* xmlSchemaGetPrimitiveType:
|
||||
* @type: the simpleType definition
|
||||
*
|
||||
* Returns the primitive type of the given type or
|
||||
@ -10286,6 +10285,25 @@ xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
|
||||
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 @@ xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
|
||||
return ("Internal Error");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
|
||||
{
|
||||
@ -14776,24 +14792,24 @@ xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
|
||||
*/
|
||||
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 @@ xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
|
||||
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 @@ xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
|
||||
}
|
||||
anc = anc->baseType;
|
||||
} while (anc != anyST);
|
||||
return (XML_SCHEMAS_VAL_WTSP_COLLAPSE);
|
||||
return (XML_SCHEMAS_FACET_COLLAPSE);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
@ -15667,11 +15676,11 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
|
||||
* 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 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
|
||||
}
|
||||
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 @@ compareValue:
|
||||
{
|
||||
#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 @@ xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
|
||||
* 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 @@ xmlSchemaValidateElementByDeclaration(xmlSchemaValidCtxtPtr ctxt,
|
||||
XML_SCHEMAV_INTERNAL,
|
||||
elem, actualType,
|
||||
"Internal error: xmlSchemaValidateElementByDeclaration, "
|
||||
"validating a default value", NULL);
|
||||
"calling validation by type", NULL);
|
||||
return (-1);
|
||||
}
|
||||
/*
|
||||
@ -19083,7 +19107,6 @@ xmlSchemaValidateElementByType(xmlSchemaValidCtxtPtr ctxt,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr ctxt,
|
||||
xmlSchemaAttrStatePtr state)
|
||||
@ -19126,6 +19149,10 @@ xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr ctxt,
|
||||
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 @@ xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr ctxt,
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,11 @@ extern double xmlXPathNINF;
|
||||
#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,
|
||||
@ -676,6 +681,34 @@ xmlSchemaNewValue(xmlSchemaValType type) {
|
||||
return(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
|
||||
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)) {
|
||||
@ -3477,6 +3514,333 @@ xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -3605,15 +3969,20 @@ xmlSchemaCompareFloats(xmlSchemaValPtr x, xmlSchemaValPtr y) {
|
||||
/**
|
||||
* 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 @@ xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
|
||||
(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 @@ xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
|
||||
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 @@ xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
|
||||
else
|
||||
return(-1);
|
||||
}
|
||||
return (-2);
|
||||
case XML_SCHEMAS_STRING:
|
||||
return (-2);
|
||||
case XML_SCHEMAS_IDREFS:
|
||||
case XML_SCHEMAS_ENTITIES:
|
||||
case XML_SCHEMAS_NMTOKENS:
|
||||
@ -3765,6 +4175,57 @@ xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user