tDOM

Check-in [68cd47d57c]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

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

Overview
Comment:Added text constrain cmd base64.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | schema
Files: files | file ages | folders
SHA3-256: 68cd47d57ce993f6f86ecaa2abbfaee6186c3e4692c12e1672a5ab3e32bb2e2e
User & Date: rolf 2019-05-06 23:18:53
Context
2019-05-09
18:33
Merged from trunk. check-in: 05a6175f48 user: rolf tags: schema
2019-05-06
23:18
Added text constrain cmd base64. check-in: 68cd47d57c user: rolf tags: schema
2019-05-02
16:53
Added text constraint commands id and idref. check-in: a886296dc3 user: rolf tags: schema
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

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
...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
...
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
...
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
...
517
518
519
520
521
522
523





524
525
526
527
528
529
530
531
532
533
<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="#SECTid0x5588b7db8b30">NAME</a> · <a href="#SECTid0x5588b7db9160">SYNOPSIS</a> · <a href="#SECTid0x5588b7db35d0">DESCRIPTION </a> · <a href="#SECTid0x5588b7e11e10">Schema definition scripts</a> · <a href="#SECTid0x5588b7e1a140">Quantity specifier</a> · <a href="#SECTid0x5588b7e1bfd0">Text constraint scripts</a> · <a href="#SECTid0x5588b7e23fe0">Exampels</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid0x5588b7db8b30">NAME</a></h2><p class="namesection">
<b class="names">tdom::schema - </b><br>Create a schema validation command</p>

  <h2><a name="SECTid0x5588b7db9160">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="SECTid0x5588b7db35d0">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="SECTid0x5588b7e11e10">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="SECTid0x5588b7e1a140">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="SECTid0x5588b7e1bfd0">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>
................................................................................
      
        <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>
  
  <h2><a name="SECTid0x5588b7e23fe0">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.





|


|


|




|







 







|







 







|







 







|







 







>
>
>
>
>


|







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
...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
...
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
...
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
...
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
<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">
      
................................................................................
        <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">
................................................................................
        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
................................................................................
        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="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>
................................................................................
      
        <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">
&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.

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.

4419
4420
4421
4422
4423
4424
4425


























































4426
4427
4428
4429
4430
4431
4432
....
4511
4512
4513
4514
4515
4516
4517


4518
4519
4520
4521
    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. */
................................................................................
                          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 */






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







 







>
>




4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
....
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
    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. */
................................................................................
                          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 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