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

Overview
Comment:Made the default recover behaviour at element end the same as for element start: skip and continue at the sibling of the current subtree.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wip
Files: files | file ages | folders
SHA3-256: 0037ce9df32e0df230b61ea0f25029ed408e537707e35b51f444dcb366d7e43e
User & Date: rolf 2020-03-19 02:15:06
Original Comment: Made the default recover behaviour at element end the same as for an element end: skip and continue at the sibling of the current subtree.
Context
2020-03-19
02:21
Integrated so far done work: bug fixes in recoving, more work on sanitizing recovering, code gardening. check-in: 33ac16a9c2 user: rolf tags: schema
02:15
Made the default recover behaviour at element end the same as for element start: skip and continue at the sibling of the current subtree. Closed-Leaf check-in: 0037ce9df3 user: rolf tags: wip
01:09
Added a recoverFlags element to the schema data structure and reworked the rewind flag int to be a recoverFlags flag. We will need more of them. check-in: 02d5ffc9b5 user: rolf tags: wip
Changes

Changes to generic/schema.c.

1054
1055
1056
1057
1058
1059
1060

1061
1062
1063
1064
1065
1066
1067
....
1152
1153
1154
1155
1156
1157
1158




1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
....
2325
2326
2327
2328
2329
2330
2331

2332
2333
2334
2335
2336
2337
2338
    )
{
    Tcl_Obj *cmdPtr;
    int rc;
    SchemaValidationStack *se;

    if (!sdata->reportCmd || sdata->evalError) return 0;

    /* If non SCHEMA_CTYPE_NAME and the pattern hasn't already matched
     * that's a pattern pushed on stack to look for (probe) if it
     * matches (or allows empty match). Even if the pattern fail it
     * may be optional; recovering is done at the caller level in case
     * the pattern isn't optional. */
    if (sdata->stack
        && sdata->stack->pattern->type != SCHEMA_CTYPE_NAME
................................................................................
    case UNEXPECTED_ELEMENT:
        finalizeElement (sdata, ac+1);
        sdata->skipDeep = 2;
        break;
    case UNEXPECTED_TEXT:
        sdata->recoverFlags |= RECOVER_FLAG_REWIND;
        break;




    case DOM_KEYCONSTRAINT:
    case DOM_XPATH_BOOLEAN:
    case MISSING_ATTRIBUTE:
    case MISSING_ELEMENT_MATCH_END:
    case MISSING_TEXT_MATCH_START:
    case MISSING_TEXT_MATCH_END:
    case UNEXPECTED_ROOT_ELEMENT:
    case UNKNOWN_ATTRIBUTE:
    case INVALID_KEYREF_MATCH_START:
    case INVALID_KEYREF_MATCH_END:
    case INVALID_KEYREF_MATCH_TEXT:
    case UNKNOWN_ROOT_ELEMENT:
    case UNKOWN_GLOBAL_ID:
................................................................................
    }

    rc = checkElementEnd (interp, sdata);
    while (rc == -1) {
        popStack (sdata);
        rc = checkElementEnd (interp, sdata);
    }

    if (rc) {
        popStack (sdata);
        if (sdata->stack == NULL) {
            /* End of the first pattern (the tree root) without error. */
            /* Check for unknown ID references */
            if (!checkDocKeys (interp, sdata)) {
                return TCL_ERROR;







>







 







>
>
>
>



<

<







 







>







1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
....
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166

1167

1168
1169
1170
1171
1172
1173
1174
....
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
    )
{
    Tcl_Obj *cmdPtr;
    int rc;
    SchemaValidationStack *se;

    if (!sdata->reportCmd || sdata->evalError) return 0;
    if (sdata->recoverFlags & RECOVER_FLAG_DONT_REPORT) return 1;
    /* If non SCHEMA_CTYPE_NAME and the pattern hasn't already matched
     * that's a pattern pushed on stack to look for (probe) if it
     * matches (or allows empty match). Even if the pattern fail it
     * may be optional; recovering is done at the caller level in case
     * the pattern isn't optional. */
    if (sdata->stack
        && sdata->stack->pattern->type != SCHEMA_CTYPE_NAME
................................................................................
    case UNEXPECTED_ELEMENT:
        finalizeElement (sdata, ac+1);
        sdata->skipDeep = 2;
        break;
    case UNEXPECTED_TEXT:
        sdata->recoverFlags |= RECOVER_FLAG_REWIND;
        break;
    case MISSING_ELEMENT_MATCH_END:
    case MISSING_TEXT_MATCH_END:
        sdata->recoverFlags |= RECOVER_FLAG_DONT_REPORT;
        break;        
    case DOM_KEYCONSTRAINT:
    case DOM_XPATH_BOOLEAN:
    case MISSING_ATTRIBUTE:

    case MISSING_TEXT_MATCH_START:

    case UNEXPECTED_ROOT_ELEMENT:
    case UNKNOWN_ATTRIBUTE:
    case INVALID_KEYREF_MATCH_START:
    case INVALID_KEYREF_MATCH_END:
    case INVALID_KEYREF_MATCH_TEXT:
    case UNKNOWN_ROOT_ELEMENT:
    case UNKOWN_GLOBAL_ID:
................................................................................
    }

    rc = checkElementEnd (interp, sdata);
    while (rc == -1) {
        popStack (sdata);
        rc = checkElementEnd (interp, sdata);
    }
    sdata->recoverFlags &= ~RECOVER_FLAG_DONT_REPORT;
    if (rc) {
        popStack (sdata);
        if (sdata->stack == NULL) {
            /* End of the first pattern (the tree root) without error. */
            /* Check for unknown ID references */
            if (!checkDocKeys (interp, sdata)) {
                return TCL_ERROR;

Changes to tests/schema.test.

7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
....
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
....
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
....
7814
7815
7816
7817
7818
7819
7820



























7821
7822
7823
7824
7825
7826
7827
    }
    s reportcmd schema-18
    set result ""
    set rc [s validate {<doc><e/></doc>}]
    lappend result $rc
    s delete
    set result
} {s MISSING_TEXT s MISSING_ELEMENT 1}

test schema-18.1a {reportcmd} {
    tdom::schema s
    s define {
        defelement doc {
            element e
            text {minLength 1}
................................................................................
        <doc><a/><b/>unexpected_text</doc>
        <doc><a/><b/><c/>unexpected_text</doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {}

proc schema-18.18 {scmd errortype} {
    lappend ::result $errortype
    lappend ::result [$scmd info expected]
}
test schema-18.18 {missing element at MATCH_ELEMENT_END} {
    set defs {
................................................................................
        tdom::schema s
        s reportcmd schema-18.18
        s define $def
        lappend result [s validate {<doc/>}]
        s delete
    }
    set result
} {}

test schema-18.19 {unexpected text} {
    tdom::schema s
    s reportcmd appendtoresult
    s define {
        defelement doc {
            ref r1 ?
................................................................................
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {UNEXPECTED_TEXT 1 UNEXPECTED_TEXT 1 UNEXPECTED_TEXT 1 UNEXPECTED_TEXT 1 UNEXPECTED_TEXT 1 UNEXPECTED_TEXT 1}





























proc validatedSAX {g xml {keepEmpties 1}} {
    set args [list -validateCmd $g]
    if {!$keepEmpties} {
        lappend args -ignorewhitespace 1
    }
    xml::parser p {*}$args







|







 







|







 







|







 







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







7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
....
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
....
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
....
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
    }
    s reportcmd schema-18
    set result ""
    set rc [s validate {<doc><e/></doc>}]
    lappend result $rc
    s delete
    set result
} {s MISSING_TEXT 1}

test schema-18.1a {reportcmd} {
    tdom::schema s
    s define {
        defelement doc {
            element e
            text {minLength 1}
................................................................................
        <doc><a/><b/>unexpected_text</doc>
        <doc><a/><b/><c/>unexpected_text</doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {UNEXPECTED_TEXT MISSING_ELEMENT 1 UNEXPECTED_TEXT MISSING_ELEMENT 1 UNEXPECTED_TEXT MISSING_ELEMENT 1 UNEXPECTED_TEXT 1}

proc schema-18.18 {scmd errortype} {
    lappend ::result $errortype
    lappend ::result [$scmd info expected]
}
test schema-18.18 {missing element at MATCH_ELEMENT_END} {
    set defs {
................................................................................
        tdom::schema s
        s reportcmd schema-18.18
        s define $def
        lappend result [s validate {<doc/>}]
        s delete
    }
    set result
} {MISSING_ELEMENT a 1 MISSING_ELEMENT a 1 MISSING_ELEMENT a0 1 MISSING_ELEMENT a0 1}

test schema-18.19 {unexpected text} {
    tdom::schema s
    s reportcmd appendtoresult
    s define {
        defelement doc {
            ref r1 ?
................................................................................
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {UNEXPECTED_TEXT 1 UNEXPECTED_TEXT 1 UNEXPECTED_TEXT 1 UNEXPECTED_TEXT 1 UNEXPECTED_TEXT 1 UNEXPECTED_TEXT 1}

test schema-18.20 {Missing element on element end} {
    tdom::schema s
    s reportcmd appendtoresult
    s define {
        defelement doc {
            element a * {
                element b ! {}
                element c ! {}
            }
        }
    }
    set result [list]
    foreach xml {
        <doc/>
        <doc></doc>
        <doc><a/></doc>
        <doc><a>unexpected_text</a></doc>
        <doc><a><b/>unexpected_text</a></doc>
        <doc><a><b/></a></doc>
        <doc><a><b/></a><a/></doc>
        <doc><a><b/></a><a><b/><c/></a><a><b/><c/>unexpected</a></doc>
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {1 1 MISSING_ELEMENT 1 UNEXPECTED_TEXT MISSING_ELEMENT 1 UNEXPECTED_TEXT MISSING_ELEMENT 1 MISSING_ELEMENT 1 MISSING_ELEMENT MISSING_ELEMENT 1 MISSING_ELEMENT UNEXPECTED_TEXT 1}

proc validatedSAX {g xml {keepEmpties 1}} {
    set args [list -validateCmd $g]
    if {!$keepEmpties} {
        lappend args -ignorewhitespace 1
    }
    xml::parser p {*}$args