Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | For a domunique constraint now the key value of an empty fieldset node set result can be given. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | schema |
Files: | files | file ages | folders |
SHA3-256: |
426dea4ca8a156acdc0c2910e5ec6dd2 |
User & Date: | rolf 2020-05-27 00:20:25 |
Context
2020-05-27
| ||
00:34 | Integrated bug fix branch: Handling of not per quantifier but per all childs optional content particle. check-in: 32945e114c user: rolf tags: schema | |
00:20 | For a domunique constraint now the key value of an empty fieldset node set result can be given. check-in: 426dea4ca8 user: rolf tags: schema | |
2020-05-20
| ||
14:01 | Fixed gross bug in info expected, which just was not triggered so far. check-in: 910d0dbb65 user: rolf tags: schema | |
Changes
Changes to doc/schema.xml.
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
<m>data</m> with the currently defined content particle and may be requested in scripts evaluated while validating the content of that particle with the schema command method call <m>info stack associated</m>.</desc> </commanddef> <commanddef> <command><method>domunique</method> <m>selector</m> <m>fieldlist</m> <m>?name?</m> <m>?IGNORE_EMPTY_FIELD_SET?</m></command> <desc>If not postvalidating a DOM tree with <m>domvalidate</m> this constraint always match. If postvalidating this constraint resembles the xsd key/keyref mechanism. The <m>selector</m> argument may be any valid XPath expression (without the xsd limits). Several <m>domunique</m> command within one element definition are allowed. They are checked in definition order. </desc> </commanddef> <commanddef> <command><method>domxpathboolean</method> <m>XPath_expr</m> <m>?name?</m></command> <desc><p>If not postvalidating a DOM tree with <m>domvalidate</m> this constraint always match. If postvalidating this constraint matches if the result of the |
| | | > > > > > > > > |
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 |
<m>data</m> with the currently defined content particle and may be requested in scripts evaluated while validating the content of that particle with the schema command method call <m>info stack associated</m>.</desc> </commanddef> <commanddef> <command><method>domunique</method> <m>selector</m> <m>fieldlist</m> <m>?name?</m> <m>?"IGNORE_EMPTY_FIELD_SET"|("EMPTY_FIELD_SET_VALUE" emptyFieldSetValue)?</m></command> <desc>If not postvalidating a DOM tree with <m>domvalidate</m> this constraint always match. If postvalidating this constraint resembles the xsd key/keyref mechanism. The <m>selector</m> argument may be any valid XPath expression (without the xsd limits). Several <m>domunique</m> command within one element definition are allowed. They are checked in definition order. The argument name is avaliable in the recovering script per <m>info vaction name</m>. If the <m>fieldlist</m> doesn't select something for a node of the result set of the <m>selector</m> then the key value will be the empty string, by default. If the arguments <m>EMPTY_FIELD_SET_VALUE <value></m> are given a empty node set will have the key value <m>value</m>. If instead the flag <m>IGNORE_EMPTY_FIELD_SET</m> flag is given then an empty node set result will not have any key value.</desc> </commanddef> <commanddef> <command><method>domxpathboolean</method> <m>XPath_expr</m> <m>?name?</m></command> <desc><p>If not postvalidating a DOM tree with <m>domvalidate</m> this constraint always match. If postvalidating this constraint matches if the result of the |
Changes to generic/schema.c.
556 557 558 559 560 561 562 563 564 565 566 567 568 569 .... 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 .... 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 .... 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 .... 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 |
{ domKeyConstraint *knext; int i; while (kc) { knext = kc->next; if (kc->name) FREE (kc->name); xpathFreeAst (kc->selector); for (i = 0; i < kc->nrFields; i++) { xpathFreeAst (kc->fields[i]); } FREE (kc->fields); FREE (kc); kc = knext; ................................................................................ ) { xpathResultSet nodeList, rs, frs; domKeyConstraint *kc; domNode *n; domAttrNode *attr; int rc, i, j, hnew, len, skip, first; char *errMsg = NULL, *keystr; Tcl_HashTable htable; Tcl_DString dStr; kc = sdata->stack->pattern->domKeys; memset (&nodeList, 0, sizeof (xpathResultSet)); nodeList.type = EmptyResult; memset (&rs, 0, sizeof (xpathResultSet)); ................................................................................ SetResult ("INVALID_DOM_KEYCONSTRAINT"); goto errorCleanup; } if (frs.type == EmptyResult || frs.nr_nodes == 0) { if (kc->flags & DKC_FLAG_IGNORE_EMPTY_FIELD_SET) { continue; } Tcl_CreateHashEntry (&htable, "", &hnew); if (!hnew) { if (recover (interp, sdata, DOM_KEYCONSTRAINT, kc->name, NULL, "", 0)) { break; } SetResultV ("DOM_KEYCONSTRAINT"); goto errorCleanup; } continue; } ................................................................................ SetResult ("INVALID_DOM_KEYCONSTRAINT"); goto errorCleanup; } if (frs.type == EmptyResult || frs.nr_nodes == 0) { if (kc->flags & DKC_FLAG_IGNORE_EMPTY_FIELD_SET) { continue; } if (first) first = 0; else Tcl_DStringAppend (&dStr, ":", 1); continue; } if (frs.nr_nodes != 1) { if (recover (interp, sdata, DOM_KEYCONSTRAINT, kc->name, NULL, NULL, 0)) { skip = 1; break; ................................................................................ Tcl_Obj *const objv[] ) { SchemaData *sdata = GETASI; ast t; char *errMsg = NULL; domKeyConstraint *kc, *kc1; int i, nrFields, flags = 0, nrFlags; Tcl_Obj *elm; CHECK_SI CHECK_TOPLEVEL checkNrArgs (3, 5, "Expected: <selector> <fieldlist> ?<name>? ?flags?"); if (sdata->cp->type != SCHEMA_CTYPE_NAME) { SetResult ("The domunique schema definition command is only " "allowed as direct child of an element."); } if (Tcl_ListObjLength (interp, objv[2], &nrFields) != TCL_OK) { SetResult ("The <fieldlist> argument must be a valid tcl list"); return TCL_ERROR; } if (nrFields == 0) { SetResult ("Non empty fieldlist argument expected."); return TCL_ERROR; } if (objc == 5) { if (Tcl_ListObjLength (interp, objv[4], &nrFlags) != TCL_OK) { SetResult ("The <flags> argument must be a valid tcl list"); return TCL_ERROR; } for (i = 0; i < nrFlags; i++) { Tcl_ListObjIndex (interp, objv[4], i, &elm); if (strcmp ("IGNORE_EMPTY_FIELD_SET", Tcl_GetString (elm)) == 0) { flags |= DKC_FLAG_IGNORE_EMPTY_FIELD_SET; continue; } SetResult3 ("Unknown flag '", Tcl_GetString (elm), "'"); return TCL_ERROR; } } if (xpathParse (Tcl_GetString (objv[1]), NULL, XPATH_EXPR, sdata->prefixns, NULL, &t, &errMsg) < 0) { SetResult3 ("Error in selector xpath: '", errMsg, ""); FREE (errMsg); return TCL_ERROR; } kc = TMALLOC (domKeyConstraint); memset (kc, 0, sizeof (domKeyConstraint)); kc->fields = MALLOC (sizeof (ast) * nrFields); memset (kc->fields, 0, sizeof (ast) * nrFields); kc->nrFields = nrFields; kc->selector = t; kc->flags = flags; for (i = 0; i < nrFields; i++) { Tcl_ListObjIndex (interp, objv[2], i, &elm); if (xpathParse (Tcl_GetString (elm), NULL, XPATH_EXPR, sdata->prefixns, NULL, &t, &errMsg) < 0) { SetResult3 ("Error in field xpath: '", errMsg, ""); FREE (errMsg); xpathFreeAst (t); freedomKeyConstraints (kc); return TCL_ERROR; } kc->fields[i] = t; } if (objc == 4) { kc->name = tdomstrdup (Tcl_GetString (objv[3])); } /* Apppend to end so that the constraints are checked in * definition order */ if (sdata->cp->domKeys) { kc1 = sdata->cp->domKeys; while (1) { if (kc1->next) kc1 = kc1->next; else break; |
> | > > > > | | > | | > > > > > > | | | | < < < | < | > > | < < | > > > > |
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 .... 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 .... 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 .... 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 .... 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 |
{ domKeyConstraint *knext; int i; while (kc) { knext = kc->next; if (kc->name) FREE (kc->name); if (kc->emptyFieldSetValue) FREE (kc->emptyFieldSetValue); xpathFreeAst (kc->selector); for (i = 0; i < kc->nrFields; i++) { xpathFreeAst (kc->fields[i]); } FREE (kc->fields); FREE (kc); kc = knext; ................................................................................ ) { xpathResultSet nodeList, rs, frs; domKeyConstraint *kc; domNode *n; domAttrNode *attr; int rc, i, j, hnew, len, skip, first; char *errMsg = NULL, *keystr, *efsv; Tcl_HashTable htable; Tcl_DString dStr; kc = sdata->stack->pattern->domKeys; memset (&nodeList, 0, sizeof (xpathResultSet)); nodeList.type = EmptyResult; memset (&rs, 0, sizeof (xpathResultSet)); ................................................................................ SetResult ("INVALID_DOM_KEYCONSTRAINT"); goto errorCleanup; } if (frs.type == EmptyResult || frs.nr_nodes == 0) { if (kc->flags & DKC_FLAG_IGNORE_EMPTY_FIELD_SET) { continue; } efsv = ""; if (kc->emptyFieldSetValue) { efsv = kc->emptyFieldSetValue; } Tcl_CreateHashEntry (&htable, efsv, &hnew); if (!hnew) { if (recover (interp, sdata, DOM_KEYCONSTRAINT, kc->name, NULL, efsv, 0)) { break; } SetResultV ("DOM_KEYCONSTRAINT"); goto errorCleanup; } continue; } ................................................................................ SetResult ("INVALID_DOM_KEYCONSTRAINT"); goto errorCleanup; } if (frs.type == EmptyResult || frs.nr_nodes == 0) { if (kc->flags & DKC_FLAG_IGNORE_EMPTY_FIELD_SET) { continue; } if (kc->emptyFieldSetValue) { if (first) first = 0; else Tcl_DStringAppend (&dStr, ":", 1); Tcl_DStringAppend (&dStr, kc->emptyFieldSetValue, kc->efsv_len); } else { if (first) first = 0; else Tcl_DStringAppend (&dStr, ":", 1); } continue; } if (frs.nr_nodes != 1) { if (recover (interp, sdata, DOM_KEYCONSTRAINT, kc->name, NULL, NULL, 0)) { skip = 1; break; ................................................................................ Tcl_Obj *const objv[] ) { SchemaData *sdata = GETASI; ast t; char *errMsg = NULL; domKeyConstraint *kc, *kc1; int i, nrFields, flags = 0; Tcl_Obj *elm; CHECK_SI CHECK_TOPLEVEL checkNrArgs (3, 6, "Expected: <selector> <fieldlist> ?<name>? ?\"IGNORE_EMPTY_FIELD_SET\"|(?\"EMPTY_FIELD_SET_VALUE\" <emptyFieldSetValue?)"); if (sdata->cp->type != SCHEMA_CTYPE_NAME) { SetResult ("The domunique schema definition command is only " "allowed as direct child of an element."); } if (Tcl_ListObjLength (interp, objv[2], &nrFields) != TCL_OK) { SetResult ("The <fieldlist> argument must be a valid tcl list"); return TCL_ERROR; } if (nrFields == 0) { SetResult ("Non empty fieldlist argument expected."); return TCL_ERROR; } if (objc == 5) { if (strcmp (Tcl_GetString (objv[4]), "IGNORE_EMPTY_FIELD_SET") != 0) { SetResult3 ("Unknown flag '", Tcl_GetString (objv[4]), "'"); return TCL_ERROR; } flags |= DKC_FLAG_IGNORE_EMPTY_FIELD_SET; } if (objc == 6) { if (strcmp (Tcl_GetString (objv[4]), "EMPTY_FIELD_SET_VALUE") != 0) { SetResult3 ("Unknown flag '", Tcl_GetString (objv[4]), "'"); return TCL_ERROR; } } if (xpathParse (Tcl_GetString (objv[1]), NULL, XPATH_EXPR, sdata->prefixns, NULL, &t, &errMsg) < 0) { SetResult3 ("Error in selector xpath: '", errMsg, ""); FREE (errMsg); return TCL_ERROR; } kc = TMALLOC (domKeyConstraint); memset (kc, 0, sizeof (domKeyConstraint)); kc->fields = MALLOC (sizeof (ast) * nrFields); memset (kc->fields, 0, sizeof (ast) * nrFields); kc->nrFields = nrFields; kc->selector = t; kc->flags = flags; for (i = 0; i < nrFields; i++) { Tcl_ListObjIndex (interp, objv[2], i, &elm); if (xpathParse (Tcl_GetString (elm), NULL, XPATH_EXPR, sdata->prefixns, NULL, &t, &errMsg) < 0) { SetResult3 ("Error in field xpath: '", errMsg, ""); FREE (errMsg); xpathFreeAst (t); freedomKeyConstraints (kc); return TCL_ERROR; } kc->fields[i] = t; } if (objc >= 4) { kc->name = tdomstrdup (Tcl_GetString (objv[3])); } if (objc == 6) { kc->emptyFieldSetValue = tdomstrdup (Tcl_GetString (objv[5])); kc->efsv_len = strlen (kc->emptyFieldSetValue); } /* Apppend to end so that the constraints are checked in * definition order */ if (sdata->cp->domKeys) { kc1 = sdata->cp->domKeys; while (1) { if (kc1->next) kc1 = kc1->next; else break; |
Changes to generic/schema.h.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
typedef struct domKeyConstraint { char *name; ast selector; ast *fields; int nrFields; int flags; struct domKeyConstraint *next; } domKeyConstraint; typedef struct { char *name; int active; |
> > |
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
typedef struct domKeyConstraint { char *name; ast selector; ast *fields; int nrFields; int flags; char *emptyFieldSetValue; int efsv_len; struct domKeyConstraint *next; } domKeyConstraint; typedef struct { char *name; int active; |
Changes to tests/schema.test.
8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 |
{<doc><item/><item/></doc>} } { lappend result [postValidation s $xml] } s delete set result } {1 0 1 1} test schema-20.3 {domunique} { tdom::schema s s define { defelement doc { element items * { element item * { |
> > > > > > > > > > > > > > > > > > > > > > > |
8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 |
{<doc><item/><item/></doc>} } { lappend result [postValidation s $xml] } s delete set result } {1 0 1 1} test schema-20.2b {domunique} { tdom::schema s s define { defelement doc { domunique item @ref itemrefkey EMPTY_FIELD_SET_VALUE abc element item * { attribute ref ? } } } set result [list] foreach xml { {<doc><item ref="abc"/><item ref="foo"/></doc>} {<doc><item ref="abc"/><item ref="abc"/></doc>} {<doc><item/><item ref="abc"/></doc>} {<doc><item/><item/></doc>} } { lappend result [postValidation s $xml] } s delete set result } {1 0 0 0} test schema-20.3 {domunique} { tdom::schema s s define { defelement doc { element items * { element item * { |