Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merged from schema. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | localkey |
Files: | files | file ages | folders |
SHA3-256: |
4879bb492bf44eb5005083e321b65e4a |
User & Date: | rolf 2019-05-09 19:16:27.337 |
Context
2019-05-10
| ||
00:40 | Merge from schema. check-in: 508a776b44 user: rolf tags: localkey | |
2019-05-09
| ||
19:16 | Merged from schema. check-in: 4879bb492b user: rolf tags: localkey | |
18:34 | Test added. check-in: 968b411fd1 user: rolf tags: schema | |
14:27 | wip check-in: b0e429ebf8 user: rolf tags: localkey | |
Changes
Changes to doc/schema.html.
1 2 3 4 5 6 | <html> <head> <link rel="stylesheet" href="manpage.css"><title>tDOM manual: schema</title><meta name="xsl-processor" content="Jochen Loewer ([email protected]), Rolf Ade ([email protected]) 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"> | | | | | | 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 | <html> <head> <link rel="stylesheet" href="manpage.css"><title>tDOM manual: schema</title><meta name="xsl-processor" content="Jochen Loewer ([email protected]), Rolf Ade ([email protected]) 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="#SECTid0x5563b3e4fb10">NAME</a> · <a href="#SECTid0x5563b3e50170">SYNOPSIS</a> · <a href="#SECTid0x5563b3e4a5f0">DESCRIPTION </a> · <a href="#SECTid0x5563b3ea8fc0">Schema definition scripts</a> · <a href="#SECTid0x5563b3eb12f0">Quantity specifier</a> · <a href="#SECTid0x5563b3eb3180">Text constraint scripts</a> · <a href="#SECTid0x5563b3ebb590">Exampels</a> </div><hr class="navsep"> </div><div class="body"> <h2><a name="SECTid0x5563b3e4fb10">NAME</a></h2><p class="namesection"> <b class="names">tdom::schema - </b><br>Create a schema validation command</p> <h2><a name="SECTid0x5563b3e50170">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="SECTid0x5563b3e4a5f0">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"> |
︙ | ︙ | |||
165 166 167 168 169 170 171 | <dt><b class="method">reset</b></dt> <dd>This method resets the validation command into state READY (while preserving the defined grammer).</dd> </dl> | | | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | <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="SECTid0x5563b3ea8fc0">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"> |
︙ | ︙ | |||
315 316 317 318 319 320 321 | 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> | | | 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | 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="SECTid0x5563b3eb12f0">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 |
︙ | ︙ | |||
360 361 362 363 364 365 366 | 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> | | | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | 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="SECTid0x5563b3eb3180">Text constraint scripts</a></h2><p></p><p>The text constraint commands are:</p><dl class="commandlist"> <dt><b class="cmd">isint</b></dt> <dd></dd> <dt> |
︙ | ︙ | |||
517 518 519 520 521 522 523 524 525 | <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> </dl> | > > > > > | | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 | <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 4648RFC 4648.</dd> </dl> <h2><a name="SECTid0x5563b3ebb590">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.
︙ | ︙ | |||
535 536 537 538 539 540 541 542 543 544 545 546 547 548 | 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. .SH Exampels .PP .UR "https://www.w3.org/TR/xmlschema-0/" <URL: https://www.w3.org/TR/xmlschema-0/> .UE The XML Schema Part 0: Primer Second Edition () starts with this | > > > > | 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | 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 RFC 4648RFC 4648. .SH Exampels .PP .UR "https://www.w3.org/TR/xmlschema-0/" <URL: https://www.w3.org/TR/xmlschema-0/> .UE The XML Schema Part 0: Primer Second Edition () starts with this |
︙ | ︙ |
Changes to doc/schema.xml.
︙ | ︙ | |||
476 477 478 479 480 481 482 483 484 485 486 487 488 489 | <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> </commandlist> </section> <section> <title>Exampels</title> <p>The XML Schema Part 0: Primer Second Edition | > > > > > | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | <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> <desc>This text constraint match if text is valid according to RFC 4648RFC 4648.</desc> </commanddef> </commandlist> </section> <section> <title>Exampels</title> <p>The XML Schema Part 0: Primer Second Edition |
︙ | ︙ |
Changes to generic/schema.c.
︙ | ︙ | |||
4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 | CHECK_TOPLEVEL checkNrArgs (1,1,"no argument expected"); ADD_CONSTRAINT (sdata, sc) sc->constraint = idrefImpl; sc->constraintData = (void *)sdata; return TCL_OK; } void tDOM_SchemaInit ( Tcl_Interp *interp ) { /* Inline definition commands. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 | CHECK_TOPLEVEL checkNrArgs (1,1,"no argument expected"); ADD_CONSTRAINT (sdata, sc) sc->constraint = idrefImpl; sc->constraintData = (void *)sdata; return TCL_OK; } static int base64Impl ( Tcl_Interp *interp, void *constraintData, char *text ) { int chars = 0, equals = 0; while (*text != '\0') { if (SPACE(*text)) { text++; continue; } if ( (*text >= 'A' && *text <= 'Z') || (*text >= 'a' && *text <= 'z') || (*text >= '0' && *text <= '9') || (*text = '+') || (*text = '/')) { chars++; text++; continue; } if (equals < 2 && *text == '=') { equals++; text++; continue; } break; } if (*text) { return 0; } if ((chars + equals) % 4 != 0) { return 0; } return 1; } static int base64TCObjCmd ( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] ) { SchemaData *sdata = GETASI; SchemaConstraint *sc; CHECK_TI CHECK_TOPLEVEL checkNrArgs (1,1,"No arguments expected"); ADD_CONSTRAINT (sdata, sc) sc->constraint = base64Impl; return TCL_OK; } void tDOM_SchemaInit ( Tcl_Interp *interp ) { /* Inline definition commands. */ |
︙ | ︙ | |||
4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 | stripTCObjCmd, NULL, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::split", splitTCObjCmd, NULL, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::id", idTCObjCmd, NULL, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::idref", idrefTCObjCmd, NULL, NULL); } #endif /* #ifndef TDOM_NO_SCHEMA */ | > > | 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 | stripTCObjCmd, NULL, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::split", splitTCObjCmd, NULL, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::id", idTCObjCmd, NULL, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::idref", idrefTCObjCmd, NULL, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::base64", base64TCObjCmd, NULL, NULL); } #endif /* #ifndef TDOM_NO_SCHEMA */ |
Changes to generic/schema.h.
︙ | ︙ | |||
101 102 103 104 105 106 107 | struct SchemaValidationStack *next; struct SchemaValidationStack *down; int activeChild; int hasMatched; int *interleaveState; } SchemaValidationStack; | < < | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | struct SchemaValidationStack *next; struct SchemaValidationStack *down; int activeChild; int hasMatched; int *interleaveState; } SchemaValidationStack; typedef enum { VALIDATION_READY, VALIDATION_STARTED, VALIDATION_ERROR, VALIDATION_FINISHED } ValidationState; |
︙ | ︙ |
Changes to generic/tcldom.c.
︙ | ︙ | |||
3944 3945 3946 3947 3948 3949 3950 | return TCL_OK; } /*---------------------------------------------------------------------------- | selectNodesNamespaces | \---------------------------------------------------------------------------*/ | | | | > > < < < < < < < | < < < < < < | < < < < < < < | < < < | < | > > | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 | return TCL_OK; } /*---------------------------------------------------------------------------- | selectNodesNamespaces | \---------------------------------------------------------------------------*/ int tcldom_prefixNSlist ( char ***prefixnsPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], const char *methodName ) { char **prefixns = *prefixnsPtr; int len, i, result; Tcl_Obj *objPtr, *listPtr; CheckArgs (2,3,2, "?prefixUriList?"); i = 0; if (objc == 2) { if (!prefixns) return TCL_OK; listPtr = Tcl_NewListObj (0, NULL); i = 0; while (prefixns[i]) { Tcl_ListObjAppendElement ( interp, listPtr, Tcl_NewStringObj (prefixns[i], -1) ); i++; } Tcl_SetObjResult (interp, listPtr); return TCL_OK; } result = Tcl_ListObjLength (interp, objv[2], &len); if (result != TCL_OK || (len % 2) != 0) { SetResult3 ("The optional argument to the ", methodName, " method must be a 'prefix namespace' pairs list"); return TCL_ERROR; } if (prefixns) { while (prefixns[i]) { FREE (prefixns[i]); i++; } } if (len == 0) { FREE (prefixns); *prefixnsPtr = NULL; return TCL_OK; } if (i < len + 1) { if (prefixns) FREE (prefixns); prefixns = MALLOC (sizeof (char*) * (len+1)); *prefixnsPtr = prefixns; } for (i = 0; i < len; i++) { Tcl_ListObjIndex (interp, objv[2], i, &objPtr); prefixns[i] = tdomstrdup (Tcl_GetString (objPtr)); } prefixns[len] = NULL; Tcl_SetObjResult (interp, objv[2]); return TCL_OK; } /*---------------------------------------------------------------------------- | renameNodes | \---------------------------------------------------------------------------*/ |
︙ | ︙ | |||
5923 5924 5925 5926 5927 5928 5929 | SetResult("DOCUMENT_NODE"); return TCL_OK; case m_cdataSectionElements: return cdataSectionElements (doc, interp, objc, objv); case m_selectNodesNamespaces: | > | | | 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 | SetResult("DOCUMENT_NODE"); return TCL_OK; case m_cdataSectionElements: return cdataSectionElements (doc, interp, objc, objv); case m_selectNodesNamespaces: return tcldom_prefixNSlist (&(doc->prefixNSMappings), interp, objc, objv, "selectNodesNamespaces"); case m_renameNode: return renameNodes (doc, interp, objc, objv); case m_deleteXPathCache: return deleteXPathCache (doc, interp, objc, objv); case m_appendChild: |
︙ | ︙ |
Changes to generic/tcldom.h.
︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 62 63 64 | int isFQName); void tcldom_createNodeObj(Tcl_Interp * interp, domNode *node, char *objCmdName); domNode * tcldom_getNodeFromObj(Tcl_Interp *interp, Tcl_Obj *nodeObj); domDocument * tcldom_getDocumentFromName(Tcl_Interp *interp, char *docName, char **errMsg); void tcldom_initialize(void); Tcl_ObjCmdProc tcldom_DomObjCmd; Tcl_ObjCmdProc tcldom_DocObjCmd; Tcl_ObjCmdProc tcldom_NodeObjCmd; Tcl_ObjCmdProc TclExpatObjCmd; | > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | int isFQName); void tcldom_createNodeObj(Tcl_Interp * interp, domNode *node, char *objCmdName); domNode * tcldom_getNodeFromObj(Tcl_Interp *interp, Tcl_Obj *nodeObj); domDocument * tcldom_getDocumentFromName(Tcl_Interp *interp, char *docName, char **errMsg); int tcldom_prefixNSlist (char ***prefixnsPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], const char *methodName); void tcldom_initialize(void); Tcl_ObjCmdProc tcldom_DomObjCmd; Tcl_ObjCmdProc tcldom_DocObjCmd; Tcl_ObjCmdProc tcldom_NodeObjCmd; Tcl_ObjCmdProc TclExpatObjCmd; |
︙ | ︙ |
Changes to tests/dom.test.
︙ | ︙ | |||
176 177 178 179 180 181 182 183 184 185 186 187 188 189 | dom createDocument test doc set result [catch {set doc foo} errMsg] lappend result $errMsg $doc delete unset doc set result } {1 {can't set "doc": var is read-only}} test dom-2.1 {Don't quash white space at start or end of non white space content} { set doc [dom parse {<root> some content </root>}] set root [$doc documentElement] $root text | > > > > > > > > > > > > > | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | dom createDocument test doc set result [catch {set doc foo} errMsg] lappend result $errMsg $doc delete unset doc set result } {1 {can't set "doc": var is read-only}} test dom-1.25 {Doc var} { dom parse <test/> doc dom parse <test/> doc unset doc } {} test dom-1.26 {Doc var} { dom parse <test/> doc set result [catch {$doc documentElement doc}] unset doc set result } {1} test dom-2.1 {Don't quash white space at start or end of non white space content} { set doc [dom parse {<root> some content </root>}] set root [$doc documentElement] $root text |
︙ | ︙ |
Changes to tests/loadtdom.tcl.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # We still support 8.4 to some degree package require Tcl 8.4 } else { package require Tcl 8.4- } package require tcltest 2.2 namespace import ::tcltest::* if {[catch {package require -exact tdom 0.9.2}]} { if {[catch {load [file join [file dir [info script]] ../unix/libtdom0.9.2.so]}]} { error "Unable to load the appropriate tDOM version!" } } if {[info commands ::tdom::xmlReadFile] == ""} { # tcldomsh without the script library. Source the lib. | > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # We still support 8.4 to some degree package require Tcl 8.4 } else { package require Tcl 8.4- } package require tcltest 2.2 namespace import ::tcltest::* catch {tcltest::loadTestedCommands} if {[catch {package require -exact tdom 0.9.2}]} { if {[catch {load [file join [file dir [info script]] ../unix/libtdom0.9.2.so]}]} { error "Unable to load the appropriate tDOM version!" } } if {[info commands ::tdom::xmlReadFile] == ""} { # tcldomsh without the script library. Source the lib. |
︙ | ︙ |
Changes to tests/schema.test.
︙ | ︙ | |||
3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 | {<doc><idref idref="abc"/><idref idref="123"/></doc>} } { lappend result [s validate $xml] } s delete set result } {1 1 0 1 1 1 1 0 0 0} test schema-15.1 {constraint cmd tcl} { tdom::schema s s define { defelement a { tcl append ::schema-15.1 element b | > > > > > > > > > > > > > > > > > > > > > > > > | 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 | {<doc><idref idref="abc"/><idref idref="123"/></doc>} } { lappend result [s validate $xml] } s delete set result } {1 1 0 1 1 1 1 0 0 0} test schema-14.27 {base64} { tdom::schema s s define { defelement doc { text base64 } } set result [list] foreach xml { <doc/> {<doc>ZVL1</doc>} {<doc>zvL1</doc>} {<doc>zvü1</doc>} {<doc>0a BED E+9</doc>} {<doc>ub1sU3==</doc>} {<doc>abc</doc>} {<doc>===</doc>} } { lappend result [s validate $xml] } s delete set result } {1 1 1 0 1 1 0 0} test schema-15.1 {constraint cmd tcl} { tdom::schema s s define { defelement a { tcl append ::schema-15.1 element b |
︙ | ︙ | |||
4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 | test schema-17.2 {info} { tdom::schema s s define { defelement b { element b1 element b2 } defelement a { element a1 element a2 } } set result [lsort [s info defelements]] | > > > > > > > > > > > > > > > > > > | 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 | test schema-17.2 {info} { tdom::schema s s define { defelement b { element b1 element b2 } defelement a { element a1 element a2 } } set result [lsort [s info defelements]] s delete set result } {a b} test schema-17.3 {info} { tdom::schema s s define { defelement b { element b1 1 text element a element b2 } defelement a { element a1 element a2 } } set result [lsort [s info defelements]] |
︙ | ︙ |