Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Integrated further improvements and features to recovering. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | schema |
Files: | files | file ages | folders |
SHA3-256: |
0e98933aa6179e2e808c65f8909e017e |
User & Date: | rolf 2020-07-30 14:33:15 |
Context
2020-07-31
| ||
10:59 | Minor documentation and test suite work. check-in: a14c1bb515 user: rolf tags: schema | |
2020-07-30
| ||
14:33 | Integrated further improvements and features to recovering. check-in: 0e98933aa6 user: rolf tags: schema | |
13:16 | Respect "ignore" return value from recover script in case of END_EVENT, enabling to get further recover calls for other missing mandantory content particle of the current content model. Closed-Leaf check-in: 42c54de7e7 user: rolf tags: wip | |
2020-07-23
| ||
23:50 | Merged from trunk. check-in: 76ba31355c user: rolf tags: schema | |
Changes
Changes to doc/schema.xml.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 ... 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 ... 229 230 231 232 233 234 235 236 237 238 239 240 241 242 .... 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 |
schema.</p> <p>Additionally, a validation command may be used as argument to the <m>-validateCmd</m> option of the <m>dom parse</m> and the <m>expat</m> commands to enable validation additional to what they otherwise do.</p> <p>The valid methods of the created commands are:</p> <commandlist> <commanddef> <command><method>prefixns</method> <m>?prefixUriList?</m></command> <desc>This method gives control to a prefix (or abbreviation) to namespace URI mapping. Everywhere a namespace argument is expected in the schema command methods ................................................................................ <desc>Returns true if the first argument is a valid tree or false otherwise. If validation failed and the optional <m>objVar</m> argument is given, then the variable with that name is set to a validation error message. If the dom tree is valid and the optional <m>objVar</m> argument is given, then the variable with that name is set to the empty string. </desc> </commanddef> <commanddef> <command><method>reportcmd</method> <m>?cmdName?</m></command> <desc>This method expects the name of a tcl command to be called in case of validation error. This command will be called with two arguments: the schema command, that is rasing the validation error, and a validation error code. For more detailed information see <ref ................................................................................ <dt>DOM_KEYCONSTRAINT</dt><dd></dd> <dt>DOM_XPATH_BOOLEAN</dt><dd></dd> <dt>INVALID_KEYREF</dt><dd></dd> <dt>INVALID_VALUE</dt><dd></dd> <dt>UNKOWN_GLOBAL_ID</dt><dd></dd> <dt>UNKOWN_ID</dt><dd></dd> </dl> </desc> </commanddef> <commanddef> <command><method>delete</method></command> <desc>This method deletes the validation command.</desc> </commanddef> ................................................................................ </commandlist> </section> <section id="recovering"> <title>Recovering</title> <p> </p> </section> <section> <title>Exampels</title> <p>The XML Schema Part 0: Primer Second Edition (<url>https://www.w3.org/TR/xmlschema-0/</url>) starts with this |
| | > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 ... 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 ... 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 .... 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 |
schema.</p> <p>Additionally, a validation command may be used as argument to the <m>-validateCmd</m> option of the <m>dom parse</m> and the <m>expat</m> commands to enable validation additional to what they otherwise do.</p> <p>The methods of the created commands are:</p> <commandlist> <commanddef> <command><method>prefixns</method> <m>?prefixUriList?</m></command> <desc>This method gives control to a prefix (or abbreviation) to namespace URI mapping. Everywhere a namespace argument is expected in the schema command methods ................................................................................ <desc>Returns true if the first argument is a valid tree or false otherwise. If validation failed and the optional <m>objVar</m> argument is given, then the variable with that name is set to a validation error message. If the dom tree is valid and the optional <m>objVar</m> argument is given, then the variable with that name is set to the empty string. </desc> </commanddef> <commanddef> <command><method>reportcmd</method> <m>?cmdName?</m></command> <desc>This method expects the name of a tcl command to be called in case of validation error. This command will be called with two arguments: the schema command, that is rasing the validation error, and a validation error code. For more detailed information see <ref ................................................................................ <dt>DOM_KEYCONSTRAINT</dt><dd></dd> <dt>DOM_XPATH_BOOLEAN</dt><dd></dd> <dt>INVALID_KEYREF</dt><dd></dd> <dt>INVALID_VALUE</dt><dd></dd> <dt>UNKOWN_GLOBAL_ID</dt><dd></dd> <dt>UNKOWN_ID</dt><dd></dd> </dl> <p> For more detailed information see section <ref refid="recovering">Recovering</ref>.</p> </desc> </commanddef> <commanddef> <command><method>delete</method></command> <desc>This method deletes the validation command.</desc> </commanddef> ................................................................................ </commandlist> </section> <section id="recovering"> <title>Recovering</title> <p>By default the validation engine stops at the first detected validation violation and reports that finding. It does so by result false (and set, if given, the result variable with an error message) in case the schema command itself is used to validate input. If the schema command is used by a SAX parser or the DOM parser it does so by throwing error.</p> <p>If a <m>reportcmd</m> is set this command is called on global level appended with the schema command and an error type as arguments if a validation violation is detected. Then the validation recovers from the error and continues. For some validation errors the reocver strategy can be determined with the script result of the reportcmd.</p> <p>With a <m>reportcmd</m> (which doesen&t throw error if called) the validation engine will never report validation failure to its caller. The validation engine recovers, continues and report the next error, if one happen and so until the end of the input. The schema command will return true and the SAX parser and DOM builder will process normally until the end of the input, as if there would not have been validation.</p> <p>Please note, that this happens only for validation errors. It isn't possible to recover from well-formedness errors. If the input isn't well-formed the schema command returns false and set, if given, the result variable with an error message about the well-formedness error.</p> <p>If the <m>reportcmd</m> throws error while called by the validation engine then validation stops and the schema command thows error with the error message of the script.</p> </section> <section> <title>Exampels</title> <p>The XML Schema Part 0: Primer Second Edition (<url>https://www.w3.org/TR/xmlschema-0/</url>) starts with this |
Changes to generic/schema.c.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 ... 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 ... 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 ... 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 .... 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 .... 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 .... 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 .... 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 .... 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 .... 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 .... 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 .... 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 .... 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 |
"UNKOWN_GLOBAL_ID", "UNKOWN_ID", "INVALID_ATTRIBUTE_VALUE", "INVALID_VALUE" }; /*---------------------------------------------------------------------------- | Recover related flage | \---------------------------------------------------------------------------*/ #define RECOVER_FLAG_REWIND 1 #define RECOVER_FLAG_DONT_REPORT 2 #define RECOVER_FLAG_IGNORE 4 /*---------------------------------------------------------------------------- | [schemacmd info expected] related flags | \---------------------------------------------------------------------------*/ #define EXPECTED_IGNORE_MATCHED 1 ................................................................................ ac += + 1; \ hm = 0; \ } \ #define updateStack(sdata,se,ac) \ if (!(sdata->recoverFlags & RECOVER_FLAG_REWIND)) { \ se->activeChild = ac; \ se->hasMatched = 1; \ } \ #ifndef TCL_THREADS SchemaData * tdomGetSchemadata (Tcl_Interp *interp) { ................................................................................ for (i = from; i < sdata->numPatternList; i++) { this = sdata->patternList[i]; hashTable = NULL; name = NULL; if (this->type == SCHEMA_CTYPE_NAME) { /* Local defined elements aren't saved under their local * name bucket in the sdata->element hash table. */ if (!(this->flags & LOCAL_DEFINED_ELEMENT)) { if (this->flags & ELEMENTTYPE_DEF) { hashTable = &sdata->elementType; name = this->typeName; } else { hashTable = &sdata->element; name = this->name; } } } if (this->type == SCHEMA_CTYPE_PATTERN) { hashTable = &sdata->pattern; name = this->name; } if (name && hashTable) { ................................................................................ static void pushToStack ( SchemaData *sdata, SchemaCP *pattern ) { SchemaValidationStack *se, *nextse; DBG(fprintf(stderr, "push to Stack:\n");serializeCP(pattern)); if (pattern->type == SCHEMA_CTYPE_NAME && sdata->lastMatchse) { se = sdata->lastMatchse; while (se) { nextse = se->down; repoolStackElement (sdata, se); se = nextse; ................................................................................ } break; case UNEXPECTED_TEXT: sdata->recoverFlags |= RECOVER_FLAG_REWIND; break; case MISSING_ELEMENT_MATCH_END: case MISSING_TEXT_MATCH_END: sdata->recoverFlags |= RECOVER_FLAG_DONT_REPORT; break; case DOM_KEYCONSTRAINT: case DOM_XPATH_BOOLEAN: case MISSING_ATTRIBUTE: case MISSING_TEXT_MATCH_START: case UNEXPECTED_ROOT_ELEMENT: case UNKNOWN_ATTRIBUTE: ................................................................................ } } else { thismayskip = 1; } break; case SCHEMA_CTYPE_ANY: if (icp->namespace && icp->namespace == namespace) { break; } sdata->skipDeep = 1; se->hasMatched = 1; se->interleaveState[i] = 1; /* See comment in probeElement: sdata->vname and * sdata->vns may be pre-filled. We reset it here.*/ ................................................................................ } if (!thismayskip && minOne (cp->quants[i])) mayskip = 0; } if (mayskip) break; if (recover (interp, sdata, MISSING_ELEMENT_MATCH_START, name, namespace, NULL, cp->nc)) { return 1; } return 0; } return -1; } ................................................................................ if (reqAttr != cp->numReqAttr) { SetResult ("Missing mandatory attribute(s)"); return TCL_ERROR; } return TCL_OK; } static int checkElementEnd ( Tcl_Interp *interp, SchemaData *sdata ) { SchemaValidationStack *se; SchemaCP *cp, *ic; ................................................................................ if (ac < cp->nc && (hasMatched (cp->quants[ac], hm))) { DBG(fprintf (stderr, "ac %d has matched, skiping to next ac\n", ac)); ac++; hm = 0; } while (ac < cp->nc) { DBG(fprintf (stderr, "ac %d hm %d mayMiss: %d\n", ac, hm, mayMiss (cp->quants[ac]))); if (se->interleaveState) { if (se->interleaveState[ac]) { ac++; continue; } } if (mayMiss (cp->quants[ac])) { ac++; continue; } switch (cp->content[ac]->type) { case SCHEMA_CTYPE_KEYSPACE_END: /* Don't happen as INTERLEAVE child */ ................................................................................ if (recursivePattern (se, ic)) { thismayskip = 1; break; } /* fall throu */ case SCHEMA_CTYPE_INTERLEAVE: pushToStack (sdata, ic); if (checkElementEnd (interp, sdata)) { thismayskip = 1; } popStack (sdata); break; case SCHEMA_CTYPE_KEYSPACE_END: case SCHEMA_CTYPE_KEYSPACE: ................................................................................ if (thismayskip) break; } if (thismayskip) break; if (!recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { return 0; } break; case SCHEMA_CTYPE_VIRTUAL: if (evalVirtual (interp, sdata, ac)) break; else return 0; case SCHEMA_CTYPE_PATTERN: ................................................................................ if (recursivePattern (se, cp->content[ac])) { break; } /* fall throu */ case SCHEMA_CTYPE_INTERLEAVE: pushToStack (sdata, cp->content[ac]); rc = checkElementEnd (interp, sdata); popStack (sdata); if (rc) break; if (recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { break; } return 0; case SCHEMA_CTYPE_ANY: case SCHEMA_CTYPE_NAME: if (recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { break; } return 0; } ac++; } if (se->interleaveState) { ................................................................................ SetResult ("No validation started"); return TCL_ERROR; } if (sdata->validationState == VALIDATION_ERROR) { return TCL_ERROR; } rc = checkElementEnd (interp, sdata); while (rc == -1) { popStack (sdata); rc = checkElementEnd (interp, sdata); } sdata->recoverFlags &= ~RECOVER_FLAG_DONT_REPORT; if (rc) { popStack (sdata); if (sdata->stack == NULL) { /* End of the first pattern (the tree root) without error. */ /* Check for unknown ID references */ if (!checkDocKeys (interp, sdata)) { return TCL_ERROR; } /* We have successfully finished validation */ sdata->validationState = VALIDATION_FINISHED; } DBG( fprintf(stderr, "probeElementEnd: _CAN_ end here.\n"); serializeStack (sdata); ); return TCL_OK; } SetResultV ("Missing mandatory content"); sdata->validationState = VALIDATION_ERROR; DBG( fprintf(stderr, "probeElementEnd: CAN'T end here.\n"); serializeStack (sdata); ); |
| > | | | > > > | | | | | | < < > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | < | < | > > > > > | < > > > | | > > > > > | | > | > > > > > > > > > > > > | | | | | | | > > > > | | | | | | | | | | | | | | | > > |
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 ... 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 ... 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 ... 976 977 978 979 980 981 982 983 984 985 986 987 988 989 .... 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 .... 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 .... 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 .... 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 .... 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 .... 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 .... 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 .... 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 .... 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 |
"UNKOWN_GLOBAL_ID", "UNKOWN_ID", "INVALID_ATTRIBUTE_VALUE", "INVALID_VALUE" }; /*---------------------------------------------------------------------------- | Recovering related flage | \---------------------------------------------------------------------------*/ #define RECOVER_FLAG_REWIND 1 #define RECOVER_FLAG_DONT_REPORT 2 #define RECOVER_FLAG_IGNORE 4 #define RECOVER_FLAG_MATCH_END_CONTINUE 8 /*---------------------------------------------------------------------------- | [schemacmd info expected] related flags | \---------------------------------------------------------------------------*/ #define EXPECTED_IGNORE_MATCHED 1 ................................................................................ ac += + 1; \ hm = 0; \ } \ #define updateStack(sdata,se,ac) \ if (!(sdata->recoverFlags & RECOVER_FLAG_REWIND)) { \ se->activeChild = ac; \ se->hasMatched = 1; \ } \ #ifndef TCL_THREADS SchemaData * tdomGetSchemadata (Tcl_Interp *interp) { ................................................................................ for (i = from; i < sdata->numPatternList; i++) { this = sdata->patternList[i]; hashTable = NULL; name = NULL; if (this->type == SCHEMA_CTYPE_NAME) { /* Local defined elements aren't saved under their local * name bucket in the sdata->element hash table. */ if (this->flags & LOCAL_DEFINED_ELEMENT) { freeSchemaCP (sdata->patternList[i]); continue; } if (this->flags & ELEMENTTYPE_DEF) { hashTable = &sdata->elementType; name = this->typeName; } else { hashTable = &sdata->element; name = this->name; } } if (this->type == SCHEMA_CTYPE_PATTERN) { hashTable = &sdata->pattern; name = this->name; } if (name && hashTable) { ................................................................................ static void pushToStack ( SchemaData *sdata, SchemaCP *pattern ) { SchemaValidationStack *se, *nextse; DBG(fprintf(stderr, "push to Stack:\n");serializeCP(pattern)); if (pattern->type == SCHEMA_CTYPE_NAME && sdata->lastMatchse) { se = sdata->lastMatchse; while (se) { nextse = se->down; repoolStackElement (sdata, se); se = nextse; ................................................................................ } break; case UNEXPECTED_TEXT: sdata->recoverFlags |= RECOVER_FLAG_REWIND; break; case MISSING_ELEMENT_MATCH_END: case MISSING_TEXT_MATCH_END: if (strcmp (Tcl_GetStringResult (interp), "ignore") == 0) { sdata->recoverFlags |= RECOVER_FLAG_MATCH_END_CONTINUE; } else { sdata->recoverFlags |= RECOVER_FLAG_DONT_REPORT; } break; case DOM_KEYCONSTRAINT: case DOM_XPATH_BOOLEAN: case MISSING_ATTRIBUTE: case MISSING_TEXT_MATCH_START: case UNEXPECTED_ROOT_ELEMENT: case UNKNOWN_ATTRIBUTE: ................................................................................ } } else { thismayskip = 1; } break; case SCHEMA_CTYPE_ANY: if (icp->namespace && icp->namespace != namespace) { break; } sdata->skipDeep = 1; se->hasMatched = 1; se->interleaveState[i] = 1; /* See comment in probeElement: sdata->vname and * sdata->vns may be pre-filled. We reset it here.*/ ................................................................................ } if (!thismayskip && minOne (cp->quants[i])) mayskip = 0; } if (mayskip) break; if (recover (interp, sdata, MISSING_ELEMENT_MATCH_START, name, namespace, NULL, cp->nc)) { if (sdata->recoverFlags & RECOVER_FLAG_IGNORE) { /* We mark the first so far not matched mandatory * interleave child cp as matched */ for (i = 0; i < cp->nc; i++) { if (!se->interleaveState[i]) { if (minOne (cp->quants[i])) { se->interleaveState[i] = 1; break; } } } } return 1; } return 0; } return -1; } ................................................................................ if (reqAttr != cp->numReqAttr) { SetResult ("Missing mandatory attribute(s)"); return TCL_ERROR; } return TCL_OK; } /* Returns either -1, 0, 1, 2 -1 means a pattern or an interleave ended may end, look further at parents next sibling. 0 means rewind with validation error. 1 means element content may end here. 2 means recovering requested further error reporting about missing childs in the current element. To be able to to answer a [info expected] on the occasion of the next error, we update the stack in this case and let probeElementEnd restart checkElementEnd again with this stack state. */ static int checkElementEnd ( Tcl_Interp *interp, SchemaData *sdata ) { SchemaValidationStack *se; SchemaCP *cp, *ic; ................................................................................ if (ac < cp->nc && (hasMatched (cp->quants[ac], hm))) { DBG(fprintf (stderr, "ac %d has matched, skiping to next ac\n", ac)); ac++; hm = 0; } while (ac < cp->nc) { DBG(fprintf (stderr, "ac %d hm %d mayMiss: %d\n", ac, hm, mayMiss (cp->quants[ac]))); if (se->interleaveState && se->interleaveState[ac]) { ac++; continue; } if (mayMiss (cp->quants[ac])) { ac++; continue; } switch (cp->content[ac]->type) { case SCHEMA_CTYPE_KEYSPACE_END: /* Don't happen as INTERLEAVE child */ ................................................................................ if (recursivePattern (se, ic)) { thismayskip = 1; break; } /* fall throu */ case SCHEMA_CTYPE_INTERLEAVE: pushToStack (sdata, ic); if (checkElementEnd (interp, sdata) == -1) { thismayskip = 1; } popStack (sdata); break; case SCHEMA_CTYPE_KEYSPACE_END: case SCHEMA_CTYPE_KEYSPACE: ................................................................................ if (thismayskip) break; } if (thismayskip) break; if (!recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { return 0; } if (sdata->recoverFlags & RECOVER_FLAG_MATCH_END_CONTINUE) { updateStack (sdata, se, ac); return 2; } break; case SCHEMA_CTYPE_VIRTUAL: if (evalVirtual (interp, sdata, ac)) break; else return 0; case SCHEMA_CTYPE_PATTERN: ................................................................................ if (recursivePattern (se, cp->content[ac])) { break; } /* fall throu */ case SCHEMA_CTYPE_INTERLEAVE: pushToStack (sdata, cp->content[ac]); rc = checkElementEnd (interp, sdata); if (rc == 0) { popStack (sdata); if (sdata->stack->pattern->type == SCHEMA_CTYPE_NAME || sdata->stack->activeChild || sdata->stack->hasMatched) { if (recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { if (sdata->recoverFlags & RECOVER_FLAG_MATCH_END_CONTINUE) { updateStack (sdata, se, ac); return 2; } break; } } return 0; } if (rc == 2) { updateStack (sdata, se, ac); return 2; } popStack (sdata); break; case SCHEMA_CTYPE_ANY: case SCHEMA_CTYPE_NAME: if (recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { if (sdata->recoverFlags & RECOVER_FLAG_MATCH_END_CONTINUE) { updateStack (sdata, se, ac); return 2; } break; } return 0; } ac++; } if (se->interleaveState) { ................................................................................ SetResult ("No validation started"); return TCL_ERROR; } if (sdata->validationState == VALIDATION_ERROR) { return TCL_ERROR; } while (1) { rc = checkElementEnd (interp, sdata); while (rc == -1) { popStack (sdata); rc = checkElementEnd (interp, sdata); } sdata->recoverFlags &= ~RECOVER_FLAG_DONT_REPORT; if (rc == 2) { sdata->recoverFlags &= ~RECOVER_FLAG_MATCH_END_CONTINUE; continue; } if (rc == 1) { popStack (sdata); if (sdata->stack == NULL) { /* End of the first pattern (the tree root) without error. */ /* Check for unknown ID references */ if (!checkDocKeys (interp, sdata)) { return TCL_ERROR; } /* We have successfully finished validation */ sdata->validationState = VALIDATION_FINISHED; } DBG( fprintf(stderr, "probeElementEnd: _CAN_ end here.\n"); serializeStack (sdata); ); return TCL_OK; } break; } SetResultV ("Missing mandatory content"); sdata->validationState = VALIDATION_ERROR; DBG( fprintf(stderr, "probeElementEnd: CAN'T end here.\n"); serializeStack (sdata); ); |
Changes to tests/schema.test.
3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 .... 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 .... 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 .... 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 |
{<n:doc xmlns:n="ns1"><elm1 xmlns="ns2"/><n:elm2/></n:doc>} } { lappend result [s validate $xml] } s delete set result } {0 0 0 0 1} test schema-14.1 {text: integer} { tdom::schema s s defelement doc { text { integer } ................................................................................ } { lappend result [s validate $xml] } s delete set result } {0 1 1 1 1 1 1 1 0 1} test schema-16.18 {interleave with all child cp optional} { tdom::schema s s defelement doc { interleave { element a ? element b ? choice { element c ? ................................................................................ ref thatPattern ? } set result [lsort -index 0 [grammar info definedPatterns]] grammar delete set result } {{thatPattern someNamespace} thisPattern} proc schema-18 {args} { lappend ::result {*}$args } test schema-18.1 {reportcmd} { tdom::schema s s define { defelement doc { ................................................................................ s reportcmd "" lappend result [s reportcmd] s reportcmd dummycallback lappend result [s reportcmd] s delete set result } {{} {} dummycallback {} dummycallback} proc validatedSAX {g xml {keepEmpties 1}} { set args [list -validateCmd $g] if {!$keepEmpties} { lappend args -ignorewhitespace 1 } xml::parser p {*}$args set rc [catch {p parse $xml} errMsg] |
> > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > |
3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 .... 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 .... 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 .... 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 |
{<n:doc xmlns:n="ns1"><elm1 xmlns="ns2"/><n:elm2/></n:doc>} } { lappend result [s validate $xml] } s delete set result } {0 0 0 0 1} test schema-13.3 {Not namespaced elements inside namespaced ones} { tdom::schema s s define { defelement doc ns1 { namespace "" { element e } } defelement e {text {fixed "here"}} } set result "" foreach xml { {<doc xmlns="ns1"><e xmlns="">here</e></doc>} {<a:doc xmlns:a="ns1"><e xmlns="">here</e></a:doc>} {<a:doc xmlns:a="ns1"><e>here</e></a:doc>} {<doc xmlns="ns1"><e>here</e></doc>} } { lappend result [s validate $xml] } s delete set result } {1 1 1 0} test schema-14.1 {text: integer} { tdom::schema s s defelement doc { text { integer } ................................................................................ } { lappend result [s validate $xml] } s delete set result } {0 1 1 1 1 1 1 1 0 1} test schema-16.18 {interleave with all content cp optional} { tdom::schema s s defelement doc { interleave { element a ? element b ? choice { element c ? ................................................................................ ref thatPattern ? } set result [lsort -index 0 [grammar info definedPatterns]] grammar delete set result } {{thatPattern someNamespace} thisPattern} proc schema-17.26 {scmd errorInfo} { global fromReportCmd if {$errorInfo eq "MISSING_ELEMENT" && [$scmd info vaction] eq "MATCH_ELEMENT_END"} { lappend fromReportCmd "END_EVENT [$scmd info vaction name]" "expecting [lsort [$scmd info expected]]" return "ignore" } else { lappend fromReportCmd "[$scmd info vaction] expecting [$scmd info expected]" } } test schema-17.26 {return "ignore" from recover handler for element end event} { tdom::schema s s define { defelement doc { element a ref bpat element d } defpattern bpat { element b ref c } defpattern c { element c + } } s reportcmd schema-17.26 set result "" set xmlnr 0 foreach xml { <doc/> <doc><a/></doc> <doc><a/><b/></doc> <doc><a/><b/><d/></doc> <doc><a/><b/><c/><d/></doc> <doc><a/><b/><c/><c/><c/><d/></doc> } { set ::fromReportCmd "" lappend result $xmlnr: [s validate $xml errMsg] lappend result {*}$fromReportCmd incr xmlnr } s delete set result } {0: 1 {END_EVENT doc} {expecting a} {END_EVENT doc} {expecting b} {END_EVENT doc} {expecting d} 1: 1 {END_EVENT doc} {expecting b} {END_EVENT doc} {expecting d} 2: 1 {END_EVENT doc} {expecting c} {END_EVENT doc} {expecting d} 3: 1 {MATCH_ELEMENT_START expecting c} 4: 1 5: 1} test schema-17.27 {return "ignore" from recover handler for element end event} { tdom::schema s s define { defelement doc { element a element b element c element d } } s reportcmd schema-17.26 set result "" set xmlnr 0 foreach xml { <doc/> <doc><a/></doc> <doc><a/><b/></doc> <doc><a/><b/><d/></doc> <doc><a/><b/><c/><d/></doc> <doc><a/><b/><c/><c/><c/><d/></doc> } { set ::fromReportCmd "" lappend result $xmlnr: [s validate $xml errMsg] lappend result {*}$fromReportCmd incr xmlnr } s delete set result } {0: 1 {END_EVENT doc} {expecting a} {END_EVENT doc} {expecting b} {END_EVENT doc} {expecting c} {END_EVENT doc} {expecting d} 1: 1 {END_EVENT doc} {expecting b} {END_EVENT doc} {expecting c} {END_EVENT doc} {expecting d} 2: 1 {END_EVENT doc} {expecting c} {END_EVENT doc} {expecting d} 3: 1 {MATCH_ELEMENT_START expecting c} 4: 1 5: 1 {MATCH_ELEMENT_START expecting d}} proc schema-18 {args} { lappend ::result {*}$args } test schema-18.1 {reportcmd} { tdom::schema s s define { defelement doc { ................................................................................ s reportcmd "" lappend result [s reportcmd] s reportcmd dummycallback lappend result [s reportcmd] s delete set result } {{} {} dummycallback {} dummycallback} proc schema-18.22 {that scmd errorType} { lappend ::result $that $errorType } test schema-18.22 {reportcmd with arguments} { tdom::schema s s reportcmd "schema-18.22 this" s defelement doc { element a element b } set result "" lappend result [s validate {<doc><a/></doc>}] s delete set result } {this MISSING_ELEMENT 1} proc validatedSAX {g xml {keepEmpties 1}} { set args [list -validateCmd $g] if {!$keepEmpties} { lappend args -ignorewhitespace 1 } xml::parser p {*}$args set rc [catch {p parse $xml} errMsg] |