implemented the checks from section 7.1, fixed some of the 4.20 and 4.21
* relaxng.c: implemented the checks from section 7.1, fixed
some of the 4.20 and 4.21 problems.
found 373 test schemas: 338 success 35 failures
found 529 test instances: 519 success 6 failures
* result/relaxng/*: updated the results
Daniel
diff --git a/ChangeLog b/ChangeLog
index 66830f7..4dc4c6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Thu Feb 20 16:00:31 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+ * relaxng.c: implemented the checks from section 7.1, fixed
+ some of the 4.20 and 4.21 problems.
+ found 373 test schemas: 338 success 35 failures
+ found 529 test instances: 519 success 6 failures
+ * result/relaxng/*: updated the results
+
Thu Feb 20 01:09:24 CET 2003 Daniel Veillard <daniel@veillard.com>
* relaxng.c: implemented the 4.20 and 4.21 simplification rules.
diff --git a/check-relaxng-test-suite.py b/check-relaxng-test-suite.py
index 3cd328a..5363a81 100755
--- a/check-relaxng-test-suite.py
+++ b/check-relaxng-test-suite.py
@@ -254,9 +254,10 @@
global nb_instances_tests
global resources
- log.write("\n ============= test %d line %d ================\n" % (
+ sections = node.xpathEval('string(section)')
+ log.write("\n ======== test %d line %d section %s ==========\n" % (
- nb_schemas_tests, node.lineNo()))
+ nb_schemas_tests, node.lineNo(), sections))
resources = {}
if debug:
print "test %d line %d" % (nb_schemas_tests, node.lineNo())
@@ -320,7 +321,7 @@
msg = msg + author.content + " "
print msg
sections = node.xpathEval('section')
- if sections != []:
+ if sections != [] and level <= 0:
msg = ""
for section in sections:
msg = msg + section.content + " "
@@ -332,6 +333,10 @@
if level >= 1 and sections != []:
+ msg = ""
+ for section in sections:
+ msg = msg + section.content + " "
+ print "Result of tests for section %s" % (msg)
if nb_schemas_tests != old_schemas_tests:
print "found %d test schemas: %d success %d failures" % (
nb_schemas_tests - old_schemas_tests,
diff --git a/relaxng.c b/relaxng.c
index a2bdf53..b5e50ed 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -96,6 +96,7 @@
typedef enum {
+ XML_RELAXNG_NOOP = -1, /* a no operation from simplification */
XML_RELAXNG_EMPTY = 0, /* an empty pattern */
XML_RELAXNG_NOT_ALLOWED, /* not allowed top */
XML_RELAXNG_EXCEPT, /* except present in nameclass defs */
@@ -159,7 +160,14 @@
XML_RELAXNG_ERR_
} xmlRelaxNGValidError;
-#define XML_RELAXNG_IN_ATTRIBUTE 1
+#define XML_RELAXNG_IN_ATTRIBUTE (1 << 0)
+#define XML_RELAXNG_IN_ONEORMORE (1 << 1)
+#define XML_RELAXNG_IN_LIST (1 << 2)
+#define XML_RELAXNG_IN_DATAEXCEPT (1 << 3)
+#define XML_RELAXNG_IN_START (1 << 4)
+#define XML_RELAXNG_IN_OOMGROUP (1 << 5)
+#define XML_RELAXNG_IN_OOMINTERLEAVE (1 << 6)
+#define XML_RELAXNG_IN_EXTERNALREF (1 << 7)
struct _xmlRelaxNGParserCtxt {
void *userData; /* user specific data block */
@@ -2477,7 +2485,7 @@
xmlRelaxNGDocumentPtr docu;
xmlNodePtr root, tmp;
xmlChar *ns;
- int newNs = 0;
+ int newNs = 0, oldflags;
xmlRelaxNGDefinePtr def;
docu = node->_private;
@@ -2526,7 +2534,10 @@
/*
* Parsing to get a precompiled schemas.
*/
+ oldflags = ctxt->flags;
+ ctxt->flags |= XML_RELAXNG_IN_EXTERNALREF;
docu->schema = xmlRelaxNGParseDocument(ctxt, root);
+ ctxt->flags = oldflags;
if ((docu->schema != NULL) &&
(docu->schema->topgrammar != NULL)) {
docu->content = docu->schema->topgrammar->start;
@@ -2931,15 +2942,10 @@
case XML_RELAXNG_CHOICE:
case XML_RELAXNG_GROUP:
case XML_RELAXNG_INTERLEAVE:
+ case XML_RELAXNG_ATTRIBUTE:
ret->content = cur;
cur->parent = ret;
break;
- case XML_RELAXNG_ATTRIBUTE:
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "attribute has an attribute child\n");
- ctxt->nbErrors++;
- break;
case XML_RELAXNG_START:
case XML_RELAXNG_PARAM:
case XML_RELAXNG_EXCEPT:
@@ -2948,6 +2954,13 @@
"attribute has invalid content\n");
ctxt->nbErrors++;
break;
+ case XML_RELAXNG_NOOP:
+ TODO
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Internal error, noop found\n");
+ ctxt->nbErrors++;
+ break;
}
}
child = child->next;
@@ -3267,6 +3280,13 @@
TODO
ctxt->nbErrors++;
break;
+ case XML_RELAXNG_NOOP:
+ TODO
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Internal error, noop found\n");
+ ctxt->nbErrors++;
+ break;
}
}
child = child->next;
@@ -3777,6 +3797,40 @@
}
/**
+ * xmlRelaxNGTryUnlink:
+ * @ctxt: a Relax-NG parser context
+ * @cur: the definition to unlink
+ * @parent: the parent definition
+ * @prev: the previous sibling definition
+ *
+ * Try to unlink a definition. If not possble make it a NOOP
+ *
+ * Returns the new prev definition
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGTryUnlink(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+ xmlRelaxNGDefinePtr cur,
+ xmlRelaxNGDefinePtr parent,
+ xmlRelaxNGDefinePtr prev) {
+ if (prev != NULL) {
+ prev->next = cur->next;
+ } else {
+ if (parent != NULL) {
+ if (parent->content == cur)
+ parent->content = cur->next;
+ else if (parent->attrs == cur)
+ parent->attrs = cur->next;
+ else if (parent->nameClass == cur)
+ parent->nameClass = cur->next;
+ } else {
+ cur->type = XML_RELAXNG_NOOP;
+ prev = cur;
+ }
+ }
+ return(prev);
+}
+
+/**
* xmlRelaxNGCheckRules:
* @ctxt: a Relax-NG parser context
* @nodes: grammar children nodes
@@ -3797,6 +3851,7 @@
xmlRelaxNGSimplify(ctxt, cur->content, cur);
}
} else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
+ cur->parent = parent;
if ((parent != NULL) &&
((parent->type == XML_RELAXNG_ATTRIBUTE) ||
(parent->type == XML_RELAXNG_LIST) ||
@@ -3809,14 +3864,11 @@
}
if ((parent != NULL) &&
(parent->type == XML_RELAXNG_CHOICE)) {
- if (prev == NULL) {
- if (parent != NULL)
- parent->content = cur->next;
- } else
- prev->next = cur->next;
+ prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
} else
prev = cur;
} else if (cur->type == XML_RELAXNG_EMPTY){
+ cur->parent = parent;
if ((parent != NULL) &&
((parent->type == XML_RELAXNG_ONEORMORE) ||
(parent->type == XML_RELAXNG_ZEROORMORE))) {
@@ -3826,16 +3878,17 @@
if ((parent != NULL) &&
((parent->type == XML_RELAXNG_GROUP) ||
(parent->type == XML_RELAXNG_INTERLEAVE))) {
- if (prev == NULL) {
- if (parent != NULL)
- parent->content = cur->next;
- } else
- prev->next = cur->next;
+ prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
} else
prev = cur;
} else {
+ cur->parent = parent;
if (cur->content != NULL)
xmlRelaxNGSimplify(ctxt, cur->content, cur);
+ if (cur->attrs != NULL)
+ xmlRelaxNGSimplify(ctxt, cur->attrs, cur);
+ if (cur->nameClass != NULL)
+ xmlRelaxNGSimplify(ctxt, cur->nameClass, cur);
/*
* This may result in a simplification
*/
@@ -3844,14 +3897,17 @@
if (cur->content == NULL)
cur->type = XML_RELAXNG_EMPTY;
else if (cur->content->next == NULL) {
- cur->content->next = cur->next;
- if (prev == NULL) {
- if (parent != NULL)
- parent->content = cur->content;
+ if ((parent == NULL) && (prev == NULL)) {
+ cur->type = XML_RELAXNG_NOOP;
+ } else if (prev == NULL) {
+ parent->content = cur->content;
+ cur->content->next = cur->next;
+ cur = cur->content;
} else {
+ cur->content->next = cur->next;
prev->next = cur->content;
+ cur = cur->content;
}
- cur = cur->content;
}
}
/*
@@ -3860,11 +3916,7 @@
if ((cur->type == XML_RELAXNG_EXCEPT) &&
(cur->content != NULL) &&
(cur->content->type == XML_RELAXNG_NOT_ALLOWED)) {
- if (prev == NULL) {
- if (parent != NULL)
- parent->content = cur->next;
- } else
- prev->next = cur->next;
+ prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
} else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
if ((parent != NULL) &&
((parent->type == XML_RELAXNG_ATTRIBUTE) ||
@@ -3878,11 +3930,7 @@
}
if ((parent != NULL) &&
(parent->type == XML_RELAXNG_CHOICE)) {
- if (prev == NULL) {
- if (parent != NULL)
- parent->content = cur->next;
- } else
- prev->next = cur->next;
+ prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
} else
prev = cur;
} else if (cur->type == XML_RELAXNG_EMPTY){
@@ -3896,11 +3944,7 @@
((parent->type == XML_RELAXNG_GROUP) ||
(parent->type == XML_RELAXNG_INTERLEAVE) ||
(parent->type == XML_RELAXNG_CHOICE))) {
- if (prev == NULL) {
- if (parent != NULL)
- parent->content = cur->next;
- } else
- prev->next = cur->next;
+ prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
} else
prev = cur;
} else {
@@ -3911,46 +3955,294 @@
}
}
-#if 0
+
/**
* xmlRelaxNGCheckRules:
* @ctxt: a Relax-NG parser context
* @nodes: grammar children nodes
- * @state: a state
+ * @flags: some accumulated flags
*
- * Check for rules in
+ * Check for rules in section 7
*
* Returns 0 if check passed, and -1 in case of error
*/
static int
xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
- xmlRelaxNGDefinePtr cur, int depth) {
- int ret = 0;
+ xmlRelaxNGDefinePtr cur, int flags) {
+ int ret = 0, nflags = flags;
- while ((ret == 0) && (cur != NULL)) {
+ while (cur != NULL) {
if ((cur->type == XML_RELAXNG_REF) ||
(cur->type == XML_RELAXNG_PARENTREF)) {
- if (cur->depth == -1) {
- cur->depth = depth;
- ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
- cur->depth = -2;
- } else if (depth == cur->depth) {
+ if (flags & XML_RELAXNG_IN_LIST) {
if (ctxt->error != NULL)
ctxt->error(ctxt->userData,
- "Detected a cycle in %s references\n", cur->name);
+ "Found forbidden pattern list//ref\n");
ctxt->nbErrors++;
- return(-1);
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern attribute//ref\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern data/except//ref\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (cur->depth != -4) {
+ cur->depth = -4;
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, flags) != 0)
+ ret = -1;
}
} else if (cur->type == XML_RELAXNG_ELEMENT) {
- ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth + 1);
+ if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern data/except//element(ref)\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_LIST) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern list//element(ref)\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern attribute//element(ref)\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ /*
+ * reset since in the simple form elements are only child
+ * of grammar/define
+ */
+ nflags = 0;
+ if (xmlRelaxNGCheckRules(ctxt, cur->attrs, nflags) != 0)
+ ret = -1;
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, nflags) != 0)
+ ret = -1;
+ } else if (cur->type == XML_RELAXNG_ATTRIBUTE) {
+ if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern attribute//attribute\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_LIST) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern list//attribute\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_OOMGROUP) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern oneOrMore//group//attribute\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_OOMINTERLEAVE) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern oneOrMore//interleave//attribute\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern data/except//attribute\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_START) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern start//attribute\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ nflags = flags | XML_RELAXNG_IN_ATTRIBUTE;
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, nflags) != 0)
+ ret = -1;
+ } else if ((cur->type == XML_RELAXNG_ONEORMORE) ||
+ (cur->type == XML_RELAXNG_ZEROORMORE)) {
+ if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern data/except//oneOrMore\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_START) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern start//oneOrMore\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ nflags = flags | XML_RELAXNG_IN_ONEORMORE;
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, nflags) != 0)
+ ret = -1;
+ } else if (cur->type == XML_RELAXNG_LIST) {
+ if (flags & XML_RELAXNG_IN_LIST) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern list//list\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern data/except//list\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_START) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern start//list\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ nflags = flags | XML_RELAXNG_IN_LIST;
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, nflags) != 0)
+ ret = -1;
+ } else if (cur->type == XML_RELAXNG_GROUP) {
+ if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern data/except//group\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_START) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern start//group\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_ONEORMORE)
+ nflags = flags | XML_RELAXNG_IN_OOMGROUP;
+ else
+ nflags = flags;
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, nflags) != 0)
+ ret = -1;
+ } else if (cur->type == XML_RELAXNG_INTERLEAVE) {
+ if (flags & XML_RELAXNG_IN_LIST) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern list//interleave\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern data/except//interleave\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_START) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern start//interleave\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_ONEORMORE)
+ nflags = flags | XML_RELAXNG_IN_OOMINTERLEAVE;
+ else
+ nflags = flags;
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, nflags) != 0)
+ ret = -1;
+ } else if (cur->type == XML_RELAXNG_EXCEPT) {
+ if ((cur->parent != NULL) &&
+ (cur->parent->type == XML_RELAXNG_DATATYPE))
+ nflags = flags | XML_RELAXNG_IN_DATAEXCEPT;
+ else
+ nflags = flags;
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, nflags) != 0)
+ ret = -1;
+ } else if (cur->type == XML_RELAXNG_DATATYPE) {
+ if (flags & XML_RELAXNG_IN_START) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern start//data\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, flags) != 0)
+ ret = -1;
+ } else if (cur->type == XML_RELAXNG_VALUE) {
+ if (flags & XML_RELAXNG_IN_START) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern start//value\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, flags) != 0)
+ ret = -1;
+ } else if (cur->type == XML_RELAXNG_TEXT) {
+ if (flags & XML_RELAXNG_IN_LIST) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern list//text\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern data/except//text\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_START) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern start//text\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ } else if (cur->type == XML_RELAXNG_EMPTY) {
+ if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern data/except//empty\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
+ if (flags & XML_RELAXNG_IN_START) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Found forbidden pattern start//empty\n");
+ ctxt->nbErrors++;
+ ret = -1;
+ }
} else {
- ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
+ if (xmlRelaxNGCheckRules(ctxt, cur->content, flags) != 0)
+ ret = -1;
}
cur = cur->next;
}
return(ret);
}
-#endif
/**
* xmlRelaxNGParseGrammar:
@@ -4064,7 +4356,15 @@
ctxt->define = olddefine;
if (schema->topgrammar->start != NULL) {
xmlRelaxNGCheckCycles(ctxt, schema->topgrammar->start, 0);
- xmlRelaxNGSimplify(ctxt, schema->topgrammar->start, NULL);
+ if ((ctxt->flags & XML_RELAXNG_IN_EXTERNALREF) == 0) {
+ xmlRelaxNGSimplify(ctxt, schema->topgrammar->start, NULL);
+ while ((schema->topgrammar->start != NULL) &&
+ (schema->topgrammar->start->type == XML_RELAXNG_NOOP) &&
+ (schema->topgrammar->start->next != NULL))
+ schema->topgrammar->start = schema->topgrammar->start->content;
+ xmlRelaxNGCheckRules(ctxt, schema->topgrammar->start,
+ XML_RELAXNG_IN_START);
+ }
}
#ifdef DEBUG
@@ -4955,6 +5255,9 @@
case XML_RELAXNG_PARAM:
TODO
break;
+ case XML_RELAXNG_NOOP:
+ xmlRelaxNGDumpDefines(output, define->content);
+ break;
}
}
@@ -6418,6 +6721,7 @@
case XML_RELAXNG_ATTRIBUTE:
ret = xmlRelaxNGValidateAttribute(ctxt, define);
break;
+ case XML_RELAXNG_NOOP:
case XML_RELAXNG_REF:
case XML_RELAXNG_PARENTREF:
case XML_RELAXNG_EXTERNALREF: