tDOM

Check-in [728f51431a]
Login

Check-in [728f51431a]

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

Overview
Comment:Enhanced the any content command to optionally match only any element in a given namespace.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | schema
Files: files | file ages | folders
SHA3-256: 728f51431a4eee5e2c2269ccd1de811bc8fe760e09a80e6facb81f5f4a3c0c62
User & Date: rolf 2019-06-15 01:04:48.891
Context
2019-06-17
09:43
Made the lately added new Schema_CP_Type types known to the debuging machinery. check-in: 8e9437ea75 user: rolf tags: schema
2019-06-15
01:04
Enhanced the any content command to optionally match only any element in a given namespace. check-in: 728f51431a user: rolf tags: schema
2019-06-08
14:36
Work on validation error reporting. check-in: 634d7e6d48 user: rolf tags: schema
Changes
Unified Diff Ignore Whitespace Patch
Changes to doc/schema.xml.
238
239
240
241
242
243
244
245
246

247

248
249

250
251
252
253
254
255
256
257
        constraint matches every string (including the empty one).
        With <m>constraint script</m> or with a given text type
        argument a text matching this script or the text type is
        expected. </desc>
      </commanddef>

      <commanddef>
        <command><method>any</method> <m>?quant?</m></command>
        <desc>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.</desc>
      </commanddef>

      <commanddef>
        <command><method>attribute</method> <m>name</m> <m>?quant?</m> <m>(?&lt;constraint script>|"type" typename?)</m></command>
        <desc>The attribute command defines a attribute (in no
        namespace) to the enclosing element. The first definition of
        <m>name</m> inside an element definition wins; later







|
|
>
|
>
|
|
>
|







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
        constraint matches every string (including the empty one).
        With <m>constraint script</m> or with a given text type
        argument a text matching this script or the text type is
        expected. </desc>
      </commanddef>

      <commanddef>
        <command><method>any</method> <m>?namespace?</m> <m>?quant?</m></command>
        <desc>The any command matches every element (in the namespace
        <m>namespace</m>, 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 <m>namespace</m> 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.</desc>
      </commanddef>

      <commanddef>
        <command><method>attribute</method> <m>name</m> <m>?quant?</m> <m>(?&lt;constraint script>|"type" typename?)</m></command>
        <desc>The attribute command defines a attribute (in no
        namespace) to the enclosing element. The first definition of
        <m>name</m> inside an element definition wins; later
Changes to generic/schema.c.
298
299
300
301
302
303
304
305


306
307
308
309
310
311
312
313
        /* content/quant will be allocated, if the cp in fact has
         * constraints */
        break;
    case SCHEMA_CTYPE_KEYSPACE_END:
    case SCHEMA_CTYPE_KEYSPACE:
        pattern->name = name;
        break;
    case SCHEMA_CTYPE_VIRTUAL:


    case SCHEMA_CTYPE_ANY:
        /* Do nothing */
        break;
    }
    return pattern;
}

DDBG(







|
>
>
|







298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
        /* content/quant will be allocated, if the cp in fact has
         * constraints */
        break;
    case SCHEMA_CTYPE_KEYSPACE_END:
    case SCHEMA_CTYPE_KEYSPACE:
        pattern->name = name;
        break;
    case SCHEMA_CTYPE_ANY:
        pattern->namespace = namespace;
        break;
    case SCHEMA_CTYPE_VIRTUAL:
        /* Do nothing */
        break;
    }
    return pattern;
}

DDBG(
337
338
339
340
341
342
343





344
345
346
347
348
349
350
        }
        /* Fall thru. */
    case SCHEMA_CTYPE_CHOICE:
    case SCHEMA_CTYPE_INTERLEAVE:
        fprintf (stderr, "\t%d childs\n", pattern->nc);
        break;
    case SCHEMA_CTYPE_ANY:





    case SCHEMA_CTYPE_TEXT:
    case SCHEMA_CTYPE_VIRTUAL:
        /* Do nothing */
        break;
    }
}








>
>
>
>
>







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
        }
        /* Fall thru. */
    case SCHEMA_CTYPE_CHOICE:
    case SCHEMA_CTYPE_INTERLEAVE:
        fprintf (stderr, "\t%d childs\n", pattern->nc);
        break;
    case SCHEMA_CTYPE_ANY:
        if (pattern->namespace) {
            fprintf (stderr, "\tNamespace: '%s'\n",
                     pattern->namespace);
        }
        break;
    case SCHEMA_CTYPE_TEXT:
    case SCHEMA_CTYPE_VIRTUAL:
        /* Do nothing */
        break;
    }
}

888
889
890
891
892
893
894




895
896
897
898
899
900
901
                        }                        
                        return 0;
                    }
                }
                break;

            case SCHEMA_CTYPE_ANY:




                updateStack (se, cp, ac);
                sdata->skipDeep = 1;
                return 1;

            case SCHEMA_CTYPE_NAME:
                DBG(fprintf (stderr, "name: %s ns: %s candidate name: %s "
                             "candidate ns: %s\n", name, namespace,







>
>
>
>







895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
                        }                        
                        return 0;
                    }
                }
                break;

            case SCHEMA_CTYPE_ANY:
                if (candidate->namespace &&
                    candidate->namespace != namespace) {
                    break;
                }
                updateStack (se, cp, ac);
                sdata->skipDeep = 1;
                return 1;

            case SCHEMA_CTYPE_NAME:
                DBG(fprintf (stderr, "name: %s ns: %s candidate name: %s "
                             "candidate ns: %s\n", name, namespace,
912
913
914
915
916
917
918
919


920

921
922
923
924
925
926
927
                for (i = 0; i < candidate->nc; i++) {
                    icp = candidate->content[i];
                    switch (icp->type) {
                    case SCHEMA_CTYPE_TEXT:
                        break;

                    case SCHEMA_CTYPE_ANY:
                        sdata->skipDeep = 1;


                        updateStack (se, cp, ac);

                        return 1;

                    case SCHEMA_CTYPE_NAME:
                        if (icp->name == name
                            && icp->namespace == namespace) {
                            pushToStack (sdata, icp);
                            updateStack (se, cp, ac);







|
>
>

>







923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
                for (i = 0; i < candidate->nc; i++) {
                    icp = candidate->content[i];
                    switch (icp->type) {
                    case SCHEMA_CTYPE_TEXT:
                        break;

                    case SCHEMA_CTYPE_ANY:
                        if (icp->namespace && icp->namespace != namespace) {
                            break;
                        }
                        updateStack (se, cp, ac);
                        sdata->skipDeep = 1;
                        return 1;

                    case SCHEMA_CTYPE_NAME:
                        if (icp->name == name
                            && icp->namespace == namespace) {
                            pushToStack (sdata, icp);
                            updateStack (se, cp, ac);
1053
1054
1055
1056
1057
1058
1059



1060
1061
1062
1063
1064
1065
1066
                    if (!checkText (interp, icp, "")) {
                        mayskip = 0;
                    }
                }
                break;

            case SCHEMA_CTYPE_ANY:



                sdata->skipDeep = 1;
                if (mayskip && minOne (cp->quants[i])) mayskip = 0;
                se->hasMatched = 1;
                se->interleaveState[i] = 1;
                return 1;

            case SCHEMA_CTYPE_NAME:







>
>
>







1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
                    if (!checkText (interp, icp, "")) {
                        mayskip = 0;
                    }
                }
                break;

            case SCHEMA_CTYPE_ANY:
                if (icp->namespace && icp->namespace == namespace) {
                    break;
                }
                sdata->skipDeep = 1;
                if (mayskip && minOne (cp->quants[i])) mayskip = 0;
                se->hasMatched = 1;
                se->interleaveState[i] = 1;
                return 1;

            case SCHEMA_CTYPE_NAME:
3329
3330
3331
3332
3333
3334
3335

3336

3337
3338
3339
3340



3341
3342











3343
3344

3345
3346
3347
3348
3349
3350
3351
3352
    int objc,
    Tcl_Obj *const objv[]
    )
{
    SchemaData *sdata = GETASI;
    SchemaCP *pattern;
    SchemaQuant quant;

    int n, m;


    CHECK_SI
    CHECK_TOPLEVEL
    checkNrArgs (1,2,"?quant?");



    quant = getQuant (interp, sdata, objc == 1 ? NULL : objv[1], &n, &m);
    if (quant == SCHEMA_CQUANT_ERROR) {











        return TCL_ERROR;
    }

    pattern = initSchemaCP (SCHEMA_CTYPE_ANY, NULL, NULL);
    REMEMBER_PATTERN (pattern)
    addToContent(sdata, pattern, quant, n, m);
    return TCL_OK;
}

static int
evalDefinition (







>
|
>



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







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
    int objc,
    Tcl_Obj *const objv[]
    )
{
    SchemaData *sdata = GETASI;
    SchemaCP *pattern;
    SchemaQuant quant;
    char *ns = NULL;
    int n, m, hnew;
    Tcl_HashEntry *h;

    CHECK_SI
    CHECK_TOPLEVEL
    checkNrArgs (1,3,"?namespace? ?quant?");
    if (objc == 1) {
        quant = SCHEMA_CQUANT_ONE;
    } else if (objc == 2) {    
        quant = getQuant (interp, sdata, objv[1], &n, &m);
        if (quant == SCHEMA_CQUANT_ERROR) {
            h = Tcl_CreateHashEntry (&sdata->namespace,
                                     Tcl_GetString (objv[1]), &hnew);
            ns = Tcl_GetHashKey (&sdata->namespace, h);
            quant = SCHEMA_CQUANT_ONE;
        }
    } else {
        h = Tcl_CreateHashEntry (&sdata->namespace,
                                 Tcl_GetString (objv[1]), &hnew);
        ns = Tcl_GetHashKey (&sdata->namespace, h);
        quant = getQuant (interp, sdata, objv[2], &n, &m);
        if (quant == SCHEMA_CQUANT_ERROR) {
            return TCL_ERROR;
        }
    }
    pattern = initSchemaCP (SCHEMA_CTYPE_ANY, ns, NULL);
    REMEMBER_PATTERN (pattern)
    addToContent(sdata, pattern, quant, n, m);
    return TCL_OK;
}

static int
evalDefinition (
Changes to tests/schema.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Features covered: Schema validation
#
# Tested functionalities:
#    schema-1.*: Basics, interface
#    schema-2.*: Grammar definition ref
#    schema-3.*: Grammar definition choice
#    schema-4.*: Script level validation with event
#    schema-5.*: dom parse -validateCmd
#    schema-6.*: expat parser -validateCmd
#    schema-7.*: Validation checks.
#    schema-8.*: tdom::schema validate method
#    schema-9.*: Choice
#    scheam-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
#












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Features covered: Schema validation
#
# Tested functionalities:
#    schema-1.*: Basics, interface
#    schema-2.*: Grammar definition ref
#    schema-3.*: Grammar definition choice
#    schema-4.*: Script level validation with event
#    schema-5.*: dom parse -validateCmd
#    schema-6.*: expat parser -validateCmd
#    schema-7.*: Validation checks.
#    schema-8.*: tdom::schema validate method
#    schema-9.*: Choice
#    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
#
2196
2197
2198
2199
2200
2201
2202



























2203
2204
2205
2206
2207
2208
2209
        {<doc><a/><a><b>text</b><c><c><c/></c></c></a><b/></doc>}
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 1 0 0}




























test schema-11.1 {attribute} {
    tdom::schema create s
    s define {
        defelement doc {
            attribute attr1
            attribute attr2 ?







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







2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
        {<doc><a/><a><b>text</b><c><c><c/></c></c></a><b/></doc>}
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 1 0 0}

test schema-10.5 {any} {
    tdom::schema create s
    s define {
        defelement doc {
            element a
            any http://foo.bar 2
            element b
        }
        defelement a {}
        defelement b {}
    }
    set result [list]
    foreach xml {
        {<doc><a/><something/><b/></doc>}
        {<doc><a/><something/><something/><b/></doc>}
        {<doc><a/><b/></doc>}
        {<doc><a/><a><b>text</b><c><c><c/></c></c></a><b/></doc>}
        {<doc xmlns:ns="http://foo.bar"><a/><ns:a/><ns:b>some</ns:b><b/></doc>}
        {<doc xmlns:ns="http://foo.bar" xmlns:ns1="http://foo.bar"><a/><ns1:a/><ns:b>some</ns:b><b/></doc>}
        {<doc xmlns:ns="http://foo.bar" xmlns:ns1="http://foo.grill"><a/><ns1:a/><ns:b>some</ns:b><b/></doc>}
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 0 0 1 1 0}

test schema-11.1 {attribute} {
    tdom::schema create s
    s define {
        defelement doc {
            attribute attr1
            attribute attr2 ?