tDOM

Check-in [97b292828f]
Login
Bounty program for improvements to Tcl and certain Tcl packages.

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

Overview
Comment:Started work on subtree local unique/key/keyref.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | localkey
Files: files | file ages | folders
SHA3-256: 97b292828f5048f3b426347b0e22604aca284c5f815fcf48b9e9f4a71333b39e
User & Date: rolf 2019-05-04 12:35:27
Context
2019-05-07
22:52
Implementend restricted XPath expressions for local key selectors and fields. check-in: 918781e945 user: rolf tags: localkey
2019-05-04
12:35
Started work on subtree local unique/key/keyref. check-in: 97b292828f user: rolf tags: localkey
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 generic/dom.c.

647
648
649
650
651
652
653

654
655

656
657
658
659
660
661
662
663
        while (prefixMappings[i]) {
            if (strcmp (prefix, prefixMappings[i]) == 0) {
                return prefixMappings[i+1];
            }
            i += 2;
        }
    }

    ns = domLookupPrefix (node, prefix);
    if (ns) return ns->uri;

    else    return NULL;
}

/*---------------------------------------------------------------------------
|   domLookupPrefix
|
\--------------------------------------------------------------------------*/
domNS *






>
|
|
>
|







647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
        while (prefixMappings[i]) {
            if (strcmp (prefix, prefixMappings[i]) == 0) {
                return prefixMappings[i+1];
            }
            i += 2;
        }
    }
    if (node) {
        ns = domLookupPrefix (node, prefix);
        if (ns) return ns->uri;
    }
    return NULL;
}

/*---------------------------------------------------------------------------
|   domLookupPrefix
|
\--------------------------------------------------------------------------*/
domNS *

Changes to generic/schema.c.

21
22
23
24
25
26
27

28
29
30
31
32
33
34
....
3309
3310
3311
3312
3313
3314
3315












































































3316
3317
3318
3319
3320
3321
3322
....
4471
4472
4473
4474
4475
4476
4477
4478




4479
4480
4481
4482
4483
4484
4485
|
\---------------------------------------------------------------------------*/

#ifndef TDOM_NO_SCHEMA

#include <tdom.h>
#include <tcldom.h>

#include <schema.h>

/* #define DEBUG */
/* #define DDEBUG */
/*----------------------------------------------------------------------------
|   Debug Macros
|
................................................................................
        pattern->content[i-1] = (SchemaCP *) objv[i];
        Tcl_IncrRefCount (objv[i]);
    }
    pattern->nc = objc;
    addToContent (sdata, pattern, SCHEMA_CQUANT_ONE, 0, 0);
    return TCL_OK;
}













































































static int
integerImpl (
    Tcl_Interp *interp,
    void *constraintData,
    char *text
    )
................................................................................
                          NamespacePatternObjCmd, NULL, NULL);
    Tcl_CreateObjCommand (interp, "tdom::schema::text",
                          TextPatternObjCmd, NULL, NULL);

    /* The 'virtual' "tcl" definition command */
    Tcl_CreateObjCommand (interp, "tdom::schema::tcl",
                          VirtualPatternObjCmd, NULL, NULL);
    




    /* The text constraint commands */
    Tcl_CreateObjCommand (interp,"tdom::schema::text::integer",
                          integerTCObjCmd, NULL, NULL);
    Tcl_CreateObjCommand (interp, "tdom::schema::text::tcl",
                          tclTCObjCmd, NULL, NULL);
    Tcl_CreateObjCommand (interp, "tdom::schema::text::fixed",
                          fixedTCObjCmd, NULL, NULL);






>







 







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







 







|
>
>
>
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
....
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
....
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
|
\---------------------------------------------------------------------------*/

#ifndef TDOM_NO_SCHEMA

#include <tdom.h>
#include <tcldom.h>
#include <domxpath.h>
#include <schema.h>

/* #define DEBUG */
/* #define DDEBUG */
/*----------------------------------------------------------------------------
|   Debug Macros
|
................................................................................
        pattern->content[i-1] = (SchemaCP *) objv[i];
        Tcl_IncrRefCount (objv[i]);
    }
    pattern->nc = objc;
    addToContent (sdata, pattern, SCHEMA_CQUANT_ONE, 0, 0);
    return TCL_OK;
}

extern void printAst (int depth, ast t);
static int
processSchemaXPath (
    Tcl_Interp *interp,
    ast t,
    int field
    )
{
    while (t) {
        switch (t->type) {
        case IsElement:
        case IsFQElement:
        case IsNSElement:
        case EvalSteps:
        case CombineSets:
            /* Only on top level? */
        case AxisAttribute:
        case AxisChild:
        case AxisDescendant:
        case GetContextNode:
        case AxisSelf:
        case IsNSAttr:
        case IsAttr:
            break;
        default:
            SetResult ("Not a reduced XPath expression.");
            printAst (0, t);
            return TCL_ERROR;
        }
        if (!field && (t->type == IsAttr || t->type == IsNSAttr)) {
            SetResult ("Attribute selection is only possible in reduced "
                       "XPath expression for field selectors.");
            return TCL_ERROR;
        }
        if (t->child) {
            if (processSchemaXPath (interp, t->child, field) != TCL_OK) {
                return TCL_ERROR;
            }
        }
        t = t->next;
    }
    return TCL_OK;
    
}

static int
uniquePatternCmd (
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]
    )
{
    SchemaData *sdata = GETASI;
    ast s, f;
    char *errMsg = NULL;

    CHECK_SI
    CHECK_TOPLEVEL
    checkNrArgs (3,3,"Expected: <selector> <fieldlist>");

    if (xpathParse (Tcl_GetString (objv[1]), NULL, XPATH_EXPR,
                    NULL, NULL, &s, &errMsg) < 0) {
        SetResult3 ("Error in selector xpath: '", errMsg, "");
        FREE (errMsg);
        return TCL_ERROR;
    }
    if (processSchemaXPath (interp, s, 0) != TCL_OK) {
        xpathFreeAst (s);
        return TCL_ERROR;
    }
    printAst (0, s);
    
    return TCL_OK;
}

static int
integerImpl (
    Tcl_Interp *interp,
    void *constraintData,
    char *text
    )
................................................................................
                          NamespacePatternObjCmd, NULL, NULL);
    Tcl_CreateObjCommand (interp, "tdom::schema::text",
                          TextPatternObjCmd, NULL, NULL);

    /* The 'virtual' "tcl" definition command */
    Tcl_CreateObjCommand (interp, "tdom::schema::tcl",
                          VirtualPatternObjCmd, NULL, NULL);

    /* Identity definition commands */
    Tcl_CreateObjCommand (interp,"tdom::schema::unique",
                          uniquePatternCmd, NULL, NULL);

    /* The text constraint commands */
    Tcl_CreateObjCommand (interp,"tdom::schema::text::integer",
                          integerTCObjCmd, NULL, NULL);
    Tcl_CreateObjCommand (interp, "tdom::schema::text::tcl",
                          tclTCObjCmd, NULL, NULL);
    Tcl_CreateObjCommand (interp, "tdom::schema::text::fixed",
                          fixedTCObjCmd, NULL, NULL);

Changes to tests/schema.test.

4121
4122
4123
4124
4125
4126
4127







4128


4129













































proc postValidation {g xml} {
    set doc [dom parse $xml]
    set rc [$g domvalidate $doc errMsg]
    $doc delete
    return $rc
}











}



















































>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
proc postValidation {g xml} {
    set doc [dom parse $xml]
    set rc [$g domvalidate $doc errMsg]
    $doc delete
    return $rc
}

test schema-19.1 {unique} {
    tdom::schema s
    s define {
        defelement doc {
            element a *
            element b *
            unique a @ref
        }
        defelement a {
            attribute ref
        }
        defelement b {
            attribute ref ?
        }
    }
    set result [list]
    foreach xml {
        <doc/>
        <doc><b/></doc>
        <doc><a/></doc>
        {<doc><a ref="1"/><a ref="foo"/></doc>}
    } {
        lappend result [s validate $xml errMsg]
        puts $errMsg
    }
    s delete
    set result
} {1 1 0 1}


test schema-19.2 {unique} {
    set schema {
        defelement doc {
            unique {${::schema-19.2}} @ref
        }
    }
    set result [list]
    foreach selector {
        a
        ./../a
        /foo
        a/b
        {a | b}
        a|b
        .//a
    } {
        set ::schema-19.2 $selector
        tdom::schema s
        lappend result [catch {s define [subst $schema]} errMsg]
        puts $errMsg
        s delete
    }
    set result
} {0 1 1 0 0 0}

}