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

Overview
Comment:Fixes: Don't try to check attributes if in skip mode - it doesn't make sense to check attributes of an unknown element. Don't fumble with activeChild before calling out to virual matches. Report also element end as possible event (if that is possible, of course) for info expected.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wip
Files: files | file ages | folders
SHA3-256: 65eff1573f3f3a3504cdbb36eb59a4d4945e9d0d1e95fa4f5976d4b8d9015e24
User & Date: rolf 2019-11-04 17:47:20
Context
2019-11-04
18:08
Added simple recovery, with infrastructure to add more fancy recovery features without too much fall out. Added info expected, which returns the expected (possible) events, even in a validation error report handler. check-in: a16fad774f user: rolf tags: schema
17:47
Fixes: Don't try to check attributes if in skip mode - it doesn't make sense to check attributes of an unknown element. Don't fumble with activeChild before calling out to virual matches. Report also element end as possible event (if that is possible, of course) for info expected. Closed-Leaf check-in: 65eff1573f user: rolf tags: wip
00:24
Save work. check-in: d2f12cc8d4 user: rolf tags: wip
Changes

Changes to generic/schema.c.

1096
1097
1098
1099
1100
1101
1102

1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
....
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
....
2863
2864
2865
2866
2867
2868
2869

2870
2871
2872
2873
2874
2875
2876
2877
2878
2879

2880
2881
2882
2883
2884
2885
2886
....
3070
3071
3072
3073
3074
3075
3076














3077
3078
3079
3080
3081
3082
3083
....
3203
3204
3205
3206
3207
3208
3209

3210
3211
3212
3213

3214

3215





3216
3217
3218
3219
3220
3221
3222
....
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
static int
evalVirtual (
    Tcl_Interp *interp,
    SchemaData *sdata,
    int ac
    )
{

    SchemaCP *cp;
    int savedac, savedhm, rc;

    cp = sdata->stack->pattern->content[ac];
    savedac = sdata->stack->activeChild;
    savedhm = sdata->stack->hasMatched;
    sdata->stack->activeChild = ac;
    sdata->stack->hasMatched = 1;
    cp->content[cp->nc-1] = (SchemaCP *) sdata->self;
    sdata->currentEvals++;
    rc = Tcl_EvalObjv (interp, cp->nc, (Tcl_Obj **) cp->content,
                       TCL_EVAL_GLOBAL);
    sdata->currentEvals--;
    sdata->stack->activeChild = savedac;
    sdata->stack->hasMatched = savedhm;    
    if (rc != TCL_OK) {
        sdata->evalError = 1;
        return 0;
    }
    return 1;
}

................................................................................

    if (probeElement (vdata->interp, sdata, s, namespace)
        != TCL_OK) {
        sdata->validationState = VALIDATION_ERROR;
        XML_StopParser (vdata->parser, 0);
        return;
    }
    if (atts[0] || (sdata->stack
                    && sdata->stack->pattern->attrs)) {
        if (probeAttributes (vdata->interp, sdata, atts)
            != TCL_OK) {
            sdata->validationState = VALIDATION_ERROR;
            XML_StopParser (vdata->parser, 0);
        }
    }
}
................................................................................
    if (probeElement (interp, sdata, ln,
                      node->namespace ?
                      node->ownerDocument->namespaces[node->namespace-1]->uri
                      : NULL)
        != TCL_OK) {
        return TCL_ERROR;
    }

    if (node->firstAttr) {
        if (probeDomAttributes (interp, sdata, node->firstAttr) != TCL_OK) {
            return TCL_ERROR;
        }
    } else {
        if (sdata->stack->pattern->numReqAttr) {
            /* probeDomAttributes fills interp result with a msg which
             * required attributes are missing. */
            probeDomAttributes (interp, sdata, NULL);
            return TCL_ERROR;

        }
    }

    if (sdata->stack->pattern->domKeys) {
        if (checkdomKeyConstraints (interp, sdata, node) != TCL_OK)
            return TCL_ERROR;
    }
................................................................................
    Tcl_Obj *rObj;

    rObj = Tcl_NewObj();
    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewStringObj ("#text", 5));
    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewObj());
    return rObj;
}















static void
definedElements (
    SchemaData *sdata,
    Tcl_Interp *interp
    )
{
................................................................................
                    }
                }
                break;

            case SCHEMA_CTYPE_VIRTUAL:
            case SCHEMA_CTYPE_KEYSPACE:
            case SCHEMA_CTYPE_KEYSPACE_END:

                break;
            }
            if (cp->type == SCHEMA_CTYPE_INTERLEAVE && minOne(cp->quants[ac]))
                mustMatch = 1;

            else if (!mayskip && minOne (cp->quants[ac])) break;

            ac++;





        }
        break;
        
    case SCHEMA_CTYPE_ANY:
    case SCHEMA_CTYPE_CHOICE:
    case SCHEMA_CTYPE_TEXT:
    case SCHEMA_CTYPE_VIRTUAL:
................................................................................
                    } else {
                        attData = objv[4];
                    }
                }
            }
            result = probeElement (interp, sdata, Tcl_GetString (objv[3]),
                                   namespacePtr);
            if (result == TCL_OK) {
                result = probeEventAttribute (interp, sdata, attData, len);
            }
            break;
            
        case k_elementend:
            if (objc != 3) {
                Tcl_WrongNumArgs (interp, 3, objv, "No arguments expected.");







>

<


<
<
<
<





<
<







 







|
|







 







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







 







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







 







>


|
|
>
|
>

>
>
>
>
>







 







|







1096
1097
1098
1099
1100
1101
1102
1103
1104

1105
1106




1107
1108
1109
1110
1111


1112
1113
1114
1115
1116
1117
1118
....
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
....
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
....
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
....
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
....
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
static int
evalVirtual (
    Tcl_Interp *interp,
    SchemaData *sdata,
    int ac
    )
{
    int rc;
    SchemaCP *cp;


    cp = sdata->stack->pattern->content[ac];




    cp->content[cp->nc-1] = (SchemaCP *) sdata->self;
    sdata->currentEvals++;
    rc = Tcl_EvalObjv (interp, cp->nc, (Tcl_Obj **) cp->content,
                       TCL_EVAL_GLOBAL);
    sdata->currentEvals--;


    if (rc != TCL_OK) {
        sdata->evalError = 1;
        return 0;
    }
    return 1;
}

................................................................................

    if (probeElement (vdata->interp, sdata, s, namespace)
        != TCL_OK) {
        sdata->validationState = VALIDATION_ERROR;
        XML_StopParser (vdata->parser, 0);
        return;
    }
    if (sdata->skipDeep == 0
        && (atts[0] || (sdata->stack && sdata->stack->pattern->attrs))) {
        if (probeAttributes (vdata->interp, sdata, atts)
            != TCL_OK) {
            sdata->validationState = VALIDATION_ERROR;
            XML_StopParser (vdata->parser, 0);
        }
    }
}
................................................................................
    if (probeElement (interp, sdata, ln,
                      node->namespace ?
                      node->ownerDocument->namespaces[node->namespace-1]->uri
                      : NULL)
        != TCL_OK) {
        return TCL_ERROR;
    }
    if (sdata->skipDeep == 0) {
        if (node->firstAttr) {
            if (probeDomAttributes (interp, sdata, node->firstAttr) != TCL_OK) {
                return TCL_ERROR;
            }
        } else {
            if (sdata->stack->pattern->numReqAttr) {
                /* probeDomAttributes fills interp result with a msg which
                 * required attributes are missing. */
                probeDomAttributes (interp, sdata, NULL);
                return TCL_ERROR;
            }
        }
    }

    if (sdata->stack->pattern->domKeys) {
        if (checkdomKeyConstraints (interp, sdata, node) != TCL_OK)
            return TCL_ERROR;
    }
................................................................................
    Tcl_Obj *rObj;

    rObj = Tcl_NewObj();
    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewStringObj ("#text", 5));
    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewObj());
    return rObj;
}

static Tcl_Obj*
serializeElementEnd (
    Tcl_Interp *interp
    )
{
    Tcl_Obj *rObj;

    rObj = Tcl_NewObj();
    Tcl_ListObjAppendElement (interp, rObj,
                              Tcl_NewStringObj ("<elementend>", 12));
    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewObj());
    return rObj;
}

static void
definedElements (
    SchemaData *sdata,
    Tcl_Interp *interp
    )
{
................................................................................
                    }
                }
                break;

            case SCHEMA_CTYPE_VIRTUAL:
            case SCHEMA_CTYPE_KEYSPACE:
            case SCHEMA_CTYPE_KEYSPACE_END:
                mayskip = 1;
                break;
            }
            if (cp->type == SCHEMA_CTYPE_INTERLEAVE) {
                if (minOne(cp->quants[ac])) mustMatch = 1;
            } else {
                if (!mayskip && minOne (cp->quants[ac])) break;
            }
            ac++;
        }
        if (cp->type == SCHEMA_CTYPE_NAME && ac == cp->nc) {
            Tcl_ListObjAppendElement (
                interp, rObj, serializeElementEnd (interp)
                );
        }
        break;
        
    case SCHEMA_CTYPE_ANY:
    case SCHEMA_CTYPE_CHOICE:
    case SCHEMA_CTYPE_TEXT:
    case SCHEMA_CTYPE_VIRTUAL:
................................................................................
                    } else {
                        attData = objv[4];
                    }
                }
            }
            result = probeElement (interp, sdata, Tcl_GetString (objv[3]),
                                   namespacePtr);
            if (sdata->skipDeep == 0 && result == TCL_OK) {
                result = probeEventAttribute (interp, sdata, attData, len);
            }
            break;
            
        case k_elementend:
            if (objc != 3) {
                Tcl_WrongNumArgs (interp, 3, objv, "No arguments expected.");

Changes to tests/schema.test.

1747
1748
1749
1750
1751
1752
1753

1754
1755
1756
1757
1758
1759
1760
....
1775
1776
1777
1778
1779
1780
1781

1782
1783
1784
1785
1786
1787
1788
....
1803
1804
1805
1806
1807
1808
1809

1810
1811
1812
1813
1814
1815
1816
....
1837
1838
1839
1840
1841
1842
1843

1844
1845
1846
1847
1848
1849
1850
....
1871
1872
1873
1874
1875
1876
1877

1878
1879
1880
1881
1882
1883
1884
....
1905
1906
1907
1908
1909
1910
1911

1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
....
1953
1954
1955
1956
1957
1958
1959

1960
1961
1962
1963
1964
1965
1966
....
1978
1979
1980
1981
1982
1983
1984

1985
1986
1987

1988
1989






























1990
1991
1992
1993
1994
1995
1996
....
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
....
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
....
5313
5314
5315
5316
5317
5318
5319

5320

5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
....
5341
5342
5343
5344
5345
5346
5347

5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
        <doc><a/><a/><a/></doc>
        <doc><a/><a/><a/><c/></doc>
        <doc><b/><b/><b/><c/></doc>
        <doc><c/></doc>
    } {
        lappend result [s validate $xml]
    }

    set result
} {0 0 1 0 1 1 1}

test schema-7.15a {choice with optional choices} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
        <doc><a/><a/><a/></doc>
        <doc><a/><a/><a/><c/></doc>
        <doc><b/><b/><b/><c/></doc>
        <doc><b/><b/><b/></doc>
    } {
        lappend result [s validate $xml]
    }

    set result
} {1 1 0 1 0 0 1}

test schema-7.15b {choice with optional choices} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
        <doc><a/><a/><a/></doc>
        <doc><a/><a/><a/><c/></doc>
        <doc><b/><b/><b/><c/></doc>
        <doc><b/></doc>
    } {
        lappend result [s validate $xml]
    }

    set result
} {1 1 0 1 0 0 1}

test schema-7.16 {choice with optional choices} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
        <doc><aa/><c/></doc>
        <doc><aa/><ab/><aa/><c/></doc>
        <doc><aa/><ab/><aa/><aa/><ab/><c/></doc>
        <doc><c/></doc>
    } {
        lappend result [s validate $xml]
    }

    set result
} {0 0 1 0 1 1 1 1 1}

test schema-7.17 {choice with optional choices} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
        <doc><aa/><c/></doc>
        <doc><aa/><ab/><aa/><c/></doc>
        <doc><aa/><ab/><aa/><aa/><ab/><c/></doc>
        <doc><c/></doc>
    } {
        lappend result [s validate $xml]
    }

    set result
} {0 0 1 0 1 1 0 0 1}

test schema-7.18 {choice} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
        <doc><aa/><c/></doc>
        <doc><aa/><ab/><aa/><c/></doc>
        <doc><aa/><ab/><aa/><aa/><ab/><c/></doc>
        <doc><c/></doc>
    } {
        lappend result [s validate $xml]
    }

    set result
} {0 0 1 0 0 1 0 0 0}

        # <doc/>
        # <doc><a/></doc>
        # <doc><a/><c/></doc>
        # <doc><a/><a/><c/></doc>
        # <doc><a/><a/></doc>
        # <doc><a/><a/><a/></doc>
        # <doc><a/><a/><a/><c/></doc>
        # <doc><aa/><c/></doc>
        # <doc><aa/><ab/><aa/><c/></doc>
        # <doc><aa/><ab/><aa/><aa/><ab/><c/></doc>
        # <doc><c/></doc>

test schema-7.19 {choice with quantified choice} {
    tdom::schema create s
    s define {
        defelement doc {
            choice {
                element a {0 2}
                group {
................................................................................
        <doc><aa/><c/></doc>
        <doc><aa/><ab/><aa/><c/></doc>
        <doc><aa/><ab/><aa/><aa/><ab/><c/></doc>
        <doc><c/></doc>
    } {
        lappend result [s validate $xml]
    }

    set result
} {0 0 1 1 0 0 0 1 0 0 1}

test schema-7.20 {group with only optional content} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
    foreach xml {
        <doc/>
        <doc><a/></doc>
        <doc><a/><c/></doc>
        <doc><a/><a/><c/></doc>
        <doc><a/><b/></doc>
        <doc><a/><b/><c/></doc>

    } {
        lappend result [s validate $xml]
    }

    set result
} {0 1 1 0 1 1}































test schema-8.1 {validate method} {
    tdom::schema create grammar
    grammar defelement doc {
        element e1
        element e2 *
    }
................................................................................
            element must
        }
    }
    set result ""
    lappend [s validate {<doc><must/></doc>}]
    s delete
    set result
} {c may must}

test schema-17.10 {info expected interleave} {
    set defs {
        {
            interleave {
                element a ?
                element b
................................................................................
    s event end
    set result [lsort [s info expected]]
    s event start something
    s event end
    lappend result {*}[lsort [s info expected]]
    s delete
    set result
} {{<any> {}} {<any> http://foo.bar} b}

proc schema-17.13 {scmd args} {
    global result
    lappend result {*}[lsort [$scmd info expected]]
}
test schema-17.13 {info expected} {
    set defs {
        {
            element a
            element b ?
        }
................................................................................
    set defnr 0
    foreach def $defs {
        tdom::schema s
        s defelement doc $def
        s reportcmd schema-17.13
        set xmlnr 0
        foreach xml $xmlinput {

            lappend result $defnr/$xmlnr: [s validate $xml errMsg]

            incr xmlnr
        }
        s delete
        incr defnr
    }
    set result
} {}

proc schema-17.14 {scmd} {
    global result
    lappend result {*}[lsort [$scmd info expected]]
}
test schema-17.14 {info expected} {
    set defs {
        {
            group + {
................................................................................
            tcl schema-17.14
            element d
        }
    }
    set result [list]
    foreach def $defs {
        tdom::schema s

        s defelement doc $def
        s event start doc
        catch {s event start unknownElement}
        s delete
    }
    set result
} {a b c d}

proc schema-17.15 {type cmd} {
    lappend ::result $type [$cmd info stack inside]
}

test schema-17.15 {info inside} {
    tdom::schema s







>







 







>







 







>







 







>







 







>







 







>



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







 







>







 







>



>

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







 







|







 







|


|
|







 







>

>






|

|







 







>


|



|







1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
....
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
....
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
....
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
....
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
....
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920












1921
1922
1923
1924
1925
1926
1927
....
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
....
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
....
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
....
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
....
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
....
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
        <doc><a/><a/><a/></doc>
        <doc><a/><a/><a/><c/></doc>
        <doc><b/><b/><b/><c/></doc>
        <doc><c/></doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 1 0 1 1 1}

test schema-7.15a {choice with optional choices} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
        <doc><a/><a/><a/></doc>
        <doc><a/><a/><a/><c/></doc>
        <doc><b/><b/><b/><c/></doc>
        <doc><b/><b/><b/></doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {1 1 0 1 0 0 1}

test schema-7.15b {choice with optional choices} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
        <doc><a/><a/><a/></doc>
        <doc><a/><a/><a/><c/></doc>
        <doc><b/><b/><b/><c/></doc>
        <doc><b/></doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {1 1 0 1 0 0 1}

test schema-7.16 {choice with optional choices} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
        <doc><aa/><c/></doc>
        <doc><aa/><ab/><aa/><c/></doc>
        <doc><aa/><ab/><aa/><aa/><ab/><c/></doc>
        <doc><c/></doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 1 0 1 1 1 1 1}

test schema-7.17 {choice with optional choices} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
        <doc><aa/><c/></doc>
        <doc><aa/><ab/><aa/><c/></doc>
        <doc><aa/><ab/><aa/><aa/><ab/><c/></doc>
        <doc><c/></doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 1 0 1 1 0 0 1}

test schema-7.18 {choice} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
        <doc><aa/><c/></doc>
        <doc><aa/><ab/><aa/><c/></doc>
        <doc><aa/><ab/><aa/><aa/><ab/><c/></doc>
        <doc><c/></doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 1 0 0 1 0 0 0}













test schema-7.19 {choice with quantified choice} {
    tdom::schema create s
    s define {
        defelement doc {
            choice {
                element a {0 2}
                group {
................................................................................
        <doc><aa/><c/></doc>
        <doc><aa/><ab/><aa/><c/></doc>
        <doc><aa/><ab/><aa/><aa/><ab/><c/></doc>
        <doc><c/></doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 1 1 0 0 0 1 0 0 1}

test schema-7.20 {group with only optional content} {
    tdom::schema create s
    s define {
        defelement doc {
................................................................................
    foreach xml {
        <doc/>
        <doc><a/></doc>
        <doc><a/><c/></doc>
        <doc><a/><a/><c/></doc>
        <doc><a/><b/></doc>
        <doc><a/><b/><c/></doc>
        <doc><b/><c/></doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 1 1 0 1 1 0}

test schema-7.21 {group with only optional content} {
    set def {
        group + {
            element c ?
            element a ?
            element b ?
        }
        element d
    }
    set result [list]
    tdom::schema s
    s defelement doc $def
    foreach xml {
        <doc/>
        <doc><a/></doc>
        <doc><a/><c/><d/></doc>
        <doc><c/><d/></doc>
        <doc><a/><a/><c/><d/></doc>
        <doc><a/><b/><d/></doc>
        <doc><a/><b/><c/><d/></doc>
        <doc><b/><c/><d/></doc>
        <doc><d/></doc>
        <doc><d/><d/></doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 1 1 1 1 1 1 1 0}

test schema-8.1 {validate method} {
    tdom::schema create grammar
    grammar defelement doc {
        element e1
        element e2 *
    }
................................................................................
            element must
        }
    }
    set result ""
    lappend [s validate {<doc><must/></doc>}]
    s delete
    set result
} {a b c may must}

test schema-17.10 {info expected interleave} {
    set defs {
        {
            interleave {
                element a ?
                element b
................................................................................
    s event end
    set result [lsort [s info expected]]
    s event start something
    s event end
    lappend result {*}[lsort [s info expected]]
    s delete
    set result
} {{<any> {}} {<any> http://foo.bar} {<elementend> {}} b}

proc schema-17.13 {scmd args} {
    global fromReportCmd
    set fromReportCmd [lsort [$scmd info expected]]
}
test schema-17.13 {info expected} {
    set defs {
        {
            element a
            element b ?
        }
................................................................................
    set defnr 0
    foreach def $defs {
        tdom::schema s
        s defelement doc $def
        s reportcmd schema-17.13
        set xmlnr 0
        foreach xml $xmlinput {
            set fromReportCmd ""
            lappend result $defnr/$xmlnr: [s validate $xml errMsg]
            lappend result {*}$fromReportCmd
            incr xmlnr
        }
        s delete
        incr defnr
    }
    set result
} {0/0: 1 a 0/1: 1 0/2: 1 a 0/3: 1 0/4: 1 a 0/5: 1 {<elementend> {}} b 1/0: 1 a b 1/1: 1 b 1/2: 1 1/3: 1 1/4: 1 a b 1/5: 1 b 2/0: 1 2/1: 1 2/2: 1 2/3: 1 2/4: 1 {<elementend> {}} a b 2/5: 1 {<elementend> {}} b}

proc schema-17.14 {scmd args} {
    global result
    lappend result {*}[lsort [$scmd info expected]]
}
test schema-17.14 {info expected} {
    set defs {
        {
            group + {
................................................................................
            tcl schema-17.14
            element d
        }
    }
    set result [list]
    foreach def $defs {
        tdom::schema s
        s reportcmd schema-17.14
        s defelement doc $def
        s event start doc
        s event start unknownElement
        s delete
    }
    set result
} {a b c d a b c d}

proc schema-17.15 {type cmd} {
    lappend ::result $type [$cmd info stack inside]
}

test schema-17.15 {info inside} {
    tdom::schema s