Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fixed bug introduced with prefixns: the shortcuts from prefixns are only used for schema definiton; they mean nothing for prefix/namespace in the xml input. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | schema |
Files: | files | file ages | folders |
SHA3-256: |
40671ee8c38a593046f959a1c79e80ea |
User & Date: | rolf 2019-08-06 23:11:33 |
Context
2019-08-06
| ||
23:31 | Removed cruft for versions not supported anymore. check-in: 13fe3aff35 user: rolf tags: schema | |
23:11 | Fixed bug introduced with prefixns: the shortcuts from prefixns are only used for schema definiton; they mean nothing for prefix/namespace in the xml input. check-in: 40671ee8c3 user: rolf tags: schema | |
2019-08-02
| ||
23:52 | The comment is correct, adjusted the code to do what it say. check-in: 4d478f979b user: rolf tags: schema | |
Changes
Changes to doc/schema.html.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ... 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 ... 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 ... 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 ... 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 ... 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 |
<html> <head> <link rel="stylesheet" href="manpage.css"><title>tDOM manual: schema</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: tmml-html.xsl,v $ $Revision: 1.11 $"><meta charset="utf-8"> </head><body> <div class="header"> <div class="navbar" align="center"> <a href="#SECTid0x55cd0c9deb30">NAME</a> · <a href="#SECTid0x55cd0c9df160">SYNOPSIS</a> · <a href="#SECTid0x55cd0c9d95d0">DESCRIPTION </a> · <a href="#SECTid0x55cd0ca3a0f0">Schema definition scripts</a> · <a href="#SECTid0x55cd0ca43030">Quantity specifier</a> · <a href="#SECTid0x55cd0ca44ec0">Text constraint scripts</a> · <a href="#SECTid0x55cd0ca4d9c0">Local key constraints</a> · <a href="#SECTid0x55cd0ca4f7d0">Exampels</a> </div><hr class="navsep"> </div><div class="body"> <h2><a name="SECTid0x55cd0c9deb30">NAME</a></h2><p class="namesection"> <b class="names">tdom::schema - </b><br>Create a schema validation command</p> <h2><a name="SECTid0x55cd0c9df160">SYNOPSIS</a></h2><pre class="syntax">package require tdom <b class="cmd">tdom::schema</b> <i class="m">?create?</i> <i class="m">cmdName</i> </pre> <h2><a name="SECTid0x55cd0c9d95d0">DESCRIPTION </a></h2><p>This command creates validation commands with a simple API. The validation commands have methods to define a schema and are able to validate XML or DOM trees (and to some degree other kind of hierarchical data) against this schema.</p><p>Additionally, a validation command may be used as argument to the <i class="m">-validateCmd</i> option of the <i class="m">dom parse</i> and the <i class="m">expat</i> commands to enable validation additional to what they otherwise do.</p><p>The valid methods of the created commands are:</p><dl class="commandlist"> ................................................................................ <dt><b class="method">reset</b></dt> <dd>This method resets the validation command into state READY (while preserving the defined grammer).</dd> </dl> <h2><a name="SECTid0x55cd0ca3a0f0">Schema definition scripts</a></h2><p>Schema definition scripts are ordinary Tcl scripts that are evaluatend in the namespace tdom::schema. The below listed schema definition commands in this tcl namespace allow to define a wide variety of document structures. Every schema definition command establish a validation constraint on the content which has to match or must be optional to render the content as valid. It is a validation error if the element in the XML source has additional (not matched) content.</p><p>The schema definition commands are:</p><dl class="commandlist"> ................................................................................ call. This is meant as toplevel command of a <i>schemacmd define</i> script. This command is not allowed nested in an other definition script command and will raise error, if you call it there.</dd> </dl> <h2><a name="SECTid0x55cd0ca43030">Quantity specifier</a></h2><p>Serveral schema definition commands expects a quantifier as one of their arguments, which specifies how often the content particle specified by the command is expected. The valid values for a <i class="m">quant</i> argument are:</p><dl class="optlist"> <dt><b>!</b></dt> <dd>The content particle must occur exactly once in valid documents. This is the default, if a quantifier is ................................................................................ n to m times (both inclusive) in a row in valid documents. The quantifier must be a tcl list with two elements. Both elements must be integers, with n >= 0 and n < m.</dd> </dl><p>If an optional quantifier is not given then it defaults to * in case of the mixed command and to ! for all other commands.</p> <h2><a name="SECTid0x55cd0ca44ec0">Text constraint scripts</a></h2><p>Text - parsed character data, as XML calles it - must sometimes have to be of a certain kind, must comply to some rules etc to be valid.</p><p>The text constraint commands are:</p><dl class="commandlist"> <dt> <b class="cmd">integer</b> <i class="m">?(xsd|tcl)?</i> </dt> <dd>This text constraint match if the text value could be ................................................................................ which elements are tested..</dd> </dl> <p>The default in case no split type argument is given is <i class="m">whitespace</i>.</p> </dd> <dt><b class="cmd">id</b></dt> <dd>This text constraint command marks the text as a document wide ID (to be referenced by an idref). Every ID value within a document must be unique. It isn't an error if the ID isn't actually referenced within the document.</dd> <dt><b class="cmd">idref</b></dt> <dd>This text constraint command expects the text to be a reference to an ID within the document. The referenced ID may be later in the document, that the reference. Several references within the document to one ID are possible.</dd> <dt><b class="cmd">base64</b></dt> <dd>This text constraint match if text is valid according to RFC 4648.</dd> </dl> <h2><a name="SECTid0x55cd0ca4d9c0">Local key constraints</a></h2><p>Document wide uniqueness and foreign key constraints are available with the text constraint commands id and idref. Keyspaces allow for sub-tree local uniqueness and foreign key constraints.</p><dl class="commandlist"> <dt> <b class="cmd">keyspace</b> <i class="m">names list></i> <i class="m"><constraint script></i> </dt> ................................................................................ active always matches. If the keyspace is active then reports error if there is still no key as the value at the end of the keyspace <i class="m">name></i>. Otherwise it matches.</dd> </dl> <h2><a name="SECTid0x55cd0ca4f7d0">Exampels</a></h2><p>The XML Schema Part 0: Primer Second Edition (<a href="https://www.w3.org/TR/xmlschema-0/">https://www.w3.org/TR/xmlschema-0/</a>) starts with this example schema:</p><pre class="example"> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:annotation> <xsd:documentation xml:lang="en"> Purchase order schema for Example.com. |
| | | | | | | | > | > > > > | > | | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ... 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 ... 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 ... 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 ... 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 ... 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 |
<html> <head> <link rel="stylesheet" href="manpage.css"><title>tDOM manual: schema</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: tmml-html.xsl,v $ $Revision: 1.11 $"><meta charset="utf-8"> </head><body> <div class="header"> <div class="navbar" align="center"> <a href="#SECTid0x55bd61f17b30">NAME</a> · <a href="#SECTid0x55bd61f18190">SYNOPSIS</a> · <a href="#SECTid0x55bd61f12610">DESCRIPTION </a> · <a href="#SECTid0x55bd61f6f140">Schema definition scripts</a> · <a href="#SECTid0x55bd61f78080">Quantity specifier</a> · <a href="#SECTid0x55bd61f79f10">Text constraint scripts</a> · <a href="#SECTid0x55bd61f82e70">Local key constraints</a> · <a href="#SECTid0x55bd61f84c80">Exampels</a> </div><hr class="navsep"> </div><div class="body"> <h2><a name="SECTid0x55bd61f17b30">NAME</a></h2><p class="namesection"> <b class="names">tdom::schema - </b><br>Create a schema validation command</p> <h2><a name="SECTid0x55bd61f18190">SYNOPSIS</a></h2><pre class="syntax">package require tdom <b class="cmd">tdom::schema</b> <i class="m">?create?</i> <i class="m">cmdName</i> </pre> <h2><a name="SECTid0x55bd61f12610">DESCRIPTION </a></h2><p>This command creates validation commands with a simple API. The validation commands have methods to define a schema and are able to validate XML or DOM trees (and to some degree other kind of hierarchical data) against this schema.</p><p>Additionally, a validation command may be used as argument to the <i class="m">-validateCmd</i> option of the <i class="m">dom parse</i> and the <i class="m">expat</i> commands to enable validation additional to what they otherwise do.</p><p>The valid methods of the created commands are:</p><dl class="commandlist"> ................................................................................ <dt><b class="method">reset</b></dt> <dd>This method resets the validation command into state READY (while preserving the defined grammer).</dd> </dl> <h2><a name="SECTid0x55bd61f6f140">Schema definition scripts</a></h2><p>Schema definition scripts are ordinary Tcl scripts that are evaluatend in the namespace tdom::schema. The below listed schema definition commands in this tcl namespace allow to define a wide variety of document structures. Every schema definition command establish a validation constraint on the content which has to match or must be optional to render the content as valid. It is a validation error if the element in the XML source has additional (not matched) content.</p><p>The schema definition commands are:</p><dl class="commandlist"> ................................................................................ call. This is meant as toplevel command of a <i>schemacmd define</i> script. This command is not allowed nested in an other definition script command and will raise error, if you call it there.</dd> </dl> <h2><a name="SECTid0x55bd61f78080">Quantity specifier</a></h2><p>Serveral schema definition commands expects a quantifier as one of their arguments, which specifies how often the content particle specified by the command is expected. The valid values for a <i class="m">quant</i> argument are:</p><dl class="optlist"> <dt><b>!</b></dt> <dd>The content particle must occur exactly once in valid documents. This is the default, if a quantifier is ................................................................................ n to m times (both inclusive) in a row in valid documents. The quantifier must be a tcl list with two elements. Both elements must be integers, with n >= 0 and n < m.</dd> </dl><p>If an optional quantifier is not given then it defaults to * in case of the mixed command and to ! for all other commands.</p> <h2><a name="SECTid0x55bd61f79f10">Text constraint scripts</a></h2><p>Text - parsed character data, as XML calles it - must sometimes have to be of a certain kind, must comply to some rules etc to be valid.</p><p>The text constraint commands are:</p><dl class="commandlist"> <dt> <b class="cmd">integer</b> <i class="m">?(xsd|tcl)?</i> </dt> <dd>This text constraint match if the text value could be ................................................................................ which elements are tested..</dd> </dl> <p>The default in case no split type argument is given is <i class="m">whitespace</i>.</p> </dd> <dt><b class="cmd">id <i class="m">?keySpace?</i> </b></dt> <dd>This text constraint command marks the text as a document wide ID (to be referenced by an idref). Every ID value within a document must be unique. It isn't an error if the ID isn't actually referenced within the document. The optional argument <i class="m">keySpace</i> does all this for a named key space. The key space "" (the empty sting) is another key space as the <i class="m">id</i> command without keySpace argument.</dd> <dt><b class="cmd">idref <i class="m">?keySpace?</i> </b></dt> <dd>This text constraint command expects the text to be a reference to an ID within the document. The referenced ID may be later in the document, that the reference. Several references within the document to one ID are possible.</dd> <dt><b class="cmd">base64</b></dt> <dd>This text constraint match if text is valid according to RFC 4648.</dd> </dl> <h2><a name="SECTid0x55bd61f82e70">Local key constraints</a></h2><p>Document wide uniqueness and foreign key constraints are available with the text constraint commands id and idref. Keyspaces allow for sub-tree local uniqueness and foreign key constraints.</p><dl class="commandlist"> <dt> <b class="cmd">keyspace</b> <i class="m">names list></i> <i class="m"><constraint script></i> </dt> ................................................................................ active always matches. If the keyspace is active then reports error if there is still no key as the value at the end of the keyspace <i class="m">name></i>. Otherwise it matches.</dd> </dl> <h2><a name="SECTid0x55bd61f84c80">Exampels</a></h2><p>The XML Schema Part 0: Primer Second Edition (<a href="https://www.w3.org/TR/xmlschema-0/">https://www.w3.org/TR/xmlschema-0/</a>) starts with this example schema:</p><pre class="example"> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:annotation> <xsd:documentation xml:lang="en"> Purchase order schema for Example.com. |
Changes to doc/schema.n.
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 |
as last argument. This call must return a valid tcl list, which elements are tested.. .PP The default in case no split type argument is given is \&\fIwhitespace\fR. .RE .TP \&\fB\fBid\fP \&\fRThis text constraint command marks the text as a document wide ID (to be referenced by an idref). Every ID value within a document must be unique. It isn't an error if the ID isn't actually referenced within the document. .TP \&\fB\fBidref\fP \&\fRThis text constraint command expects the text to be a reference to an ID within the document. The referenced ID may be later in the document, that the reference. Several references within the document to one ID are possible. .TP \&\fB\fBbase64\fP \&\fRThis text constraint match if text is valid according to |
| | > > > > | |
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 |
as last argument. This call must return a valid tcl list, which elements are tested.. .PP The default in case no split type argument is given is \&\fIwhitespace\fR. .RE .TP \&\fB\fBid \fI?keySpace?\fB\fP \&\fRThis text constraint command marks the text as a document wide ID (to be referenced by an idref). Every ID value within a document must be unique. It isn't an error if the ID isn't actually referenced within the document. The optional argument \fIkeySpace\fR does all this for a named key space. The key space "" (the empty sting) is another key space as the \fIid\fR command without keySpace argument. .TP \&\fB\fBidref \fI?keySpace?\fB\fP \&\fRThis text constraint command expects the text to be a reference to an ID within the document. The referenced ID may be later in the document, that the reference. Several references within the document to one ID are possible. .TP \&\fB\fBbase64\fP \&\fRThis text constraint match if text is valid according to |
Changes to doc/schema.xml.
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 |
as last argument. This call must return a valid tcl list,
which elements are tested..</dd>
</dl>
<p>The default in case no split type argument is given is
<m>whitespace</m>.</p></desc>
</commanddef>
<commanddef>
<command><cmd>id</cmd></command>
<desc>This text constraint command marks the text as a
document wide ID (to be referenced by an idref). Every ID
value within a document must be unique. It isn't an error if
the ID isn't actually referenced within the document.</desc>
</commanddef>
<commanddef>
<command><cmd>idref</cmd></command>
<desc>This text constraint command expects the text to be a
reference to an ID within the document. The referenced ID may
be later in the document, that the reference. Several
references within the document to one ID are possible.</desc>
</commanddef>
<commanddef>
<command><cmd>base64</cmd></command>
|
| | > > > > | |
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 |
as last argument. This call must return a valid tcl list, which elements are tested..</dd> </dl> <p>The default in case no split type argument is given is <m>whitespace</m>.</p></desc> </commanddef> <commanddef> <command><cmd>id <m>?keySpace?</m></cmd></command> <desc>This text constraint command marks the text as a document wide ID (to be referenced by an idref). Every ID value within a document must be unique. It isn't an error if the ID isn't actually referenced within the document. The optional argument <m>keySpace</m> does all this for a named key space. The key space "" (the empty sting) is another key space as the <m>id</m> command without keySpace argument.</desc> </commanddef> <commanddef> <command><cmd>idref <m>?keySpace?</m></cmd></command> <desc>This text constraint command expects the text to be a reference to an ID within the document. The referenced ID may be later in the document, that the reference. Several references within the document to one ID are possible.</desc> </commanddef> <commanddef> <command><cmd>base64</cmd></command> |
Changes to generic/schema.c.
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 ... 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 .... 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 .... 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 .... 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 .... 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 .... 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 .... 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 |
cleanupLastPattern ( SchemaData *sdata, unsigned int from ) { unsigned int i; Tcl_HashTable *hashTable; Tcl_HashEntry *entryPtr; SchemaCP *this, *previous, *current; for (i = from; i < sdata->numPatternList; i++) { this = sdata->patternList[i]; hashTable = NULL; if (this->type == SCHEMA_CTYPE_NAME) { ................................................................................ if (this->type == SCHEMA_CTYPE_PATTERN) { hashTable = &sdata->pattern; } if (this->name && hashTable) { if (this->flags & FORWARD_PATTERN_DEF) { sdata->forwardPatternDefs--; } entryPtr = Tcl_FindHashEntry (hashTable, this->name); previous = NULL; current = Tcl_GetHashValue (entryPtr); while (current != NULL && current != this) { previous = current; current = current->next; } if (previous) { if (current->next) { previous->next = current->next; } else { previous->next = NULL; } } else { if (current) { Tcl_SetHashValue (entryPtr, current->next); } else { Tcl_DeleteHashEntry (entryPtr); } } } freeSchemaCP (sdata->patternList[i]); } sdata->numPatternList = from; } ................................................................................ case SCHEMA_CTYPE_KEYSPACE_END: case SCHEMA_CTYPE_KEYSPACE: Tcl_Panic ("Keyspace constraint child of INTERLEAVE"); break; } } if (mayskip) break; if (recover (interp, sdata, S("UNCOMPLET_CP"))) { sdata->skipDeep = 2; return 1; } ................................................................................ probeElement ( Tcl_Interp *interp, SchemaData *sdata, const char *name, void *namespace ) { Tcl_HashEntry *entryPtr; void *namespacePtr, *namePtr; SchemaCP *pattern; int rc; if (sdata->skipDeep) { sdata->skipDeep++; return TCL_OK; } if (sdata->validationState == VALIDATION_FINISHED) { SetResult ("Validation finished."); ................................................................................ } DBG( fprintf (stderr, "probeElement: look if '%s' in ns '%s' match\n", name, (char *)namespace); ); namespacePtr = getNamespacePtr (sdata, namespace); entryPtr = Tcl_FindHashEntry (&sdata->element, name); if (entryPtr) { namePtr = Tcl_GetHashKey (&sdata->element, entryPtr); } else { namePtr = NULL; } if (sdata->validationState == VALIDATION_READY) { /* The root of the tree to check. */ if (sdata->start) { if (strcmp (name, sdata->start) != 0) { SetResult ("Root element doesn't match"); return TCL_ERROR; ................................................................................ if (sdata->startNamespace) { SetResult ("Root element namespace doesn't match"); return TCL_ERROR; } } } } if (entryPtr) { pattern = (SchemaCP *) Tcl_GetHashValue (entryPtr); while (pattern) { if (pattern->namespace == namespacePtr) { break; } pattern = pattern->next; } } else { ................................................................................ int objc, Tcl_Obj *const objv[] ) { SchemaData *sdata = GETASI; Schema_CP_Type patternType = (Schema_CP_Type) clientData; Tcl_HashTable *hashTable; Tcl_HashEntry *entryPtr; SchemaCP *pattern = NULL, *current; SchemaQuant quant; int hnew, n, m; CHECK_SI CHECK_TOPLEVEL if (patternType == SCHEMA_CTYPE_NAME) { ................................................................................ hashTable = &sdata->pattern; } quant = getQuant (interp, sdata, objc == 2 ? NULL : objv[2], &n, &m); if (quant == SCHEMA_CQUANT_ERROR) { return TCL_ERROR; } entryPtr = Tcl_CreateHashEntry (hashTable, Tcl_GetString(objv[1]), &hnew); if (objc < 4) { /* Reference to an element or pattern */ if (!hnew) { pattern = (SchemaCP *) Tcl_GetHashValue (entryPtr); while (pattern) { if (pattern->namespace == sdata->currentNamespace) { break; } pattern = pattern->next; } } if (!pattern) { pattern = initSchemaCP ( patternType, sdata->currentNamespace, Tcl_GetHashKey (hashTable, entryPtr) ); pattern->flags |= FORWARD_PATTERN_DEF; sdata->forwardPatternDefs++; if (!hnew) { current = (SchemaCP *) Tcl_GetHashValue (entryPtr); pattern->next = current; } REMEMBER_PATTERN (pattern); Tcl_SetHashValue (entryPtr, pattern); } addToContent (sdata, pattern, quant, n, m); } else { /* Local definition of this element */ if (hnew) { pattern = initSchemaCP ( SCHEMA_CTYPE_NAME, sdata->currentNamespace, Tcl_GetHashKey (hashTable, entryPtr) ); pattern->flags |= PLACEHOLDER_PATTERN_DEF; REMEMBER_PATTERN (pattern); Tcl_SetHashValue (entryPtr, pattern); } pattern = initSchemaCP ( SCHEMA_CTYPE_NAME, sdata->currentNamespace, Tcl_GetHashKey (hashTable, entryPtr) ); pattern->flags |= LOCAL_DEFINED_ELEMENT; return evalDefinition (interp, sdata, objv[3], pattern, quant, n, m); } return TCL_OK; } |
| | | | | < | | > > > > > > > > > > > > > > > > > > | > > > > > > | | | | | | > | | | | | | | | | | | |
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 ... 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 .... 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 .... 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 .... 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 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 .... 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 .... 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 .... 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 |
cleanupLastPattern ( SchemaData *sdata, unsigned int from ) { unsigned int i; Tcl_HashTable *hashTable; Tcl_HashEntry *h; SchemaCP *this, *previous, *current; for (i = from; i < sdata->numPatternList; i++) { this = sdata->patternList[i]; hashTable = NULL; if (this->type == SCHEMA_CTYPE_NAME) { ................................................................................ if (this->type == SCHEMA_CTYPE_PATTERN) { hashTable = &sdata->pattern; } if (this->name && hashTable) { if (this->flags & FORWARD_PATTERN_DEF) { sdata->forwardPatternDefs--; } h = Tcl_FindHashEntry (hashTable, this->name); previous = NULL; current = Tcl_GetHashValue (h); while (current != NULL && current != this) { previous = current; current = current->next; } if (previous) { if (current->next) { previous->next = current->next; } else { previous->next = NULL; } } else { if (current) { Tcl_SetHashValue (h, current->next); } else { Tcl_DeleteHashEntry (h); } } } freeSchemaCP (sdata->patternList[i]); } sdata->numPatternList = from; } ................................................................................ case SCHEMA_CTYPE_KEYSPACE_END: case SCHEMA_CTYPE_KEYSPACE: Tcl_Panic ("Keyspace constraint child of INTERLEAVE"); break; } } if (mayskip) break; if (recover (interp, sdata, S("UNCOMPLET_CP"))) { sdata->skipDeep = 2; return 1; } ................................................................................ probeElement ( Tcl_Interp *interp, SchemaData *sdata, const char *name, void *namespace ) { Tcl_HashEntry *h; void *namespacePtr, *namePtr; SchemaCP *pattern; int rc = 1; if (sdata->skipDeep) { sdata->skipDeep++; return TCL_OK; } if (sdata->validationState == VALIDATION_FINISHED) { SetResult ("Validation finished."); ................................................................................ } DBG( fprintf (stderr, "probeElement: look if '%s' in ns '%s' match\n", name, (char *)namespace); ); /* This is problematic. If feeded with continuously new namespaces */ if (namespace) { h = Tcl_FindHashEntry (&sdata->namespace, namespace); } else { h = NULL; } if (h) { namespacePtr = Tcl_GetHashKey (&sdata->namespace, h); } else { if (namespace) { /* This namespace isn't known at all by the schema; this * element may only match an any condition. If it does we * know only later. So we use namePtr and namespacePtr * both NULL that match nothing else in the schema and * will be able to look if there is such a possible any * match in the schema. */ rc = 0; } namespacePtr = NULL; } if (!rc) { /* Already the provided namespace isn't known to the schema, * so the name in that namespace of course also. */ namePtr = NULL; } else { h = Tcl_FindHashEntry (&sdata->element, name); if (h) { namePtr = Tcl_GetHashKey (&sdata->element, h); } else { namePtr = NULL; } } if (sdata->validationState == VALIDATION_READY) { /* The root of the tree to check. */ if (sdata->start) { if (strcmp (name, sdata->start) != 0) { SetResult ("Root element doesn't match"); return TCL_ERROR; ................................................................................ if (sdata->startNamespace) { SetResult ("Root element namespace doesn't match"); return TCL_ERROR; } } } } if (h) { pattern = (SchemaCP *) Tcl_GetHashValue (h); while (pattern) { if (pattern->namespace == namespacePtr) { break; } pattern = pattern->next; } } else { ................................................................................ int objc, Tcl_Obj *const objv[] ) { SchemaData *sdata = GETASI; Schema_CP_Type patternType = (Schema_CP_Type) clientData; Tcl_HashTable *hashTable; Tcl_HashEntry *h; SchemaCP *pattern = NULL, *current; SchemaQuant quant; int hnew, n, m; CHECK_SI CHECK_TOPLEVEL if (patternType == SCHEMA_CTYPE_NAME) { ................................................................................ hashTable = &sdata->pattern; } quant = getQuant (interp, sdata, objc == 2 ? NULL : objv[2], &n, &m); if (quant == SCHEMA_CQUANT_ERROR) { return TCL_ERROR; } h = Tcl_CreateHashEntry (hashTable, Tcl_GetString(objv[1]), &hnew); if (objc < 4) { /* Reference to an element or pattern */ if (!hnew) { pattern = (SchemaCP *) Tcl_GetHashValue (h); while (pattern) { if (pattern->namespace == sdata->currentNamespace) { break; } pattern = pattern->next; } } if (!pattern) { pattern = initSchemaCP ( patternType, sdata->currentNamespace, Tcl_GetHashKey (hashTable, h) ); pattern->flags |= FORWARD_PATTERN_DEF; sdata->forwardPatternDefs++; if (!hnew) { current = (SchemaCP *) Tcl_GetHashValue (h); pattern->next = current; } REMEMBER_PATTERN (pattern); Tcl_SetHashValue (h, pattern); } addToContent (sdata, pattern, quant, n, m); } else { /* Local definition of this element */ if (hnew) { pattern = initSchemaCP ( SCHEMA_CTYPE_NAME, sdata->currentNamespace, Tcl_GetHashKey (hashTable, h) ); pattern->flags |= PLACEHOLDER_PATTERN_DEF; REMEMBER_PATTERN (pattern); Tcl_SetHashValue (h, pattern); } pattern = initSchemaCP ( SCHEMA_CTYPE_NAME, sdata->currentNamespace, Tcl_GetHashKey (hashTable, h) ); pattern->flags |= LOCAL_DEFINED_ELEMENT; return evalDefinition (interp, sdata, objv[3], pattern, quant, n, m); } return TCL_OK; } |
Changes to tests/schema.test.
596
597
598
599
600
601
602
603
604
605
606
607
608
609
....
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
|
}
} errMsg]
lappend result $errMsg
s delete
set result
} {1 {Command only allowed at lop level} 1 {Command only allowed at lop level} 1 {Method not allowed in nested schema define script} 1 {This recursive call is not allowed}}
test schema-2.1 {grammar definition: ref} {
tdom::schema create grammar
grammar defpattern thisPattern {
element a
element b
}
grammar defpattern thatPattern {
................................................................................
{<doc xmlns:ns="http://foo.bar" xmlns:ns1="http://foo.grill"><a/><ns1:a/><ns:b>some</ns:b><b/></doc>}
} {
lappend result [s validate $xml]
}
s delete
set result
} {0 0 0 0 1 1 0}
test schema-11.1 {attribute} {
tdom::schema create s
s define {
defelement doc {
attribute attr1
attribute attr2 ?
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
....
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
|
} } errMsg] lappend result $errMsg s delete set result } {1 {Command only allowed at lop level} 1 {Command only allowed at lop level} 1 {Method not allowed in nested schema define script} 1 {This recursive call is not allowed}} test schema-1.27 {prefixns} { tdom::schema create s s define { prefixns {a http:://some.uri} defelement doc a {} } set result [s validate {<b:doc xmlns:b="a"/>} errMsg] lappend result $errMsg s delete set result } {0 {error "Unknown element" at line 1 character 20}} test schema-2.1 {grammar definition: ref} { tdom::schema create grammar grammar defpattern thisPattern { element a element b } grammar defpattern thatPattern { ................................................................................ {<doc xmlns:ns="http://foo.bar" xmlns:ns1="http://foo.grill"><a/><ns1:a/><ns:b>some</ns:b><b/></doc>} } { lappend result [s validate $xml] } s delete set result } {0 0 0 0 1 1 0} test schema-10.6 {any} { tdom::schema create s s define { defelement doc { any } } set result [list] foreach xml { {<doc><a:some xmlns:a="uri"/></doc>} } { lappend result [s validate $xml] } s delete set result } {1} test schema-11.1 {attribute} { tdom::schema create s s define { defelement doc { attribute attr1 attribute attr2 ? |