Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Gardening around. Moved generation of all schmea related Tcl commands to tDOM_SchemaInit(). Moved the method 'status' as 'validationstatus' (alias 'vstatus') under the 'info' method and used the opportunity to start to define the schema command method info.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | schema
Files: files | file ages | folders
SHA3-256: e5493b6b50eef92138145e078e819bc6f68155ae3afb95be2dd337ae71efe0c0
User & Date: rolf 2019-07-23 23:54:45
Context
2019-07-31
22:17
Hardened isodate. check-in: 4fed50bd75 user: rolf tags: schema
2019-07-23
23:54
Gardening around. Moved generation of all schmea related Tcl commands to tDOM_SchemaInit(). Moved the method 'status' as 'validationstatus' (alias 'vstatus') under the 'info' method and used the opportunity to start to define the schema command method info. check-in: e5493b6b50 user: rolf tags: schema
2019-07-12
22:26
Merged from trunk. check-in: df3a907a20 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
...
161
162
163
164
165
166
167







168
169
170
171
172
173
174
175
176
177
178
179
180







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
...
259
260
261
262
263
264
265
266
267
268

269

270
271
272


273
274
275
276
277
278
279
...
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
...
390
391
392
393
394
395
396
397
398
399
400

401







402
403
404
405
406
407
408
409
...
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
...
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
...
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
<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="#SECTid0x555cbefafb30">NAME</a> · <a href="#SECTid0x555cbefb0160">SYNOPSIS</a> · <a href="#SECTid0x555cbefaa5d0">DESCRIPTION </a> · <a href="#SECTid0x555cbf00a680">Schema definition scripts</a> · <a href="#SECTid0x555cbf0131a0">Quantity specifier</a> · <a href="#SECTid0x555cbf015030">Text constraint scripts</a> · <a href="#SECTid0x555cbf01d520">Local key constraints</a> · <a href="#SECTid0x555cbf01f330">Exampels</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid0x555cbefafb30">NAME</a></h2><p class="namesection">
<b class="names">tdom::schema - </b><br>Create a schema validation command</p>

  <h2><a name="SECTid0x555cbefb0160">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="SECTid0x555cbefaa5d0">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">delete</b></dt>
        <dd>This method deletes the validation command.</dd>
      

      







        <dt><b class="method">state</b></dt>
        <dd>This method returns the state of the validation command
        with respect to validation state. The possible return values
        and their meanings are:
        <dl>
          <dt>READY</dt><dd>The validation command is ready to start
          validation</dd>
          <dt>VALIDATING</dt><dd>The validation command is in the
          process of validating input.</dd>
          <dt>FINISHED</dt><dd>The validation has finished, no futher
          events are expected.</dd>
        </dl>
        </dd>







      
      
      
        <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="SECTid0x555cbf00a680">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">
................................................................................
        With <i class="m">constraint script</i> or with a given text type
        argument a text matching this script or the text type is
        expected. </dd>
      

      
        <dt>
<b class="method">any</b> <i class="m">?quant?</i>
</dt>
        <dd>The any command matches every element (with whatever

        attributes) or subtree, no matter if known within the schema

        or not. Please notice, that this mean the quantifier * and +
        will eat up any elements until the enclosing element
        ends.</dd>


      

      
        <dt>
<b class="method">attribute</b> <i class="m">name</i> <i class="m">?quant?</i> <i class="m">(?&lt;constraint script&gt;|"type" typename?)</i>
</dt>
        <dd>The attribute command defines a attribute (in no
................................................................................
        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="SECTid0x555cbf0131a0">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 &gt;= 0 and n &lt; 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="SECTid0x555cbf015030">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">isint</b></dt>







        <dd></dd>
      

      
        <dt>
<b class="cmd">fixed</b> <i class="m">value</i>
</dt>
        <dd>The text constraint only matches if the text value is
................................................................................
      
        <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="SECTid0x555cbf01d520">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&gt;</i> <i class="m">&lt;constraint script&gt;</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&gt;</i>. Otherwise it
            matches.</dd>
        
    </dl>

  <h2><a name="SECTid0x555cbf01f330">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">
&lt;xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;

  &lt;xsd:annotation&gt;
    &lt;xsd:documentation xml:lang="en"&gt;
     Purchase order schema for Example.com.
................................................................................
    # Copyright 2000 Example.com. All rights reserved.

    element purchaseOrder {ref PurchaseOrderType}

    element comment {text}

    defpattern PurchaseOrderType {
        element shipTo {ref USAddress}
        element billTo {ref USAddress}
        element comment ?
        element items
        attribute orderDate
    }

    defpattern USAddress {
        element name ! {text}
        element street ! {text}
        element city ! {text}
        element state ! {text}
        element zip ! {text isNumber}
        attribute country ! {text {fixed "US"}}
    }

    defelement items {
        element item * {
            element product ! {text}
            element quntity ! {text {maxExcluse 100}}
            element USPrice ! {text isNumber}
            element comment
            element shipDate ? {text isDate}
            attribute partNum ! {text {pattern "\d{3}-[A-Z]{2}"}}
        }
    }
}
      
    </pre><p>The RELAX NG Tutorial
    (<a href="http://relaxng.org/tutorial-20011203.html">http://relaxng.org/tutorial-20011203.html</a>) starts with
described at     this example:</p><pre class="example">






|


|


|




|







 







>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>










|







 







|

|
>
|
>
|
|
<
>
>







 







|







 







|



>
|
>
>
>
>
>
>
>
|







 







|







 







|







 







|
|


|








|





|
|

|
|







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
...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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
203
204
205
206
207
208
209
210
211
212
...
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
...
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
422
423
424
425
426
427
428
429
430
431
432
433
434
...
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
...
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
<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">delete</b></dt>
        <dd>This method deletes the validation command.</dd>
      

      
          <dt>
<b class="method">info</b> <i class="m">?args?</i>
</dt>
          <dd>This method bundles methods to query the state of and
          details about the schema command.
          <dl class="optlist">
              
                  <dt><b>validationstate</b></dt>
                  <dd>This method returns the state of the validation command
                  with respect to validation state. The possible return values
                  and their meanings are:
                  <dl>
                      <dt>READY</dt><dd>The validation command is ready to start
                      validation</dd>
                      <dt>VALIDATING</dt><dd>The validation command is in the
                      process of validating input.</dd>
                      <dt>FINISHED</dt><dd>The validation has finished, no futher
                      events are expected.</dd>
                  </dl>
                  </dd>
              
              
                  <dt><b>vstate</b></dt>
                  <dd>This method is a shorter alias for validationstate; see there.</dd>
              
          </dl>
          </dd>
      
      
      
        <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">
................................................................................
        With <i class="m">constraint script</i> or with a given text type
        argument a text matching this script or the text type is
        expected. </dd>
      

      
        <dt>
<b class="method">any</b> <i class="m">?namespace?</i> <i class="m">?quant?</i>
</dt>
        <dd>The any command matches every element (in the namespace
        <i class="m">namespace</i>, if that is given) (with whatever attributes)
        or subtree, no matter if known within the schema or not.
        Please notice, that in case of no <i class="m">namespace</i> argument is
        given this mean the quantifier * and + will eat up any
        elements until the enclosing element ends. If you really have

        a namespace that looks like a valid tDOM schema quantifier
        you'll have to spell out always all two arguments.</dd>
      

      
        <dt>
<b class="method">attribute</b> <i class="m">name</i> <i class="m">?quant?</i> <i class="m">(?&lt;constraint script&gt;|"type" typename?)</i>
</dt>
        <dd>The attribute command defines a attribute (in no
................................................................................
        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 &gt;= 0 and n &lt; 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
        parsed as an integer. If the optional argument to the command
        is <i class="m">tcl</i> everthing that returns TCL_OK if feeded into
        Tcl_GetInt() matches. If the optional argument to the command
        is <i class="m">xsd</i> then the constraint match if the value is a
        valid xsd:integer. Without argument <i class="m">xsd</i> is the
        default.</dd>
      

      
        <dt>
<b class="cmd">fixed</b> <i class="m">value</i>
</dt>
        <dd>The text constraint only matches if the text value is
................................................................................
      
        <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&gt;</i> <i class="m">&lt;constraint script&gt;</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&gt;</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">
&lt;xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;

  &lt;xsd:annotation&gt;
    &lt;xsd:documentation xml:lang="en"&gt;
     Purchase order schema for Example.com.
................................................................................
    # Copyright 2000 Example.com. All rights reserved.

    element purchaseOrder {ref PurchaseOrderType}

    element comment {text}

    defpattern PurchaseOrderType {
        element shipTo ! {ref USAddress}
        element billTo ! {ref USAddress}
        element comment ?
        element items
        attribute orderDate isodate
    }

    defpattern USAddress {
        element name ! {text}
        element street ! {text}
        element city ! {text}
        element state ! {text}
        element zip ! {text isNumber}
        attribute country ! {fixed "US"}
    }

    defelement items {
        element item * {
            element product ! {text}
            element quantity ! {text {maxExcluse 100}}
            element USPrice ! {text integer}
            element comment
            element shipDate ? {text isodate}
            attribute partNum ! {pattern "\d{3}-[A-Z]{2}"}
        }
    }
}
      
    </pre><p>The RELAX NG Tutorial
    (<a href="http://relaxng.org/tutorial-20011203.html">http://relaxng.org/tutorial-20011203.html</a>) starts with
described at     this example:</p><pre class="example">

Changes to doc/schema.n.

269
270
271
272
273
274
275
276




277
278
279
280
281
282
283
284
...
287
288
289
290
291
292
293



294
295
296
297
298
299
300
...
341
342
343
344
345
346
347
348
349

350

351
352
353


354
355
356
357
358
359
360
...
434
435
436
437
438
439
440
441
442






443
444
445
446
447
448
449
...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
name is set to a validation error message. If the dom tree is
valid and the optional \fIobjVar\fR argument is given, then
the variable with that name is set to the empty string.
.TP
\&\fB\fBdelete\fP
\&\fRThis method deletes the validation command.
.TP
\&\fB\fBstate\fP




\&\fRThis method returns the state of the validation command
with respect to validation state. The possible return values
and their meanings are:
.RS
.TP
READY
The validation command is ready to start
validation
................................................................................
The validation command is in the
process of validating input.
.TP
FINISHED
The validation has finished, no futher
events are expected.
.RE



.TP
\&\fB\fBreset\fP
\&\fRThis method resets the validation command into state
READY (while preserving the defined grammer).
.SH "Schema definition scripts"
.PP
Schema definition scripts are ordinary Tcl scripts that are
................................................................................
\&\fB\fBtext\fP \fI?<constraint script>|\*(lqtype\*(lq typename?\fB
\&\fRWithout the optional constraint script this validation
constraint matches every string (including the empty one).
With \fIconstraint script\fR or with a given text type
argument a text matching this script or the text type is
expected.
.TP
\&\fB\fBany\fP \fI?quant?\fB
\&\fRThe any command matches every element (with whatever

attributes) or subtree, no matter if known within the schema

or not. Please notice, that this mean the quantifier * and +
will eat up any elements until the enclosing element
ends.


.TP
\&\fB\fBattribute\fP \fIname\fB \fI?quant?\fB \fI(?<constraint script>|\*(lqtype\*(lq typename?)\fB
\&\fRThe attribute command defines a attribute (in no
namespace) to the enclosing element. The first definition of
\&\fIname\fR inside an element definition wins; later
definitions of the same name are silently ignored. After the
\&\fIname\fR argument there may be one of the qunatifieres ? or
................................................................................
.PP
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.
.PP
The text constraint commands are:
.TP
\&\fB\fBisint\fP
\&\fR






.TP
\&\fB\fBfixed\fP \fIvalue\fB
\&\fRThe text constraint only matches if the text value is
string equal to the given value.
.TP
\&\fB\fBtcl\fP \fItclcmd\fB \fI?arg arg ...?\fB
\&\fREvaluates the tcl script \fItclcmd arg arg ... \fR and
................................................................................
    # Copyright 2000 Example.com. All rights reserved.

    element purchaseOrder {ref PurchaseOrderType}

    element comment {text}

    defpattern PurchaseOrderType {
        element shipTo {ref USAddress}
        element billTo {ref USAddress}
        element comment ?
        element items
        attribute orderDate
    }

    defpattern USAddress {
        element name ! {text}
        element street ! {text}
        element city ! {text}
        element state ! {text}
        element zip ! {text isNumber}
        attribute country ! {text {fixed "US"}}
    }

    defelement items {
        element item * {
            element product ! {text}
            element quntity ! {text {maxExcluse 100}}
            element USPrice ! {text isNumber}
            element comment
            element shipDate ? {text isDate}
            attribute partNum ! {text {pattern "\ed{3}-[A-Z]{2}"}}
        }
    }
}
      
    
.CE
.PP







|
>
>
>
>
|







 







>
>
>







 







|
|
>
|
>
|
|
<
>
>







 







|
|
>
>
>
>
>
>







 







|
|


|








|





|
|

|
|







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
...
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
...
348
349
350
351
352
353
354
355
356
357
358
359
360
361

362
363
364
365
366
367
368
369
370
...
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
name is set to a validation error message. If the dom tree is
valid and the optional \fIobjVar\fR argument is given, then
the variable with that name is set to the empty string.
.TP
\&\fB\fBdelete\fP
\&\fRThis method deletes the validation command.
.TP
\&\fB\fBinfo\fP \fI?args?\fB
\&\fRThis method bundles methods to query the state of and
details about the schema command.
.RS
.IP "\fBvalidationstate\fR"
This method returns the state of the validation command
with respect to validation state. The possible return values
and their meanings are:
.RS
.TP
READY
The validation command is ready to start
validation
................................................................................
The validation command is in the
process of validating input.
.TP
FINISHED
The validation has finished, no futher
events are expected.
.RE
.IP "\fBvstate\fR"
This method is a shorter alias for validationstate; see there.
.RE
.TP
\&\fB\fBreset\fP
\&\fRThis method resets the validation command into state
READY (while preserving the defined grammer).
.SH "Schema definition scripts"
.PP
Schema definition scripts are ordinary Tcl scripts that are
................................................................................
\&\fB\fBtext\fP \fI?<constraint script>|\*(lqtype\*(lq typename?\fB
\&\fRWithout the optional constraint script this validation
constraint matches every string (including the empty one).
With \fIconstraint script\fR or with a given text type
argument a text matching this script or the text type is
expected.
.TP
\&\fB\fBany\fP \fI?namespace?\fB \fI?quant?\fB
\&\fRThe any command matches every element (in the namespace
\&\fInamespace\fR, if that is given) (with whatever attributes)
or subtree, no matter if known within the schema or not.
Please notice, that in case of no \fInamespace\fR argument is
given this mean the quantifier * and + will eat up any
elements until the enclosing element ends. If you really have

a namespace that looks like a valid tDOM schema quantifier
you'll have to spell out always all two arguments.
.TP
\&\fB\fBattribute\fP \fIname\fB \fI?quant?\fB \fI(?<constraint script>|\*(lqtype\*(lq typename?)\fB
\&\fRThe attribute command defines a attribute (in no
namespace) to the enclosing element. The first definition of
\&\fIname\fR inside an element definition wins; later
definitions of the same name are silently ignored. After the
\&\fIname\fR argument there may be one of the qunatifieres ? or
................................................................................
.PP
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.
.PP
The text constraint commands are:
.TP
\&\fB\fBinteger\fP \fI?(xsd|tcl)?\fB
\&\fRThis text constraint match if the text value could be
parsed as an integer. If the optional argument to the command
is \fItcl\fR everthing that returns TCL_OK if feeded into
Tcl_GetInt() matches. If the optional argument to the command
is \fIxsd\fR then the constraint match if the value is a
valid xsd:integer. Without argument \fIxsd\fR is the
default.
.TP
\&\fB\fBfixed\fP \fIvalue\fB
\&\fRThe text constraint only matches if the text value is
string equal to the given value.
.TP
\&\fB\fBtcl\fP \fItclcmd\fB \fI?arg arg ...?\fB
\&\fREvaluates the tcl script \fItclcmd arg arg ... \fR and
................................................................................
    # Copyright 2000 Example.com. All rights reserved.

    element purchaseOrder {ref PurchaseOrderType}

    element comment {text}

    defpattern PurchaseOrderType {
        element shipTo ! {ref USAddress}
        element billTo ! {ref USAddress}
        element comment ?
        element items
        attribute orderDate isodate
    }

    defpattern USAddress {
        element name ! {text}
        element street ! {text}
        element city ! {text}
        element state ! {text}
        element zip ! {text isNumber}
        attribute country ! {fixed "US"}
    }

    defelement items {
        element item * {
            element product ! {text}
            element quantity ! {text {maxExcluse 100}}
            element USPrice ! {text integer}
            element comment
            element shipDate ? {text isodate}
            attribute partNum ! {pattern "\ed{3}-[A-Z]{2}"}
        }
    }
}
      
    
.CE
.PP

Changes to doc/schema.xml.

147
148
149
150
151
152
153
154





155
156
157
158
159
160
161
162
163
164
165
166







167
168
169
170
171
172
173
...
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
      
      <commanddef>
        <command><method>delete</method></command>
        <desc>This method deletes the validation command.</desc>
      </commanddef>

      <commanddef>
        <command><method>state</method></command>





        <desc>This method returns the state of the validation command
        with respect to validation state. The possible return values
        and their meanings are:
        <dl>
          <dt>READY</dt><dd>The validation command is ready to start
          validation</dd>
          <dt>VALIDATING</dt><dd>The validation command is in the
          process of validating input.</dd>
          <dt>FINISHED</dt><dd>The validation has finished, no futher
          events are expected.</dd>
        </dl>
        </desc>







      </commanddef>
      
      <commanddef>
        <command><method>reset</method></command>
        <desc>This method resets the validation command into state
        READY (while preserving the defined grammer).</desc>
      </commanddef>
................................................................................
    have to be of a certain kind, must comply to some rules etc to be
    valid.</p>

    <p>The text constraint commands are:</p>

    <commandlist>
      <commanddef>
        <command><cmd>integer</cmd> <m>?(xsd|tcl)?</command>
        <desc>This text constraint match if the text value could be
        parsed as an integer. If the optional argument to the command
        is <m>tcl</m> everthing that returns TCL_OK if feeded into
        Tcl_GetInt() matches. If the optional argument to the command
        is <m>xsd</m> then the constraint match if the value is a
        valid xsd:integer. Without argument <m>xsd</m> is the
        default.</desc>







|
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>







 







|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
...
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
      
      <commanddef>
        <command><method>delete</method></command>
        <desc>This method deletes the validation command.</desc>
      </commanddef>

      <commanddef>
          <command><method>info</method> <m>?args?</m></command>
          <desc>This method bundles methods to query the state of and
          details about the schema command.
          <optlist>
              <optdef>
                  <optname>validationstate</optname>
                  <desc>This method returns the state of the validation command
                  with respect to validation state. The possible return values
                  and their meanings are:
                  <dl>
                      <dt>READY</dt><dd>The validation command is ready to start
                      validation</dd>
                      <dt>VALIDATING</dt><dd>The validation command is in the
                      process of validating input.</dd>
                      <dt>FINISHED</dt><dd>The validation has finished, no futher
                      events are expected.</dd>
                  </dl>
                  </desc>
              </optdef>
              <optdef>
                  <optname>vstate</optname>
                  <desc>This method is a shorter alias for validationstate; see there.</desc>
              </optdef>
          </optlist>
          </desc>
      </commanddef>
      
      <commanddef>
        <command><method>reset</method></command>
        <desc>This method resets the validation command into state
        READY (while preserving the defined grammer).</desc>
      </commanddef>
................................................................................
    have to be of a certain kind, must comply to some rules etc to be
    valid.</p>

    <p>The text constraint commands are:</p>

    <commandlist>
      <commanddef>
        <command><cmd>integer</cmd> <m>?(xsd|tcl)?</m></command>
        <desc>This text constraint match if the text value could be
        parsed as an integer. If the optional argument to the command
        is <m>tcl</m> everthing that returns TCL_OK if feeded into
        Tcl_GetInt() matches. If the optional argument to the command
        is <m>xsd</m> then the constraint match if the value is a
        valid xsd:integer. Without argument <m>xsd</m> is the
        default.</desc>

Changes to generic/schema.c.

2656
2657
2658
2659
2660
2661
2662
2663

2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
....
2682
2683
2684
2685
2686
2687
2688


















2689
2690
2691
2692
2693
2694
2695
....
2726
2727
2728
2729
2730
2731
2732














2733
2734
2735
2736
2737
2738
2739
....
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
....
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
....
5399
5400
5401
5402
5403
5404
5405



5406
5407
5408
5409
5410
5411
5412
    Tcl_HashEntry *h;
    Tcl_HashSearch search;
    SchemaCP *cp;
    SchemaValidationStack *se;
    Tcl_Obj *resultObj, *elmObj;
    
    static const char *schemaInstanceInfoMethods[] = {
        "defelements", "stack", NULL

    };
    enum schemaInstanceInfoMethod {
        m_defelements, m_stack
    };

    static const char *schemaInstanceInfoStackMethods[] = {
        "top", "inside", NULL
    };
    enum schemaInstanceInfoStackMethod {
        m_top, m_inside
................................................................................
                             "method", 0, &methodIndex)
        != TCL_OK) {
        return TCL_ERROR;
    }
    
    Tcl_ResetResult (interp);
    switch ((enum schemaInstanceInfoMethod) methodIndex) {


















    case m_defelements:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 1, objv, "defelements");
            return TCL_ERROR;
        }
        resultObj = Tcl_GetObjResult (interp);
        for (h = Tcl_FirstHashEntry (&sdata->element, &search);
................................................................................
            }
            serializeElementName (elmObj, se->pattern);
            Tcl_SetObjResult (interp, elmObj);
            return TCL_OK;
            break;
        }
        














    }
    
    return TCL_OK;
}

int
schemaInstanceCmd (
................................................................................
    SchemaCP      *pattern, *current = NULL;
    void          *namespacePtr, *savedNamespacePtr;
    char          *xmlstr, *errMsg;
    domDocument   *doc;
    domNode       *node;

    static const char *schemaInstanceMethods[] = {
        "defelement", "defpattern",  "start",   "event", "delete",
        "nrForwardDefinitions",      "state",   "reset", "define",
        "validate",   "domvalidate", "deftext", "info",  "reportcmd",
        "prefixns",   NULL
    };
    enum schemaInstanceMethod {
        m_defelement,  m_defpattern,  m_start,   m_event, m_delete,
        m_nrForwardDefinitions,       m_state,   m_reset, m_define,
        m_validate,    m_domvalidate, m_deftext, m_info,  m_reportcmd,
        m_prefixns
    };

    static const char *eventKeywords[] = {
        "start", "end", "text", NULL
    };

    enum eventKeyword
................................................................................

    case m_nrForwardDefinitions:
        if (objc != 2) {
            Tcl_WrongNumArgs(interp, 2, objv, "");
            return TCL_ERROR;
        }
        SetIntResult(sdata->forwardPatternDefs);
        break;

    case m_state:
        switch (sdata->validationState) {
        case VALIDATION_READY:
            SetResult ("READY");
            break;
        case VALIDATION_STARTED:
            SetResult ("VALIDATING");
            break;
        case VALIDATION_FINISHED:
            SetResult ("FINISHED");
            break;
        default:
            SetResult ("Internal error: Invalid validation state");
            return TCL_ERROR;
        }
        break;

    case m_reset:
        CHECK_EVAL
        schemaReset (sdata);
        break;

................................................................................
}

void
tDOM_SchemaInit (
    Tcl_Interp *interp
    )
{



    /* Inline definition commands. */
    Tcl_CreateObjCommand (interp, "tdom::schema::defelement",
                          schemaInstanceCmd, NULL, NULL);
    Tcl_CreateObjCommand (interp, "tdom::schema::defpattern",
                          schemaInstanceCmd, NULL, NULL);
    Tcl_CreateObjCommand (interp, "tdom::schema::deftext",
                          schemaInstanceCmd, NULL, NULL);







|
>


|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
|


|
|
|
<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>
>







2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
....
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
....
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
....
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801

2802
2803
2804
2805
2806
2807
2808
....
3069
3070
3071
3072
3073
3074
3075

















3076
3077
3078
3079
3080
3081
3082
....
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
    Tcl_HashEntry *h;
    Tcl_HashSearch search;
    SchemaCP *cp;
    SchemaValidationStack *se;
    Tcl_Obj *resultObj, *elmObj;
    
    static const char *schemaInstanceInfoMethods[] = {
        "validationstate", "vstate", "defelements", "stack", "toplevel",
        NULL
    };
    enum schemaInstanceInfoMethod {
        m_validationstate, m_vstate, m_defelements, m_stack, m_toplevel
    };

    static const char *schemaInstanceInfoStackMethods[] = {
        "top", "inside", NULL
    };
    enum schemaInstanceInfoStackMethod {
        m_top, m_inside
................................................................................
                             "method", 0, &methodIndex)
        != TCL_OK) {
        return TCL_ERROR;
    }
    
    Tcl_ResetResult (interp);
    switch ((enum schemaInstanceInfoMethod) methodIndex) {
    case m_validationstate:
    case m_vstate:
        switch (sdata->validationState) {
        case VALIDATION_READY:
            SetResult ("READY");
            break;
        case VALIDATION_STARTED:
            SetResult ("VALIDATING");
            break;
        case VALIDATION_FINISHED:
            SetResult ("FINISHED");
            break;
        default:
            SetResult ("Internal error: Invalid validation state");
            return TCL_ERROR;
        }
        break;
        
    case m_defelements:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 1, objv, "defelements");
            return TCL_ERROR;
        }
        resultObj = Tcl_GetObjResult (interp);
        for (h = Tcl_FirstHashEntry (&sdata->element, &search);
................................................................................
            }
            serializeElementName (elmObj, se->pattern);
            Tcl_SetObjResult (interp, elmObj);
            return TCL_OK;
            break;
        }
        
    case m_toplevel:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 1, objv, "no argument expected");
            return TCL_ERROR;
        }
        if (!sdata->currentEvals) {
            SetResult ("not called while schema evaluation");
            return TCL_ERROR;
        }
        if (!sdata->defineToplevel && sdata->currentEvals > 1) {
            SetBooleanResult (0);
        } else {
            SetBooleanResult (1);
        }
    }
    
    return TCL_OK;
}

int
schemaInstanceCmd (
................................................................................
    SchemaCP      *pattern, *current = NULL;
    void          *namespacePtr, *savedNamespacePtr;
    char          *xmlstr, *errMsg;
    domDocument   *doc;
    domNode       *node;

    static const char *schemaInstanceMethods[] = {
        "defelement",  "defpattern",  "start", "event",     "delete",
        "nrForwardDefinitions",       "reset", "define",    "validate",
        "domvalidate", "deftext",     "info",  "reportcmd", "prefixns",
        NULL
    };
    enum schemaInstanceMethod {
        m_defelement,  m_defpattern, m_start, m_event,     m_delete,
        m_nrForwardDefinitions,      m_reset, m_define,    m_validate,
        m_domvalidate, m_deftext,    m_info,  m_reportcmd, m_prefixns

    };

    static const char *eventKeywords[] = {
        "start", "end", "text", NULL
    };

    enum eventKeyword
................................................................................

    case m_nrForwardDefinitions:
        if (objc != 2) {
            Tcl_WrongNumArgs(interp, 2, objv, "");
            return TCL_ERROR;
        }
        SetIntResult(sdata->forwardPatternDefs);

















        break;

    case m_reset:
        CHECK_EVAL
        schemaReset (sdata);
        break;

................................................................................
}

void
tDOM_SchemaInit (
    Tcl_Interp *interp
    )
{
    Tcl_CreateObjCommand (interp, "tdom::schema", tDOM_SchemaObjCmd,
                          NULL, NULL);

    /* Inline definition commands. */
    Tcl_CreateObjCommand (interp, "tdom::schema::defelement",
                          schemaInstanceCmd, NULL, NULL);
    Tcl_CreateObjCommand (interp, "tdom::schema::defpattern",
                          schemaInstanceCmd, NULL, NULL);
    Tcl_CreateObjCommand (interp, "tdom::schema::deftext",
                          schemaInstanceCmd, NULL, NULL);

Changes to generic/tdominit.c.

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#endif

#ifndef TDOM_NO_PULL
    Tcl_CreateObjCommand(interp, "tdom::pullparser", tDOM_PullParserCmd, NULL, NULL );    
#endif

#ifndef TDOM_NO_SCHEMA
    Tcl_CreateObjCommand (interp, "tdom::schema", tDOM_SchemaObjCmd,
                          NULL, NULL);
    tDOM_SchemaInit (interp);
#endif
    
#ifdef USE_TCL_STUBS
    Tcl_PkgProvideEx(interp, PACKAGE_NAME, PACKAGE_VERSION, 
                     (ClientData) &tdomStubs);
#else







<
<







94
95
96
97
98
99
100


101
102
103
104
105
106
107
#endif

#ifndef TDOM_NO_PULL
    Tcl_CreateObjCommand(interp, "tdom::pullparser", tDOM_PullParserCmd, NULL, NULL );    
#endif

#ifndef TDOM_NO_SCHEMA


    tDOM_SchemaInit (interp);
#endif
    
#ifdef USE_TCL_STUBS
    Tcl_PkgProvideEx(interp, PACKAGE_NAME, PACKAGE_VERSION, 
                     (ClientData) &tdomStubs);
#else

Changes to tests/schema.test.

13
14
15
16
17
18
19




20
21
22
23
24
25
26
...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
#    schema-10.*: Any
#    schema-11.*: attribute, nsattribute
#    schema-12.*: schemaCmd domvalidate
#    schema-13.*: XML namespaces
#    schema-14.*: text
#    schema-15.*: Constraint cmd tcl
#    schema-16.*: interleave




#
# Copyright (c) 2018 Rolf Ade.

source [file join [file dir [info script]] loadtdom.tcl]

if {[dom featureinfo schema]} {

................................................................................
    }
    foreach e {e1 e2} {
        grammar defelement $e {}
    }
    pullValidate grammar {
        <doc><e1/></doc>
    }
    if {[grammar state] ne "FINISHED"} {
        error "Wrong state."
    }
    grammar reset
    pullValidate grammar {
        <doc><e1/><e2/></doc>
    }
    if {[grammar state] ne "FINISHED"} {
        error "Wrong state."
    }
    grammar reset
    pullValidate grammar {
        <doc><e1/><e2/><e2/><e2/></doc>
    }
    if {[grammar state] ne "FINISHED"} {
        error "Wrong state."
    }
    grammar delete
} {}

test schema-4.1a {validation} {
    tdom::schema create s







>
>
>
>







 







|






|






|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
...
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
#    schema-10.*: Any
#    schema-11.*: attribute, nsattribute
#    schema-12.*: schemaCmd domvalidate
#    schema-13.*: XML namespaces
#    schema-14.*: text
#    schema-15.*: Constraint cmd tcl
#    schema-16.*: interleave
#    schema-17.*: info
#    schema-18.*: reportcmd
#    schema-19.*: keyspace
#    schema-20.*: domunique
#
# Copyright (c) 2018 Rolf Ade.

source [file join [file dir [info script]] loadtdom.tcl]

if {[dom featureinfo schema]} {

................................................................................
    }
    foreach e {e1 e2} {
        grammar defelement $e {}
    }
    pullValidate grammar {
        <doc><e1/></doc>
    }
    if {[grammar info vstate] ne "FINISHED"} {
        error "Wrong state."
    }
    grammar reset
    pullValidate grammar {
        <doc><e1/><e2/></doc>
    }
    if {[grammar info validationstate] ne "FINISHED"} {
        error "Wrong state."
    }
    grammar reset
    pullValidate grammar {
        <doc><e1/><e2/><e2/><e2/></doc>
    }
    if {[grammar info vstate] ne "FINISHED"} {
        error "Wrong state."
    }
    grammar delete
} {}

test schema-4.1a {validation} {
    tdom::schema create s