tDOM

Check-in [918781e945]
Login

Check-in [918781e945]

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

Overview
Comment:Implementend restricted XPath expressions for local key selectors and fields.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | localkey
Files: files | file ages | folders
SHA3-256: 918781e945270c3fcb93e560e9b74889d4280e9e1cbab6d11b1b5a325b53f730
User & Date: rolf 2019-05-07 22:52:31.963
Context
2019-05-09
14:27
wip check-in: b0e429ebf8 user: rolf tags: localkey
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
Changes
Unified Diff Ignore Whitespace Patch
Changes to generic/schema.c.
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
}

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,







|
>


>
>


|
|
>
>
>
>
|
<


>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
|
<
>
|


>
>
>
>
>
>
>
>



<
<
<
<
<
<



|



>


>

<







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
}

extern void printAst (int depth, ast t);
static int
processSchemaXPath (
    Tcl_Interp *interp,
    ast t,
    int field,
    int toplevel
    )
{
    ast child;
    
    while (t) {
        switch (t->type) {
        case GetContextNode:
            if (!toplevel) {
                SetResult ("Not a reduced XPath expression.");
                return TCL_ERROR;
            }
            t = t->next;
            continue;

        case CombineSets:
            /* Only on top level? */
            if (!toplevel) {
                SetResult ("Not a reduced XPath expression.");
                return TCL_ERROR;
            }
            for (child = t->child; child != NULL; child = child->next) {
                if (processSchemaXPath (interp, child, field, 0) != TCL_OK) {
                    return TCL_ERROR;
                }
            }
            break;
        case AxisDescendant:
            if (!toplevel) {
                SetResult ("Not a reduced XPath expression.");
                return TCL_ERROR;
            }
            break;
        case IsElement:
        case IsFQElement:
        case IsNSElement:
        case AxisChild:

            break;
        case AxisAttribute:
        case IsNSAttr:
        case IsAttr:
            if (!field) {
                SetResult ("Attribute selection is only possible in reduced "
                           "XPath expression for field selectors.");
                return TCL_ERROR;
            }
            if (t->type == AxisAttribute) {
                break;
            }
            break;
        default:
            SetResult ("Not a reduced XPath expression.");






            return TCL_ERROR;
        }
        if (t->child) {
            if (processSchemaXPath (interp, t->child, field, 0) != TCL_OK) {
                return TCL_ERROR;
            }
        }
        toplevel = 0;
        t = t->next;
    }
    /* printAst (0, t); */
    return TCL_OK;

}

static int
uniquePatternCmd (
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390

3391
3392
3393
3394
3395
3396
3397

    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,







|



<

>







3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414

3415
3416
3417
3418
3419
3420
3421
3422
3423

    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, 1) != TCL_OK) {
        xpathFreeAst (s);
        return TCL_ERROR;
    }

    
    xpathFreeAst (s);
    return TCL_OK;
}

static int
integerImpl (
    Tcl_Interp *interp,
    void *constraintData,
Changes to generic/schema.h.
67
68
69
70
71
72
73







74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98


99
100
101
102
103
104
105
/* The SchemaFlags flags */
#define FORWARD_PATTERN_DEF     1
#define PLACEHOLDER_PATTERN_DEF 2
#define AMBIGUOUS_PATTERN       4
#define LOCAL_DEFINED_ELEMENT   8
#define CONSTRAINT_TEXT_CHILD  16
#define MIXED_CONTENT          32 








typedef struct SchemaCP
{
    Schema_CP_Type    type;
    char             *namespace;
    char             *name;
    struct SchemaCP  *next;
    SchemaFlags       flags;
    struct SchemaCP **content;
    SchemaQuant      *quants;
    unsigned int      nc;
    SchemaAttr      **attrs;
    unsigned int      numAttr;
    unsigned int      numReqAttr;

} SchemaCP;

typedef struct SchemaValidationStack
{
    SchemaCP *pattern;
    struct SchemaValidationStack *next;
    struct SchemaValidationStack *down;
    int               activeChild;
    int               hasMatched;
    int              *interleaveState;
} SchemaValidationStack;



typedef enum {
    VALIDATION_READY,
    VALIDATION_STARTED,
    VALIDATION_ERROR,
    VALIDATION_FINISHED
} ValidationState;







>
>
>
>
>
>
>














>











>
>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* The SchemaFlags flags */
#define FORWARD_PATTERN_DEF     1
#define PLACEHOLDER_PATTERN_DEF 2
#define AMBIGUOUS_PATTERN       4
#define LOCAL_DEFINED_ELEMENT   8
#define CONSTRAINT_TEXT_CHILD  16
#define MIXED_CONTENT          32 

typedef struct keyConstraint {
    char           *name;
    char           *ns;
    struct keyConstraint *child;
    struct keyConstraint *next;
} keyConstraint;

typedef struct SchemaCP
{
    Schema_CP_Type    type;
    char             *namespace;
    char             *name;
    struct SchemaCP  *next;
    SchemaFlags       flags;
    struct SchemaCP **content;
    SchemaQuant      *quants;
    unsigned int      nc;
    SchemaAttr      **attrs;
    unsigned int      numAttr;
    unsigned int      numReqAttr;
    keyConstraint    *localkeys;
} SchemaCP;

typedef struct SchemaValidationStack
{
    SchemaCP *pattern;
    struct SchemaValidationStack *next;
    struct SchemaValidationStack *down;
    int               activeChild;
    int               hasMatched;
    int              *interleaveState;
} SchemaValidationStack;

typedef keyConstraint *key;

typedef enum {
    VALIDATION_READY,
    VALIDATION_STARTED,
    VALIDATION_ERROR,
    VALIDATION_FINISHED
} ValidationState;
Changes to tests/schema.test.
4166
4167
4168
4169
4170
4171
4172





4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
        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}

}







>
>
>
>
>




|



|


4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
        a
        ./../a
        /foo
        a/b
        {a | b}
        a|b
        .//a
        //a
        a/@ref
        a/b/c
        a//b/c
        (.//b|a)/c
    } {
        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 0 1 1 0 1 1}

}