mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2024-10-26 12:25:09 +03:00
Some changes/fixes to the streaming evaluation. A bit of support for
* pattern.c: Some changes/fixes to the streaming evaluation. * xmlschemas.c: A bit of support for parsing the schema for schema. Fixed attribute derivation when the use is "prohibited" and was "optional". Fixed an attribute construction bug, a left-over from the time, where <complexContent>, <extension>, etc. where created as structs.
This commit is contained in:
parent
9ea5565f41
commit
9ca11bfc3d
@ -1,3 +1,12 @@
|
||||
Tue Jun 14 21:19:16 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
|
||||
|
||||
* pattern.c: Some changes/fixes to the streaming evaluation.
|
||||
* xmlschemas.c: A bit of support for parsing the schema for
|
||||
schema. Fixed attribute derivation when the use is
|
||||
"prohibited" and was "optional". Fixed an attribute construction
|
||||
bug, a left-over from the time, where <complexContent>,
|
||||
<extension>, etc. where created as structs.
|
||||
|
||||
Tue Jun 14 12:35:12 CEST 2005 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* libxml-2.0.pc.in: removed a redundant include path
|
||||
|
293
pattern.c
293
pattern.c
@ -38,7 +38,6 @@
|
||||
#ifdef LIBXML_PATTERN_ENABLED
|
||||
|
||||
/* #define DEBUG_STREAMING */
|
||||
#define SUPPORT_IDC
|
||||
|
||||
#define ERROR(a, b, c, d)
|
||||
#define ERROR5(a, b, c, d, e)
|
||||
@ -48,10 +47,18 @@
|
||||
#define XML_STREAM_STEP_ROOT 4
|
||||
#define XML_STREAM_STEP_ATTR 8
|
||||
|
||||
/*
|
||||
* TODO: This is used on _xmlStreamCtxt, so don't use any values
|
||||
* from xmlPatternFlags.
|
||||
*/
|
||||
#define XML_STREAM_DESC 1<<16
|
||||
|
||||
#define XML_PATTERN_NOTPATTERN (XML_PATTERN_XPATH | \
|
||||
XML_PATTERN_XSSEL | \
|
||||
XML_PATTERN_XSFIELD)
|
||||
#define XML_PATTERN_XSD (XML_PATTERN_XSSEL | XML_PATTERN_XSFIELD)
|
||||
|
||||
#define XML_STREAM_XS_IDC(item) (item->flags & \
|
||||
(XML_PATTERN_XSSEL | XML_PATTERN_XSFIELD))
|
||||
|
||||
typedef struct _xmlStreamStep xmlStreamStep;
|
||||
typedef xmlStreamStep *xmlStreamStepPtr;
|
||||
@ -68,6 +75,7 @@ struct _xmlStreamComp {
|
||||
int nbStep; /* number of steps in the automata */
|
||||
int maxStep; /* allocated number of steps */
|
||||
xmlStreamStepPtr steps; /* the array of steps */
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct _xmlStreamCtxt {
|
||||
@ -78,6 +86,7 @@ struct _xmlStreamCtxt {
|
||||
int level; /* how deep are we ? */
|
||||
int *states; /* the array of step indexes */
|
||||
int flags; /* validation options */
|
||||
int blockLevel;
|
||||
};
|
||||
|
||||
static void xmlFreeStreamComp(xmlStreamCompPtr comp);
|
||||
@ -879,6 +888,7 @@ xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
|
||||
if (name == NULL) {
|
||||
if (CUR == '*') {
|
||||
PUSH(XML_OP_ATTR, NULL, NULL);
|
||||
NEXT;
|
||||
} else {
|
||||
ERROR(NULL, NULL, NULL,
|
||||
"xmlCompileAttributeTest : Name expected\n");
|
||||
@ -1122,7 +1132,7 @@ error:
|
||||
static void
|
||||
xmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
|
||||
SKIP_BLANKS;
|
||||
if (CUR == '/') {
|
||||
if ((CUR == '/') && (NXT(1) != '/')) {
|
||||
ctxt->comp->flags |= PAT_FROM_ROOT;
|
||||
} else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) {
|
||||
ctxt->comp->flags |= PAT_FROM_CUR;
|
||||
@ -1429,8 +1439,27 @@ xmlStreamCompile(xmlPatternPtr comp) {
|
||||
break;
|
||||
case XML_OP_ANCESTOR:
|
||||
flags |= XML_STREAM_STEP_DESC;
|
||||
/*
|
||||
* Mark the expression as having "//".
|
||||
*/
|
||||
if ((stream->flags & XML_STREAM_DESC) == 0)
|
||||
stream->flags |= XML_STREAM_DESC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((! root) && (comp->flags & XML_PATTERN_NOTPATTERN) == 0) {
|
||||
/*
|
||||
* If this should behave like a real pattern, we will mark
|
||||
* the first step as having "//", to be reentrant on every
|
||||
* tree level.
|
||||
*/
|
||||
if ((stream->flags & XML_STREAM_DESC) == 0)
|
||||
stream->flags |= XML_STREAM_DESC;
|
||||
|
||||
if (stream->nbStep > 0) {
|
||||
if ((stream->steps[0].flags & XML_STREAM_STEP_DESC) == 0)
|
||||
stream->steps[0].flags |= XML_STREAM_STEP_DESC;
|
||||
}
|
||||
}
|
||||
stream->steps[s].flags |= XML_STREAM_STEP_FINAL;
|
||||
if (root)
|
||||
@ -1475,6 +1504,7 @@ xmlNewStreamCtxt(xmlStreamCompPtr stream) {
|
||||
cur->maxState = 4;
|
||||
cur->level = 0;
|
||||
cur->comp = stream;
|
||||
cur->blockLevel = -1;
|
||||
return(cur);
|
||||
}
|
||||
|
||||
@ -1568,6 +1598,7 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream,
|
||||
if ((name == NULL) && (ns == NULL)) {
|
||||
stream->nbState = 0;
|
||||
stream->level = 0;
|
||||
stream->blockLevel = -1;
|
||||
if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
|
||||
tmp = xmlStreamCtxtAddState(stream, 0, 0);
|
||||
if (tmp < 0)
|
||||
@ -1596,47 +1627,68 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream,
|
||||
stream->level++;
|
||||
goto stream_next;
|
||||
}
|
||||
if ((stream->flags & XML_PATTERN_NOTPATTERN) != 0) {
|
||||
tmp = stream->level;
|
||||
for (i = 0; i < comp->nbStep; i++) {
|
||||
if (comp->steps[i].flags & XML_STREAM_STEP_DESC) {
|
||||
tmp = -2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (comp->nbStep <= tmp) {
|
||||
stream->level++;
|
||||
goto stream_next;
|
||||
}
|
||||
|
||||
if (stream->blockLevel != -1) {
|
||||
/*
|
||||
* Skip blocked expressions.
|
||||
*/
|
||||
stream->level++;
|
||||
goto stream_next;
|
||||
}
|
||||
/*
|
||||
* Check evolution of existing states
|
||||
*/
|
||||
i = 0;
|
||||
m = stream->nbState;
|
||||
for (i = 0;i < m;i++) {
|
||||
match = 0;
|
||||
step = stream->states[2 * i];
|
||||
/* dead states */
|
||||
if (step < 0) continue;
|
||||
/* skip new states just added */
|
||||
if (stream->states[(2 * i) + 1] > stream->level)
|
||||
continue;
|
||||
/* skip continuations */
|
||||
desc = comp->steps[step].flags & XML_STREAM_STEP_DESC;
|
||||
if ((stream->states[(2 * i) + 1] < stream->level) && (!desc))
|
||||
continue;
|
||||
while (i < m) {
|
||||
if ((comp->flags & XML_STREAM_DESC) == 0) {
|
||||
/*
|
||||
* If there is no "//", then only the last
|
||||
* added state is of interest.
|
||||
*/
|
||||
step = stream->states[2 * (stream->nbState -1)];
|
||||
/*
|
||||
* TODO: Security check, should not happen, remove it.
|
||||
*/
|
||||
if (stream->states[(2 * (stream->nbState -1)) + 1] <
|
||||
stream->level) {
|
||||
return (-1);
|
||||
}
|
||||
desc = 0;
|
||||
/* loop-stopper */
|
||||
i = m;
|
||||
} else {
|
||||
/*
|
||||
* If there are "//", then we need to process every "//"
|
||||
* occuring in the states, plus any other state for this
|
||||
* level.
|
||||
*/
|
||||
step = stream->states[2 * i];
|
||||
|
||||
/* discard old states */
|
||||
/* something needed about old level discarded */
|
||||
/* TODO: should not happen anymore: dead states */
|
||||
if (step < 0)
|
||||
goto next_state;
|
||||
|
||||
tmp = stream->states[(2 * i) + 1];
|
||||
|
||||
/* skip new states just added */
|
||||
if (tmp > stream->level)
|
||||
goto next_state;
|
||||
|
||||
/* skip states at ancestor levels, except if "//" */
|
||||
desc = comp->steps[step].flags & XML_STREAM_STEP_DESC;
|
||||
if ((tmp < stream->level) && (!desc))
|
||||
goto next_state;
|
||||
}
|
||||
/*
|
||||
* Check for correct node-type.
|
||||
*/
|
||||
if ((comp->steps[step].flags & XML_STREAM_STEP_ATTR) &&
|
||||
(nodeType != XML_ATTRIBUTE_NODE))
|
||||
continue;
|
||||
|
||||
if ((nodeType == XML_ATTRIBUTE_NODE) &&
|
||||
((comp->steps[0].flags & XML_STREAM_STEP_ATTR) == 0))
|
||||
goto next_state;
|
||||
/*
|
||||
* Compare local/namespace-name.
|
||||
*/
|
||||
match = 0;
|
||||
if (comp->dict) {
|
||||
if (comp->steps[step].name == NULL) {
|
||||
if (comp->steps[step].ns == NULL)
|
||||
@ -1677,76 +1729,105 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (((comp->flags & XML_STREAM_DESC) == 0) &&
|
||||
((! match) || final)) {
|
||||
/*
|
||||
* Mark this expression as blocked for any evaluation at
|
||||
* deeper levels. Note that this includes "/foo"
|
||||
* expressions if the *pattern* behaviour is used.
|
||||
*/
|
||||
stream->blockLevel = stream->level +1;
|
||||
}
|
||||
next_state:
|
||||
i++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check creating a new state.
|
||||
*/
|
||||
stream->level++;
|
||||
|
||||
|
||||
/*
|
||||
* Check the start only if this is a "desc" evaluation
|
||||
* or if we are at the first level of evaluation.
|
||||
* Re/enter the expression.
|
||||
*/
|
||||
if (comp->steps[0].flags & XML_STREAM_STEP_ROOT)
|
||||
goto stream_next;
|
||||
|
||||
desc = comp->steps[0].flags & XML_STREAM_STEP_DESC;
|
||||
if ( ((comp->steps[0].flags & XML_STREAM_STEP_ROOT) == 0) &&
|
||||
( ((stream->flags & XML_PATTERN_XSD) == 0) ||
|
||||
( (desc || (stream->level == 1)) )
|
||||
)
|
||||
) {
|
||||
|
||||
/*
|
||||
#ifdef SUPPORT_IDC
|
||||
|
||||
|
||||
if ((desc || (stream->level == 1)) &&
|
||||
(!(comp->steps[0].flags & XML_STREAM_STEP_ROOT))) {
|
||||
|
||||
*
|
||||
* Workaround for missing "self::node()" on "@foo".
|
||||
*
|
||||
if (comp->steps[0].flags & XML_STREAM_STEP_ATTR) {
|
||||
xmlStreamCtxtAddState(stream, 0, stream->level);
|
||||
goto stream_next;
|
||||
}
|
||||
#else
|
||||
if (stream->flags & XML_PATTERN_NOTPATTERN) {
|
||||
/*
|
||||
* Re/enter the expression if it is a "descendant" one,
|
||||
* or if we are at the 1st level of evaluation.
|
||||
*/
|
||||
|
||||
if (!(comp->steps[0].flags & XML_STREAM_STEP_ROOT)) {
|
||||
#endif
|
||||
*/
|
||||
if (comp->steps[0].name == NULL) {
|
||||
if (comp->steps[0].ns == NULL)
|
||||
match = 1;
|
||||
else {
|
||||
if (comp->dict)
|
||||
match = (comp->steps[0].ns == ns);
|
||||
else
|
||||
match = xmlStrEqual(comp->steps[0].ns, ns);
|
||||
}
|
||||
} else {
|
||||
if ((stream->flags & XML_PATTERN_XSD) && (!desc)) {
|
||||
if (stream->level == 1) {
|
||||
if (XML_STREAM_XS_IDC(stream)) {
|
||||
/*
|
||||
* Workaround for missing "self::node() on "foo".
|
||||
*/
|
||||
xmlStreamCtxtAddState(stream, 0, stream->level);
|
||||
* XS-IDC: The missing "self::node()" will always
|
||||
* match the first given node.
|
||||
*/
|
||||
goto stream_next;
|
||||
} else {
|
||||
if (comp->dict) {
|
||||
match = ((comp->steps[0].name == name) &&
|
||||
(comp->steps[0].ns == ns));
|
||||
} else {
|
||||
match = ((xmlStrEqual(comp->steps[0].name, name)) &&
|
||||
(xmlStrEqual(comp->steps[0].ns, ns)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
if (comp->steps[0].flags & XML_STREAM_STEP_FINAL)
|
||||
ret = 1;
|
||||
else
|
||||
xmlStreamCtxtAddState(stream, 1, stream->level);
|
||||
}
|
||||
} else
|
||||
goto compare;
|
||||
}
|
||||
/*
|
||||
* A "//" is always reentrant.
|
||||
*/
|
||||
if (desc)
|
||||
goto compare;
|
||||
|
||||
/*
|
||||
* XS-IDC: Process the 2nd level, since the missing
|
||||
* "self::node()" is responsible for the 2nd level being
|
||||
* the real start level.
|
||||
*/
|
||||
if ((stream->level == 2) && XML_STREAM_XS_IDC(stream))
|
||||
goto compare;
|
||||
|
||||
goto stream_next;
|
||||
}
|
||||
|
||||
compare:
|
||||
/*
|
||||
* Check expected node-type.
|
||||
*/
|
||||
if ((nodeType == XML_ATTRIBUTE_NODE) &&
|
||||
((comp->steps[0].flags & XML_STREAM_STEP_ATTR) == 0))
|
||||
goto stream_next;
|
||||
/*
|
||||
* Compare local/namespace-name.
|
||||
*/
|
||||
match = 0;
|
||||
if (comp->steps[0].name == NULL) {
|
||||
if (comp->steps[0].ns == NULL)
|
||||
match = 1;
|
||||
else {
|
||||
if (comp->dict)
|
||||
match = (comp->steps[0].ns == ns);
|
||||
else
|
||||
match = xmlStrEqual(comp->steps[0].ns, ns);
|
||||
}
|
||||
} else {
|
||||
if (comp->dict)
|
||||
match = ((comp->steps[0].name == name) &&
|
||||
(comp->steps[0].ns == ns));
|
||||
else
|
||||
match = ((xmlStrEqual(comp->steps[0].name, name)) &&
|
||||
(xmlStrEqual(comp->steps[0].ns, ns)));
|
||||
}
|
||||
if (match) {
|
||||
final = comp->steps[0].flags & XML_STREAM_STEP_FINAL;
|
||||
if (final)
|
||||
ret = 1;
|
||||
else
|
||||
xmlStreamCtxtAddState(stream, 1, stream->level);
|
||||
}
|
||||
if (((comp->flags & XML_STREAM_DESC) == 0) &&
|
||||
((! match) || final)) {
|
||||
/*
|
||||
* Mark this expression as blocked for any evaluation at
|
||||
* deeper levels.
|
||||
*/
|
||||
stream->blockLevel = stream->level;
|
||||
}
|
||||
|
||||
stream_next:
|
||||
stream = stream->next;
|
||||
} /* while stream != NULL */
|
||||
@ -1811,26 +1892,32 @@ xmlStreamPushAttr(xmlStreamCtxtPtr stream,
|
||||
*/
|
||||
int
|
||||
xmlStreamPop(xmlStreamCtxtPtr stream) {
|
||||
int i, m;
|
||||
int i, lev;
|
||||
int ret;
|
||||
|
||||
if (stream == NULL)
|
||||
return(-1);
|
||||
ret = 0;
|
||||
while (stream != NULL) {
|
||||
/*
|
||||
* Reset block-level.
|
||||
*/
|
||||
if (stream->blockLevel == stream->level)
|
||||
stream->blockLevel = -1;
|
||||
|
||||
stream->level--;
|
||||
if (stream->level < 0)
|
||||
ret = -1;
|
||||
|
||||
ret = -1;
|
||||
/*
|
||||
* Check evolution of existing states
|
||||
*/
|
||||
m = stream->nbState;
|
||||
for (i = 0;i < m;i++) {
|
||||
if (stream->states[(2 * i)] < 0) break;
|
||||
*/
|
||||
for (i = stream->nbState -1; i >= 0; i--) {
|
||||
/* discard obsoleted states */
|
||||
if (stream->states[(2 * i) + 1] > stream->level)
|
||||
stream->states[(2 * i)] = -1;
|
||||
lev = stream->states[(2 * i) + 1];
|
||||
if (lev > stream->level)
|
||||
stream->nbState--;
|
||||
if (lev <= stream->level)
|
||||
break;
|
||||
}
|
||||
stream = stream->next;
|
||||
}
|
||||
|
87
xmlschemas.c
87
xmlschemas.c
@ -256,6 +256,7 @@ struct _xmlSchemaParserCtxt {
|
||||
int sizeLocalImports;
|
||||
int nbLocalImports;
|
||||
xmlHashTablePtr substGroups;
|
||||
int isS4S;
|
||||
};
|
||||
|
||||
#define XML_SCHEMAS_ATTR_UNKNOWN 1
|
||||
@ -6914,10 +6915,10 @@ xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
|
||||
*/
|
||||
if (isField)
|
||||
selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
|
||||
NULL, 1, nsArray);
|
||||
NULL, XML_PATTERN_XSFIELD, nsArray);
|
||||
else
|
||||
selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
|
||||
NULL, 1, nsArray);
|
||||
NULL, XML_PATTERN_XSSEL, nsArray);
|
||||
if (nsArray != NULL)
|
||||
xmlFree((xmlChar **) nsArray);
|
||||
|
||||
@ -8046,10 +8047,21 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
|
||||
NULL, node,
|
||||
"name", NULL);
|
||||
return (NULL);
|
||||
} else if (xmlSchemaPValAttrNode(ctxt,
|
||||
NULL, NULL, attr,
|
||||
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
|
||||
return (NULL);
|
||||
} else {
|
||||
if (xmlSchemaPValAttrNode(ctxt,
|
||||
NULL, NULL, attr,
|
||||
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
|
||||
return (NULL);
|
||||
/*
|
||||
* Skip built-in types.
|
||||
*/
|
||||
if (ctxt->isS4S) {
|
||||
xmlSchemaTypePtr biType;
|
||||
|
||||
biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
|
||||
if (biType != NULL)
|
||||
return (biType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9020,7 +9032,7 @@ xmlSchemaParseForImpInc(xmlSchemaParserCtxtPtr pctxt,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
const xmlChar *oldURL, **oldLocImps, *oldTNS;
|
||||
int oldFlags, oldNumLocImps, oldSizeLocImps;
|
||||
int oldFlags, oldNumLocImps, oldSizeLocImps, oldIsS4S;
|
||||
|
||||
/*
|
||||
* Save and reset the context & schema.
|
||||
@ -9035,9 +9047,17 @@ xmlSchemaParseForImpInc(xmlSchemaParserCtxtPtr pctxt,
|
||||
oldSizeLocImps = pctxt->sizeLocalImports;
|
||||
pctxt->sizeLocalImports = 0;
|
||||
oldFlags = schema->flags;
|
||||
oldIsS4S = pctxt->isS4S;
|
||||
xmlSchemaClearSchemaDefaults(schema);
|
||||
oldTNS = schema->targetNamespace;
|
||||
schema->targetNamespace = targetNamespace;
|
||||
if ((targetNamespace != NULL) &&
|
||||
xmlStrEqual(targetNamespace, xmlSchemaNs)) {
|
||||
/*
|
||||
* We are parsing the schema for schema!
|
||||
*/
|
||||
pctxt->isS4S = 1;
|
||||
}
|
||||
/*
|
||||
* Parse the schema.
|
||||
*/
|
||||
@ -9054,6 +9074,7 @@ xmlSchemaParseForImpInc(xmlSchemaParserCtxtPtr pctxt,
|
||||
pctxt->nbLocalImports = oldNumLocImps;
|
||||
pctxt->sizeLocalImports = oldSizeLocImps;
|
||||
pctxt->URL = oldURL;
|
||||
pctxt->isS4S = oldIsS4S;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -10568,15 +10589,13 @@ xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
|
||||
return (NULL);
|
||||
nberrors = ctxt->nberrors;
|
||||
ctxt->nberrors = 0;
|
||||
ctxt->isS4S = 0;
|
||||
if (IS_SCHEMA(node, "schema")) {
|
||||
xmlSchemaImportPtr import;
|
||||
|
||||
schema = xmlSchemaNewSchema(ctxt);
|
||||
if (schema == NULL)
|
||||
return (NULL);
|
||||
/*
|
||||
* Disable build of list of items.
|
||||
*/
|
||||
attr = xmlSchemaGetPropNode(node, "targetNamespace");
|
||||
if (attr != NULL) {
|
||||
xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
|
||||
@ -10585,6 +10604,12 @@ xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
|
||||
* TODO: Should we proceed with an invalid target namespace?
|
||||
*/
|
||||
schema->targetNamespace = xmlDictLookup(ctxt->dict, val, -1);
|
||||
if (xmlStrEqual(schema->targetNamespace, xmlSchemaNs)) {
|
||||
/*
|
||||
* We are parsing the schema for schema!
|
||||
*/
|
||||
ctxt->isS4S = 1;
|
||||
}
|
||||
} else {
|
||||
schema->targetNamespace = NULL;
|
||||
}
|
||||
@ -12474,18 +12499,7 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr pctxt,
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((type->subtypes != NULL) &&
|
||||
((type->subtypes->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT) ||
|
||||
(type->subtypes->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT))) {
|
||||
/*
|
||||
* type --> (<simpleContent>|<complexContent>)
|
||||
* --> (<restriction>|<extension>) --> attributes
|
||||
*/
|
||||
attrs = type->subtypes->subtypes->attributes;
|
||||
} else {
|
||||
/* Short hand form of the complexType. */
|
||||
attrs = type->attributes;
|
||||
}
|
||||
attrs = type->attributes;
|
||||
/*
|
||||
* Handle attribute wildcards.
|
||||
*/
|
||||
@ -12661,6 +12675,13 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr pctxt,
|
||||
found = 1;
|
||||
|
||||
if ((cur->attr->occurs ==
|
||||
XML_SCHEMAS_ATTR_USE_PROHIBITED) &&
|
||||
(base->attr->occurs ==
|
||||
XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
|
||||
/*
|
||||
* NOOP.
|
||||
*/
|
||||
} else if ((cur->attr->occurs ==
|
||||
XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
|
||||
(base->attr->occurs ==
|
||||
XML_SCHEMAS_ATTR_USE_REQUIRED)) {
|
||||
@ -18085,7 +18106,7 @@ xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
|
||||
{
|
||||
const xmlChar *targetNs, *oldtns;
|
||||
xmlDocPtr doc, olddoc;
|
||||
int oldflags, ret = 0;
|
||||
int oldflags, ret = 0, oldIsS4S;
|
||||
xmlNodePtr docElem;
|
||||
xmlSchemaParserCtxtPtr pctxt;
|
||||
|
||||
@ -18137,9 +18158,17 @@ xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
|
||||
oldflags = schema->flags;
|
||||
oldtns = schema->targetNamespace;
|
||||
olddoc = schema->doc;
|
||||
oldIsS4S = vctxt->pctxt->isS4S;
|
||||
|
||||
xmlSchemaClearSchemaDefaults(schema);
|
||||
schema->targetNamespace = targetNs;
|
||||
if ((targetNs != NULL) &&
|
||||
xmlStrEqual(targetNs, xmlSchemaNs)) {
|
||||
/*
|
||||
* We are parsing the schema for schema!
|
||||
*/
|
||||
vctxt->pctxt->isS4S = 1;
|
||||
}
|
||||
/* schema->nbCurItems = 0; */
|
||||
pctxt->schema = schema;
|
||||
pctxt->ctxtType = NULL;
|
||||
@ -18170,6 +18199,7 @@ finally:
|
||||
/*
|
||||
* Restore the context & schema.
|
||||
*/
|
||||
vctxt->pctxt->isS4S = oldIsS4S;
|
||||
schema->flags = oldflags;
|
||||
schema->targetNamespace = oldtns;
|
||||
schema->doc = olddoc;
|
||||
@ -18904,7 +18934,7 @@ xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
|
||||
}
|
||||
} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
|
||||
/*
|
||||
* An IDC key node was found.
|
||||
* An IDC key node was found by the IDC field.
|
||||
*/
|
||||
#if DEBUG_IDC
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@ -22770,10 +22800,10 @@ xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
|
||||
vctxt->inode->localName,
|
||||
vctxt->inode->nsName);
|
||||
if (vctxt->inode->decl == NULL) {
|
||||
VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
|
||||
ret = XML_SCHEMAV_CVC_ELT_1;
|
||||
VERROR(ret, NULL,
|
||||
"No matching global declaration available "
|
||||
"for the validation root");
|
||||
ret = vctxt->err;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
@ -22823,6 +22853,9 @@ xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
/*
|
||||
* Validate against the type definition.
|
||||
*/
|
||||
type_validation:
|
||||
|
||||
if (vctxt->inode->typeDef == NULL) {
|
||||
@ -22840,7 +22873,7 @@ type_validation:
|
||||
goto exit;
|
||||
}
|
||||
/*
|
||||
* Evaluate IDCs. Do it here, since new matchers are registered
|
||||
* Evaluate IDCs. Do it here, since new IDC matchers are registered
|
||||
* during validation against the declaration. This must be done
|
||||
* _before_ attribute validation.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user