Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Scripted XPath functions now also work in domunique/domxpathboolean XPath expression arguments. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | schema |
Files: | files | file ages | folders |
SHA3-256: |
6c38650608e0a0de106a06c3d1caa589 |
User & Date: | rolf 2020-05-30 01:38:14 |
Context
2020-06-11
| ||
00:52 | Merged from trunk. check-in: f782953f52 user: rolf tags: schema | |
2020-05-30
| ||
01:38 | Scripted XPath functions now also work in domunique/domxpathboolean XPath expression arguments. check-in: 6c38650608 user: rolf tags: schema | |
01:04 | Scripted XPath functions in domunique/domxpathboolean XPath expression crashes. check-in: ad809ed898 user: rolf tags: schema | |
Changes
Changes to generic/domxpath.c.
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
....
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
|
int xpathEvalAst ( ast t, xpathResultSet *nodeList, domNode *node, xpathResultSet *rs, char **errMsg ) { int i, rc, first = 1, docOrder = 1; xpathResultSet savedContext; savedContext = *nodeList; ................................................................................ if (t->type == Pred) { *errMsg = "Pred step not expected now!"; return XPATH_EVAL_ERR; } if (first) { rc = xpathEvalStepAndPredicates (t, nodeList, node, node, 0, &docOrder, NULL, rs, errMsg); CHECK_RC; first = 0; } else { DBG( fprintf(stderr, "doing location step nodeList->nr_nodes=%d \n", nodeList->nr_nodes); ) if (rs->type != xNodeSetResult) { |
>
|
|
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
....
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
|
int xpathEvalAst ( ast t, xpathResultSet *nodeList, domNode *node, xpathCBs * cbs, xpathResultSet *rs, char **errMsg ) { int i, rc, first = 1, docOrder = 1; xpathResultSet savedContext; savedContext = *nodeList; ................................................................................ if (t->type == Pred) { *errMsg = "Pred step not expected now!"; return XPATH_EVAL_ERR; } if (first) { rc = xpathEvalStepAndPredicates (t, nodeList, node, node, 0, &docOrder, cbs, rs, errMsg); CHECK_RC; first = 0; } else { DBG( fprintf(stderr, "doing location step nodeList->nr_nodes=%d \n", nodeList->nr_nodes); ) if (rs->type != xNodeSetResult) { |
Changes to generic/domxpath.h.
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
206
207
208
209
210
211
212
213
214
215
|
void xpathFreeAst (ast t);
double xpathGetPrio (ast t);
int xpathEval (domNode *node, domNode *exprContext, char *xpath,
char **prefixMappings, xpathCBs *cbs,
xpathParseVarCB *parseVarCB, Tcl_HashTable *catch,
char **errMsg, xpathResultSet *rs);
int xpathEvalAst (ast t, xpathResultSet *nodeList, domNode *node,
xpathResultSet *rs, char **errMsg);
int xpathMatches (ast steps, domNode * exprContext, domNode *nodeToMatch,
xpathCBs *cbs, char **errMsg
);
int xpathEvalSteps (ast steps, xpathResultSet *nodeList,
domNode *currentNode, domNode *exprContext, int currentPos,
int *docOrder,
................................................................................
void rsSetString ( xpathResultSet *rs, const char *s );
void rsAddNode ( xpathResultSet *rs, domNode *node );
void rsAddNodeFast ( xpathResultSet *rs, domNode *node );
void rsCopy ( xpathResultSet *to, xpathResultSet *from );
/* This function is only used for debugging code */
void rsPrint ( xpathResultSet *rs );
#endif
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
void xpathFreeAst (ast t); double xpathGetPrio (ast t); int xpathEval (domNode *node, domNode *exprContext, char *xpath, char **prefixMappings, xpathCBs *cbs, xpathParseVarCB *parseVarCB, Tcl_HashTable *catch, char **errMsg, xpathResultSet *rs); int xpathEvalAst (ast t, xpathResultSet *nodeList, domNode *node, xpathCBs *cbs, xpathResultSet *rs, char **errMsg); int xpathMatches (ast steps, domNode * exprContext, domNode *nodeToMatch, xpathCBs *cbs, char **errMsg ); int xpathEvalSteps (ast steps, xpathResultSet *nodeList, domNode *currentNode, domNode *exprContext, int currentPos, int *docOrder, ................................................................................ void rsSetString ( xpathResultSet *rs, const char *s ); void rsAddNode ( xpathResultSet *rs, domNode *node ); void rsAddNodeFast ( xpathResultSet *rs, domNode *node ); void rsCopy ( xpathResultSet *to, xpathResultSet *from ); /* This function is only used for debugging code */ void rsPrint ( xpathResultSet *rs ); /* This function is used (outside of tcldom.c) only by schema.c. It * has to have a prototype somewhere. */ int tcldom_xpathFuncCallBack ( void *clientData, char *functionName, domNode *ctxNode, int position, xpathResultSet *nodeList, domNode *exprContext, int argc, xpathResultSets *args, xpathResultSet *result, char **errMsg ); #endif |
Changes to generic/schema.c.
3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 .... 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 .... 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 .... 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 |
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)); rs.type = EmptyResult; memset (&frs, 0, sizeof (xpathResultSet)); frs.type = EmptyResult; Tcl_DStringInit (&dStr); xpathRSReset (&nodeList, node); while (kc) { xpathRSReset (&rs, NULL); rc = xpathEvalAst (kc->selector, &nodeList, node, &rs, &errMsg); if (rc) { SetResult (errMsg); goto errorCleanup; } if (kc->flags & DKC_FLAG_BOOLEAN) { i = xpathFuncBoolean (&rs); if (!i) { ................................................................................ if (n->nodeType != ELEMENT_NODE) { SetResult ("INVALID_DOM_KEYCONSTRAINT"); goto errorCleanup; } xpathRSReset (&nodeList, n); if (kc->nrFields == 1) { xpathRSReset (&frs, NULL); rc = xpathEvalAst (kc->fields[0], &nodeList, n, &frs, &errMsg); if (rc) { SetResult (errMsg); goto errorCleanup; } if (frs.type != xNodeSetResult && frs.type != EmptyResult) { SetResult ("INVALID_DOM_KEYCONSTRAINT"); goto errorCleanup; ................................................................................ } } else { Tcl_DStringSetLength (&dStr, 0); skip = 0; first = 1; for (j = 0; j < kc->nrFields; j++) { xpathRSReset (&frs, NULL); rc = xpathEvalAst (kc->fields[j], &nodeList, n, &frs, &errMsg); if (rc) { SetResult (errMsg); goto errorCleanup; } if (frs.type != xNodeSetResult && frs.type != EmptyResult) { SetResult ("INVALID_DOM_KEYCONSTRAINT"); ................................................................................ FREE (keystr); } } if (skip) break; Tcl_CreateHashEntry (&htable, Tcl_DStringValue (&dStr), &hnew); if (!hnew) { if (recover (interp, sdata, DOM_KEYCONSTRAINT, kc->name,NULL, Tcl_DStringValue (&dStr), 0)) { break; } SetResultV ("DOM_KEYCONSTRAINT"); goto errorCleanup; } } } |
> > > > > | | > | | | > |
3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 .... 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 .... 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 .... 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 |
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; xpathCBs cbs; kc = sdata->stack->pattern->domKeys; memset (&nodeList, 0, sizeof (xpathResultSet)); nodeList.type = EmptyResult; memset (&rs, 0, sizeof (xpathResultSet)); rs.type = EmptyResult; memset (&frs, 0, sizeof (xpathResultSet)); frs.type = EmptyResult; Tcl_DStringInit (&dStr); xpathRSReset (&nodeList, node); cbs.funcCB = tcldom_xpathFuncCallBack; cbs.funcClientData = interp; cbs.varCB = NULL; cbs.varClientData = NULL; while (kc) { xpathRSReset (&rs, NULL); rc = xpathEvalAst (kc->selector, &nodeList, node, &cbs, &rs, &errMsg); if (rc) { SetResult (errMsg); goto errorCleanup; } if (kc->flags & DKC_FLAG_BOOLEAN) { i = xpathFuncBoolean (&rs); if (!i) { ................................................................................ if (n->nodeType != ELEMENT_NODE) { SetResult ("INVALID_DOM_KEYCONSTRAINT"); goto errorCleanup; } xpathRSReset (&nodeList, n); if (kc->nrFields == 1) { xpathRSReset (&frs, NULL); rc = xpathEvalAst (kc->fields[0], &nodeList, n, &cbs, &frs, &errMsg); if (rc) { SetResult (errMsg); goto errorCleanup; } if (frs.type != xNodeSetResult && frs.type != EmptyResult) { SetResult ("INVALID_DOM_KEYCONSTRAINT"); goto errorCleanup; ................................................................................ } } else { Tcl_DStringSetLength (&dStr, 0); skip = 0; first = 1; for (j = 0; j < kc->nrFields; j++) { xpathRSReset (&frs, NULL); rc = xpathEvalAst (kc->fields[j], &nodeList, n, &cbs, &frs, &errMsg); if (rc) { SetResult (errMsg); goto errorCleanup; } if (frs.type != xNodeSetResult && frs.type != EmptyResult) { SetResult ("INVALID_DOM_KEYCONSTRAINT"); ................................................................................ FREE (keystr); } } if (skip) break; Tcl_CreateHashEntry (&htable, Tcl_DStringValue (&dStr), &hnew); if (!hnew) { if (recover (interp, sdata, DOM_KEYCONSTRAINT, kc->name, NULL, Tcl_DStringValue (&dStr), 0)) { break; } SetResultV ("DOM_KEYCONSTRAINT"); goto errorCleanup; } } } |
Changes to generic/tcldom.c.
1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 |
}
/*----------------------------------------------------------------------------
| tcldom_xpathFuncCallBack
|
\---------------------------------------------------------------------------*/
static
int tcldom_xpathFuncCallBack (
void *clientData,
char *functionName,
domNode *ctxNode,
int position,
xpathResultSet *nodeList,
domNode *exprContext,
|
< |
1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 |
} /*---------------------------------------------------------------------------- | tcldom_xpathFuncCallBack | \---------------------------------------------------------------------------*/ int tcldom_xpathFuncCallBack ( void *clientData, char *functionName, domNode *ctxNode, int position, xpathResultSet *nodeList, domNode *exprContext, |
Changes to tests/schema.test.
9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 |
} lassign $args arg1Typ arg1Value arg2Typ arg2Value set arg1 [::dom::xpathFuncHelper::coerce2string $arg1Typ $arg1Value] set arg2 [::dom::xpathFuncHelper::coerce2string $arg2Typ $arg2Value] return [list number [string compare $arg1 $arg2]] } test schema-25.6 {domxpathboolean - scripted XPath function} { tdom::schema s s define { defelement doc { element a ! { text domxpathboolean {compare('foo','bar') < 0} first domxpathboolean {compare('foo','bar') > 0} second } } } set doc [dom parse {<doc><a>2020-07-30</a></doc>}] set result [s domvalidate $doc error] } {0} proc schema-26.1 {scmd} { lappend ::result "fromtcl: [[$scmd info domNode] nodeName]" } test schema-26.1 {info domNode} { tdom::schema s |
> > > > | | > | < > > |
9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 |
} lassign $args arg1Typ arg1Value arg2Typ arg2Value set arg1 [::dom::xpathFuncHelper::coerce2string $arg1Typ $arg1Value] set arg2 [::dom::xpathFuncHelper::coerce2string $arg2Typ $arg2Value] return [list number [string compare $arg1 $arg2]] } proc schema-25.6 {scmd errorType} { lappend ::result $errorType [$scmd info vaction name] } test schema-25.6 {domxpathboolean - scripted XPath function} { tdom::schema s s reportcmd schema-25.6 s define { defelement doc { element a ! { text domxpathboolean {compare('foo','bar') > 0} first domxpathboolean {compare('foo','bar') < 0} second } } } set doc [dom parse {<doc><a>2020-07-30</a></doc>}] set result "" lappend result [s domvalidate $doc] set result } {DOM_XPATH_BOOLEAN second 1} proc schema-26.1 {scmd} { lappend ::result "fromtcl: [[$scmd info domNode] nodeName]" } test schema-26.1 {info domNode} { tdom::schema s |