| OLD | NEW |
| 1 /* | 1 /* |
| 2 * transform.c: Implementation of the XSL Transformation 1.0 engine | 2 * transform.c: Implementation of the XSL Transformation 1.0 engine |
| 3 * transform part, i.e. applying a Stylesheet to a document | 3 * transform part, i.e. applying a Stylesheet to a document |
| 4 * | 4 * |
| 5 * References: | 5 * References: |
| 6 * http://www.w3.org/TR/1999/REC-xslt-19991116 | 6 * http://www.w3.org/TR/1999/REC-xslt-19991116 |
| 7 * | 7 * |
| 8 * Michael Kay "XSLT Programmer's Reference" pp 637-643 | 8 * Michael Kay "XSLT Programmer's Reference" pp 637-643 |
| 9 * Writing Multiple Output Files | 9 * Writing Multiple Output Files |
| 10 * | 10 * |
| 11 * XSLT-1.1 Working Draft | 11 * XSLT-1.1 Working Draft |
| 12 * http://www.w3.org/TR/xslt11#multiple-output | 12 * http://www.w3.org/TR/xslt11#multiple-output |
| 13 * | 13 * |
| 14 * See Copyright for the status of this software. | 14 * See Copyright for the status of this software. |
| 15 * | 15 * |
| 16 * daniel@veillard.com | 16 * daniel@veillard.com |
| 17 */ | 17 */ |
| 18 | 18 |
| 19 #define IN_LIBXSLT | 19 #define IN_LIBXSLT |
| 20 #include "libxslt.h" | 20 #include "libxslt.h" |
| 21 | 21 |
| 22 #include <string.h> | 22 #include <string.h> |
| 23 #include <stdio.h> |
| 23 | 24 |
| 24 #include <libxml/xmlmemory.h> | 25 #include <libxml/xmlmemory.h> |
| 25 #include <libxml/parser.h> | 26 #include <libxml/parser.h> |
| 26 #include <libxml/tree.h> | 27 #include <libxml/tree.h> |
| 27 #include <libxml/valid.h> | 28 #include <libxml/valid.h> |
| 28 #include <libxml/hash.h> | 29 #include <libxml/hash.h> |
| 29 #include <libxml/encoding.h> | 30 #include <libxml/encoding.h> |
| 30 #include <libxml/xmlerror.h> | 31 #include <libxml/xmlerror.h> |
| 31 #include <libxml/xpath.h> | 32 #include <libxml/xpath.h> |
| 32 #include <libxml/parserInternals.h> | 33 #include <libxml/parserInternals.h> |
| (...skipping 24 matching lines...) Expand all Loading... |
| 57 #define WITH_XSLT_DEBUG_PROCESS | 58 #define WITH_XSLT_DEBUG_PROCESS |
| 58 #endif | 59 #endif |
| 59 | 60 |
| 60 #define XSLT_GENERATE_HTML_DOCTYPE | 61 #define XSLT_GENERATE_HTML_DOCTYPE |
| 61 #ifdef XSLT_GENERATE_HTML_DOCTYPE | 62 #ifdef XSLT_GENERATE_HTML_DOCTYPE |
| 62 static int xsltGetHTMLIDs(const xmlChar *version, const xmlChar **publicID, | 63 static int xsltGetHTMLIDs(const xmlChar *version, const xmlChar **publicID, |
| 63 const xmlChar **systemID); | 64 const xmlChar **systemID); |
| 64 #endif | 65 #endif |
| 65 | 66 |
| 66 int xsltMaxDepth = 3000; | 67 int xsltMaxDepth = 3000; |
| 68 int xsltMaxVars = 15000; |
| 67 | 69 |
| 68 /* | 70 /* |
| 69 * Useful macros | 71 * Useful macros |
| 70 */ | 72 */ |
| 71 | 73 |
| 72 #ifndef FALSE | 74 #ifndef FALSE |
| 73 # define FALSE (0 == 1) | 75 # define FALSE (0 == 1) |
| 74 # define TRUE (!FALSE) | 76 # define TRUE (!FALSE) |
| 75 #endif | 77 #endif |
| 76 | 78 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 if (ctxt->templMax == 0) { | 120 if (ctxt->templMax == 0) { |
| 119 ctxt->templMax = 4; | 121 ctxt->templMax = 4; |
| 120 ctxt->templTab = | 122 ctxt->templTab = |
| 121 (xsltTemplatePtr *) xmlMalloc(ctxt->templMax * | 123 (xsltTemplatePtr *) xmlMalloc(ctxt->templMax * |
| 122 sizeof(ctxt->templTab[0])); | 124 sizeof(ctxt->templTab[0])); |
| 123 if (ctxt->templTab == NULL) { | 125 if (ctxt->templTab == NULL) { |
| 124 xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); | 126 xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); |
| 125 return (0); | 127 return (0); |
| 126 } | 128 } |
| 127 } | 129 } |
| 128 if (ctxt->templNr >= ctxt->templMax) { | 130 else if (ctxt->templNr >= ctxt->templMax) { |
| 129 ctxt->templMax *= 2; | 131 ctxt->templMax *= 2; |
| 130 ctxt->templTab = | 132 ctxt->templTab = |
| 131 (xsltTemplatePtr *) xmlRealloc(ctxt->templTab, | 133 (xsltTemplatePtr *) xmlRealloc(ctxt->templTab, |
| 132 ctxt->templMax * | 134 ctxt->templMax * |
| 133 sizeof(ctxt->templTab[0])); | 135 sizeof(ctxt->templTab[0])); |
| 134 if (ctxt->templTab == NULL) { | 136 if (ctxt->templTab == NULL) { |
| 135 xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); | 137 xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); |
| 136 return (0); | 138 return (0); |
| 137 } | 139 } |
| 138 } | 140 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 { | 244 { |
| 243 if (ctxt->profMax == 0) { | 245 if (ctxt->profMax == 0) { |
| 244 ctxt->profMax = 4; | 246 ctxt->profMax = 4; |
| 245 ctxt->profTab = | 247 ctxt->profTab = |
| 246 (long *) xmlMalloc(ctxt->profMax * sizeof(ctxt->profTab[0])); | 248 (long *) xmlMalloc(ctxt->profMax * sizeof(ctxt->profTab[0])); |
| 247 if (ctxt->profTab == NULL) { | 249 if (ctxt->profTab == NULL) { |
| 248 xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); | 250 xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); |
| 249 return (0); | 251 return (0); |
| 250 } | 252 } |
| 251 } | 253 } |
| 252 if (ctxt->profNr >= ctxt->profMax) { | 254 else if (ctxt->profNr >= ctxt->profMax) { |
| 253 ctxt->profMax *= 2; | 255 ctxt->profMax *= 2; |
| 254 ctxt->profTab = | 256 ctxt->profTab = |
| 255 (long *) xmlRealloc(ctxt->profTab, | 257 (long *) xmlRealloc(ctxt->profTab, |
| 256 ctxt->profMax * sizeof(ctxt->profTab[0])); | 258 ctxt->profMax * sizeof(ctxt->profTab[0])); |
| 257 if (ctxt->profTab == NULL) { | 259 if (ctxt->profTab == NULL) { |
| 258 xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); | 260 xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); |
| 259 return (0); | 261 return (0); |
| 260 } | 262 } |
| 261 } | 263 } |
| 262 ctxt->profTab[ctxt->profNr] = value; | 264 ctxt->profTab[ctxt->profNr] = value; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 281 ctxt->profNr--; | 283 ctxt->profNr--; |
| 282 if (ctxt->profNr > 0) | 284 if (ctxt->profNr > 0) |
| 283 ctxt->prof = ctxt->profTab[ctxt->profNr - 1]; | 285 ctxt->prof = ctxt->profTab[ctxt->profNr - 1]; |
| 284 else | 286 else |
| 285 ctxt->prof = (long) 0; | 287 ctxt->prof = (long) 0; |
| 286 ret = ctxt->profTab[ctxt->profNr]; | 288 ret = ctxt->profTab[ctxt->profNr]; |
| 287 ctxt->profTab[ctxt->profNr] = 0; | 289 ctxt->profTab[ctxt->profNr] = 0; |
| 288 return (ret); | 290 return (ret); |
| 289 } | 291 } |
| 290 | 292 |
| 293 static void |
| 294 profCallgraphAdd(xsltTemplatePtr templ, xsltTemplatePtr parent) |
| 295 { |
| 296 int i; |
| 297 |
| 298 if (templ->templMax == 0) { |
| 299 templ->templMax = 4; |
| 300 templ->templCalledTab = |
| 301 (xsltTemplatePtr *) xmlMalloc(templ->templMax * |
| 302 sizeof(templ->templCalledTab[0])); |
| 303 templ->templCountTab = |
| 304 (int *) xmlMalloc(templ->templMax * |
| 305 sizeof(templ->templCountTab[0])); |
| 306 if (templ->templCalledTab == NULL || templ->templCountTab == NULL) { |
| 307 xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); |
| 308 return; |
| 309 } |
| 310 } |
| 311 else if (templ->templNr >= templ->templMax) { |
| 312 templ->templMax *= 2; |
| 313 templ->templCalledTab = |
| 314 (xsltTemplatePtr *) xmlRealloc(templ->templCalledTab, |
| 315 templ->templMax * |
| 316 sizeof(templ->templCalledTab[0])); |
| 317 templ->templCountTab = |
| 318 (int *) xmlRealloc(templ->templCountTab, |
| 319 templ->templMax * |
| 320 sizeof(templ->templCountTab[0])); |
| 321 if (templ->templCalledTab == NULL || templ->templCountTab == NULL) { |
| 322 xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); |
| 323 return; |
| 324 } |
| 325 } |
| 326 |
| 327 for (i = 0; i < templ->templNr; i++) { |
| 328 if (templ->templCalledTab[i] == parent) { |
| 329 templ->templCountTab[i]++; |
| 330 break; |
| 331 } |
| 332 } |
| 333 if (i == templ->templNr) { |
| 334 /* not found, add new one */ |
| 335 templ->templCalledTab[templ->templNr] = parent; |
| 336 templ->templCountTab[templ->templNr] = 1; |
| 337 templ->templNr++; |
| 338 } |
| 339 } |
| 340 |
| 341 /** |
| 342 * xsltPreCompEval: |
| 343 * @ctxt: transform context |
| 344 * @node: context node |
| 345 * @comp: precompiled expression |
| 346 * |
| 347 * Evaluate a precompiled XPath expression. |
| 348 */ |
| 349 static xmlXPathObjectPtr |
| 350 xsltPreCompEval(xsltTransformContextPtr ctxt, xmlNodePtr node, |
| 351 xsltStylePreCompPtr comp) { |
| 352 xmlXPathObjectPtr res; |
| 353 xmlXPathContextPtr xpctxt; |
| 354 xmlNodePtr oldXPContextNode; |
| 355 xmlNsPtr *oldXPNamespaces; |
| 356 int oldXPProximityPosition, oldXPContextSize, oldXPNsNr; |
| 357 |
| 358 xpctxt = ctxt->xpathCtxt; |
| 359 oldXPContextNode = xpctxt->node; |
| 360 oldXPProximityPosition = xpctxt->proximityPosition; |
| 361 oldXPContextSize = xpctxt->contextSize; |
| 362 oldXPNsNr = xpctxt->nsNr; |
| 363 oldXPNamespaces = xpctxt->namespaces; |
| 364 |
| 365 xpctxt->node = node; |
| 366 #ifdef XSLT_REFACTORED |
| 367 if (comp->inScopeNs != NULL) { |
| 368 xpctxt->namespaces = comp->inScopeNs->list; |
| 369 xpctxt->nsNr = comp->inScopeNs->xpathNumber; |
| 370 } else { |
| 371 xpctxt->namespaces = NULL; |
| 372 xpctxt->nsNr = 0; |
| 373 } |
| 374 #else |
| 375 xpctxt->namespaces = comp->nsList; |
| 376 xpctxt->nsNr = comp->nsNr; |
| 377 #endif |
| 378 |
| 379 res = xmlXPathCompiledEval(comp->comp, xpctxt); |
| 380 |
| 381 xpctxt->node = oldXPContextNode; |
| 382 xpctxt->proximityPosition = oldXPProximityPosition; |
| 383 xpctxt->contextSize = oldXPContextSize; |
| 384 xpctxt->nsNr = oldXPNsNr; |
| 385 xpctxt->namespaces = oldXPNamespaces; |
| 386 |
| 387 return(res); |
| 388 } |
| 389 |
| 390 /** |
| 391 * xsltPreCompEvalToBoolean: |
| 392 * @ctxt: transform context |
| 393 * @node: context node |
| 394 * @comp: precompiled expression |
| 395 * |
| 396 * Evaluate a precompiled XPath expression as boolean. |
| 397 */ |
| 398 static int |
| 399 xsltPreCompEvalToBoolean(xsltTransformContextPtr ctxt, xmlNodePtr node, |
| 400 xsltStylePreCompPtr comp) { |
| 401 int res; |
| 402 xmlXPathContextPtr xpctxt; |
| 403 xmlNodePtr oldXPContextNode; |
| 404 xmlNsPtr *oldXPNamespaces; |
| 405 int oldXPProximityPosition, oldXPContextSize, oldXPNsNr; |
| 406 |
| 407 xpctxt = ctxt->xpathCtxt; |
| 408 oldXPContextNode = xpctxt->node; |
| 409 oldXPProximityPosition = xpctxt->proximityPosition; |
| 410 oldXPContextSize = xpctxt->contextSize; |
| 411 oldXPNsNr = xpctxt->nsNr; |
| 412 oldXPNamespaces = xpctxt->namespaces; |
| 413 |
| 414 xpctxt->node = node; |
| 415 #ifdef XSLT_REFACTORED |
| 416 if (comp->inScopeNs != NULL) { |
| 417 xpctxt->namespaces = comp->inScopeNs->list; |
| 418 xpctxt->nsNr = comp->inScopeNs->xpathNumber; |
| 419 } else { |
| 420 xpctxt->namespaces = NULL; |
| 421 xpctxt->nsNr = 0; |
| 422 } |
| 423 #else |
| 424 xpctxt->namespaces = comp->nsList; |
| 425 xpctxt->nsNr = comp->nsNr; |
| 426 #endif |
| 427 |
| 428 res = xmlXPathCompiledEvalToBoolean(comp->comp, xpctxt); |
| 429 |
| 430 xpctxt->node = oldXPContextNode; |
| 431 xpctxt->proximityPosition = oldXPProximityPosition; |
| 432 xpctxt->contextSize = oldXPContextSize; |
| 433 xpctxt->nsNr = oldXPNsNr; |
| 434 xpctxt->namespaces = oldXPNamespaces; |
| 435 |
| 436 return(res); |
| 437 } |
| 438 |
| 291 /************************************************************************ | 439 /************************************************************************ |
| 292 * * | 440 * * |
| 293 * XInclude default settings * | 441 * XInclude default settings * |
| 294 * * | 442 * * |
| 295 ************************************************************************/ | 443 ************************************************************************/ |
| 296 | 444 |
| 297 static int xsltDoXIncludeDefault = 0; | 445 static int xsltDoXIncludeDefault = 0; |
| 298 | 446 |
| 299 /** | 447 /** |
| 300 * xsltSetXIncludeDefault: | 448 * xsltSetXIncludeDefault: |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 cur->templTab = (xsltTemplatePtr *) | 597 cur->templTab = (xsltTemplatePtr *) |
| 450 xmlMalloc(10 * sizeof(xsltTemplatePtr)); | 598 xmlMalloc(10 * sizeof(xsltTemplatePtr)); |
| 451 if (cur->templTab == NULL) { | 599 if (cur->templTab == NULL) { |
| 452 xsltTransformError(NULL, NULL, (xmlNodePtr) doc, | 600 xsltTransformError(NULL, NULL, (xmlNodePtr) doc, |
| 453 "xsltNewTransformContext: out of memory\n"); | 601 "xsltNewTransformContext: out of memory\n"); |
| 454 goto internal_err; | 602 goto internal_err; |
| 455 } | 603 } |
| 456 cur->templNr = 0; | 604 cur->templNr = 0; |
| 457 cur->templMax = 5; | 605 cur->templMax = 5; |
| 458 cur->templ = NULL; | 606 cur->templ = NULL; |
| 607 cur->maxTemplateDepth = xsltMaxDepth; |
| 459 | 608 |
| 460 /* | 609 /* |
| 461 * initialize the variables stack | 610 * initialize the variables stack |
| 462 */ | 611 */ |
| 463 cur->varsTab = (xsltStackElemPtr *) | 612 cur->varsTab = (xsltStackElemPtr *) |
| 464 xmlMalloc(10 * sizeof(xsltStackElemPtr)); | 613 xmlMalloc(10 * sizeof(xsltStackElemPtr)); |
| 465 if (cur->varsTab == NULL) { | 614 if (cur->varsTab == NULL) { |
| 466 xmlGenericError(xmlGenericErrorContext, | 615 xmlGenericError(xmlGenericErrorContext, |
| 467 "xsltNewTransformContext: out of memory\n"); | 616 "xsltNewTransformContext: out of memory\n"); |
| 468 goto internal_err; | 617 goto internal_err; |
| 469 } | 618 } |
| 470 cur->varsNr = 0; | 619 cur->varsNr = 0; |
| 471 cur->varsMax = 10; | 620 cur->varsMax = 10; |
| 472 cur->vars = NULL; | 621 cur->vars = NULL; |
| 473 cur->varsBase = 0; | 622 cur->varsBase = 0; |
| 623 cur->maxTemplateVars = xsltMaxVars; |
| 474 | 624 |
| 475 /* | 625 /* |
| 476 * the profiling stack is not initialized by default | 626 * the profiling stack is not initialized by default |
| 477 */ | 627 */ |
| 478 cur->profTab = NULL; | 628 cur->profTab = NULL; |
| 479 cur->profNr = 0; | 629 cur->profNr = 0; |
| 480 cur->profMax = 0; | 630 cur->profMax = 0; |
| 481 cur->prof = 0; | 631 cur->prof = 0; |
| 482 | 632 |
| 483 cur->style = style; | 633 cur->style = style; |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 if (string == NULL) | 869 if (string == NULL) |
| 720 return(NULL); | 870 return(NULL); |
| 721 | 871 |
| 722 #ifdef WITH_XSLT_DEBUG_PROCESS | 872 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 723 XSLT_TRACE(ctxt,XSLT_TRACE_COPY_TEXT,xsltGenericDebug(xsltGenericDebugContex
t, | 873 XSLT_TRACE(ctxt,XSLT_TRACE_COPY_TEXT,xsltGenericDebug(xsltGenericDebugContex
t, |
| 724 "xsltCopyTextString: copy text %s\n", | 874 "xsltCopyTextString: copy text %s\n", |
| 725 string)); | 875 string)); |
| 726 #endif | 876 #endif |
| 727 | 877 |
| 728 /* | 878 /* |
| 729 * Play save and reset the merging mechanism for every new | 879 * Play safe and reset the merging mechanism for every new |
| 730 * target node. | 880 * target node. |
| 731 */ | 881 */ |
| 732 if ((target == NULL) || (target->children == NULL)) { | 882 if ((target == NULL) || (target->children == NULL)) { |
| 733 ctxt->lasttext = NULL; | 883 ctxt->lasttext = NULL; |
| 734 } | 884 } |
| 735 | 885 |
| 736 /* handle coalescing of text nodes here */ | 886 /* handle coalescing of text nodes here */ |
| 737 len = xmlStrlen(string); | 887 len = xmlStrlen(string); |
| 738 if ((ctxt->type == XSLT_OUTPUT_XML) && | 888 if ((ctxt->type == XSLT_OUTPUT_XML) && |
| 739 (ctxt->style->cdataSection != NULL) && | 889 (ctxt->style->cdataSection != NULL) && |
| (...skipping 2188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2928 #endif | 3078 #endif |
| 2929 | 3079 |
| 2930 if (list == NULL) | 3080 if (list == NULL) |
| 2931 return; | 3081 return; |
| 2932 CHECK_STOPPED; | 3082 CHECK_STOPPED; |
| 2933 | 3083 |
| 2934 /* | 3084 /* |
| 2935 * Check for infinite recursion: stop if the maximum of nested templates | 3085 * Check for infinite recursion: stop if the maximum of nested templates |
| 2936 * is excceeded. Adjust xsltMaxDepth if you need more. | 3086 * is excceeded. Adjust xsltMaxDepth if you need more. |
| 2937 */ | 3087 */ |
| 2938 if (((ctxt->templNr >= xsltMaxDepth) || | 3088 if (ctxt->templNr >= ctxt->maxTemplateDepth) |
| 2939 (ctxt->varsNr >= 5 * xsltMaxDepth))) | |
| 2940 { | 3089 { |
| 2941 xsltTransformError(ctxt, NULL, list, | 3090 xsltTransformError(ctxt, NULL, list, |
| 2942 "xsltApplyXSLTTemplate: A potential infinite template recursion " | 3091 "xsltApplyXSLTTemplate: A potential infinite template recursion " |
| 2943 "was detected.\n" | 3092 "was detected.\n" |
| 2944 "You can adjust xsltMaxDepth (--maxdepth) in order to " | 3093 "You can adjust xsltMaxDepth (--maxdepth) in order to " |
| 2945 "raise the maximum number of nested template calls and " | 3094 "raise the maximum number of nested template calls and " |
| 2946 "variables/params (currently set to %d).\n", | 3095 "variables/params (currently set to %d).\n", |
| 2947 » xsltMaxDepth); | 3096 » ctxt->maxTemplateDepth); |
| 2948 xsltDebug(ctxt, contextNode, list, NULL); | 3097 xsltDebug(ctxt, contextNode, list, NULL); |
| 2949 return; | 3098 return; |
| 2950 } | 3099 } |
| 2951 | 3100 |
| 3101 if (ctxt->varsNr >= ctxt->maxTemplateVars) |
| 3102 { |
| 3103 xsltTransformError(ctxt, NULL, list, |
| 3104 "xsltApplyXSLTTemplate: A potential infinite template recursion " |
| 3105 "was detected.\n" |
| 3106 "You can adjust maxTemplateVars (--maxvars) in order to " |
| 3107 "raise the maximum number of variables/params (currently set to %d).
\n", |
| 3108 ctxt->maxTemplateVars); |
| 3109 xsltDebug(ctxt, contextNode, list, NULL); |
| 3110 return; |
| 3111 } |
| 3112 |
| 2952 oldUserFragmentTop = ctxt->tmpRVT; | 3113 oldUserFragmentTop = ctxt->tmpRVT; |
| 2953 ctxt->tmpRVT = NULL; | 3114 ctxt->tmpRVT = NULL; |
| 2954 oldLocalFragmentTop = ctxt->localRVT; | 3115 oldLocalFragmentTop = ctxt->localRVT; |
| 2955 | 3116 |
| 2956 /* | 3117 /* |
| 2957 * Initiate a distinct scope of local params/variables. | 3118 * Initiate a distinct scope of local params/variables. |
| 2958 */ | 3119 */ |
| 2959 oldVarsBase = ctxt->varsBase; | 3120 oldVarsBase = ctxt->varsBase; |
| 2960 ctxt->varsBase = ctxt->varsNr; | 3121 ctxt->varsBase = ctxt->varsNr; |
| 2961 | 3122 |
| 2962 ctxt->node = contextNode; | 3123 ctxt->node = contextNode; |
| 2963 if (ctxt->profile) { | 3124 if (ctxt->profile) { |
| 2964 templ->nbCalls++; | 3125 templ->nbCalls++; |
| 2965 start = xsltTimestamp(); | 3126 start = xsltTimestamp(); |
| 2966 profPush(ctxt, 0); | 3127 profPush(ctxt, 0); |
| 3128 profCallgraphAdd(templ, ctxt->templ); |
| 2967 } | 3129 } |
| 2968 /* | 3130 /* |
| 2969 * Push the xsl:template declaration onto the stack. | 3131 * Push the xsl:template declaration onto the stack. |
| 2970 */ | 3132 */ |
| 2971 templPush(ctxt, templ); | 3133 templPush(ctxt, templ); |
| 2972 | 3134 |
| 2973 #ifdef WITH_XSLT_DEBUG_PROCESS | 3135 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 2974 if (templ->name != NULL) | 3136 if (templ->name != NULL) |
| 2975 XSLT_TRACE(ctxt,XSLT_TRACE_APPLY_TEMPLATE,xsltGenericDebug(xsltGenericDe
bugContext, | 3137 XSLT_TRACE(ctxt,XSLT_TRACE_APPLY_TEMPLATE,xsltGenericDebug(xsltGenericDe
bugContext, |
| 2976 "applying xsl:template '%s'\n", templ->name)); | 3138 "applying xsl:template '%s'\n", templ->name)); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3223 xmlDocPtr oldOutput; | 3385 xmlDocPtr oldOutput; |
| 3224 xmlNodePtr oldInsert, root; | 3386 xmlNodePtr oldInsert, root; |
| 3225 const char *oldOutputFile; | 3387 const char *oldOutputFile; |
| 3226 xsltOutputType oldType; | 3388 xsltOutputType oldType; |
| 3227 xmlChar *URL = NULL; | 3389 xmlChar *URL = NULL; |
| 3228 const xmlChar *method; | 3390 const xmlChar *method; |
| 3229 const xmlChar *doctypePublic; | 3391 const xmlChar *doctypePublic; |
| 3230 const xmlChar *doctypeSystem; | 3392 const xmlChar *doctypeSystem; |
| 3231 const xmlChar *version; | 3393 const xmlChar *version; |
| 3232 const xmlChar *encoding; | 3394 const xmlChar *encoding; |
| 3395 int redirect_write_append = 0; |
| 3233 | 3396 |
| 3234 if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL)) | 3397 if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL)) |
| 3235 return; | 3398 return; |
| 3236 | 3399 |
| 3237 if (comp->filename == NULL) { | 3400 if (comp->filename == NULL) { |
| 3238 | 3401 |
| 3239 if (xmlStrEqual(inst->name, (const xmlChar *) "output")) { | 3402 if (xmlStrEqual(inst->name, (const xmlChar *) "output")) { |
| 3240 /* | 3403 /* |
| 3241 * The element "output" is in the namespace XSLT_SAXON_NAMESPACE | 3404 * The element "output" is in the namespace XSLT_SAXON_NAMESPACE |
| 3242 * (http://icl.com/saxon) | 3405 * (http://icl.com/saxon) |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3638 XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic) | 3801 XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic) |
| 3639 XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem) | 3802 XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem) |
| 3640 if (((doctypePublic != NULL) || (doctypeSystem != NULL))) | 3803 if (((doctypePublic != NULL) || (doctypeSystem != NULL))) |
| 3641 res->intSubset = xmlCreateIntSubset(res, doctype, | 3804 res->intSubset = xmlCreateIntSubset(res, doctype, |
| 3642 doctypePublic, | 3805 doctypePublic, |
| 3643 doctypeSystem); | 3806 doctypeSystem); |
| 3644 } | 3807 } |
| 3645 } | 3808 } |
| 3646 | 3809 |
| 3647 /* | 3810 /* |
| 3648 * Save the result | 3811 * Calls to redirect:write also take an optional attribute append. |
| 3812 * Attribute append="true|yes" which will attempt to simply append |
| 3813 * to an existing file instead of always opening a new file. The |
| 3814 * default behavior of always overwriting the file still happens |
| 3815 * if we do not specify append. |
| 3816 * Note that append use will forbid use of remote URI target. |
| 3649 */ | 3817 */ |
| 3650 ret = xsltSaveResultToFilename((const char *) filename, | 3818 prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"append", |
| 3651 res, style, 0); | 3819 » » » » NULL); |
| 3820 if (prop != NULL) { |
| 3821 » if (xmlStrEqual(prop, (const xmlChar *) "true") || |
| 3822 » xmlStrEqual(prop, (const xmlChar *) "yes")) { |
| 3823 » style->omitXmlDeclaration = 1; |
| 3824 » redirect_write_append = 1; |
| 3825 » } else |
| 3826 » style->omitXmlDeclaration = 0; |
| 3827 » xmlFree(prop); |
| 3828 } |
| 3829 |
| 3830 if (redirect_write_append) { |
| 3831 FILE *f; |
| 3832 |
| 3833 » f = fopen((const char *) filename, "ab"); |
| 3834 » if (f == NULL) { |
| 3835 » ret = -1; |
| 3836 » } else { |
| 3837 » ret = xsltSaveResultToFile(f, res, style); |
| 3838 » fclose(f); |
| 3839 » } |
| 3840 } else { |
| 3841 » ret = xsltSaveResultToFilename((const char *) filename, res, style, 0); |
| 3842 } |
| 3652 if (ret < 0) { | 3843 if (ret < 0) { |
| 3653 xsltTransformError(ctxt, NULL, inst, | 3844 xsltTransformError(ctxt, NULL, inst, |
| 3654 "xsltDocumentElem: unable to save to %s\n", | 3845 "xsltDocumentElem: unable to save to %s\n", |
| 3655 filename); | 3846 filename); |
| 3656 ctxt->state = XSLT_STATE_ERROR; | 3847 ctxt->state = XSLT_STATE_ERROR; |
| 3657 #ifdef WITH_XSLT_DEBUG_EXTRA | 3848 #ifdef WITH_XSLT_DEBUG_EXTRA |
| 3658 } else { | 3849 } else { |
| 3659 xsltGenericDebug(xsltGenericDebugContext, | 3850 xsltGenericDebug(xsltGenericDebugContext, |
| 3660 "Wrote %d bytes to %s\n", ret, filename); | 3851 "Wrote %d bytes to %s\n", ret, filename); |
| 3661 #endif | 3852 #endif |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3908 goto error; | 4099 goto error; |
| 3909 } | 4100 } |
| 3910 if (xmlValidateQName(prop, 0)) { | 4101 if (xmlValidateQName(prop, 0)) { |
| 3911 xsltTransformError(ctxt, NULL, inst, | 4102 xsltTransformError(ctxt, NULL, inst, |
| 3912 "xsl:element: The effective name '%s' is not a " | 4103 "xsl:element: The effective name '%s' is not a " |
| 3913 "valid QName.\n", prop); | 4104 "valid QName.\n", prop); |
| 3914 /* we fall through to catch any further errors, if possible */ | 4105 /* we fall through to catch any further errors, if possible */ |
| 3915 } | 4106 } |
| 3916 name = xsltSplitQName(ctxt->dict, prop, &prefix); | 4107 name = xsltSplitQName(ctxt->dict, prop, &prefix); |
| 3917 xmlFree(prop); | 4108 xmlFree(prop); |
| 3918 if ((prefix != NULL) && | |
| 3919 (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3))) | |
| 3920 { | |
| 3921 /* | |
| 3922 * TODO: Should we really disallow an "xml" prefix? | |
| 3923 */ | |
| 3924 goto error; | |
| 3925 } | |
| 3926 } else { | 4109 } else { |
| 3927 /* | 4110 /* |
| 3928 * The "name" value was static. | 4111 * The "name" value was static. |
| 3929 */ | 4112 */ |
| 3930 #ifdef XSLT_REFACTORED | 4113 #ifdef XSLT_REFACTORED |
| 3931 prefix = comp->nsPrefix; | 4114 prefix = comp->nsPrefix; |
| 3932 name = comp->name; | 4115 name = comp->name; |
| 3933 #else | 4116 #else |
| 3934 name = xsltSplitQName(ctxt->dict, comp->name, &prefix); | 4117 name = xsltSplitQName(ctxt->dict, comp->name, &prefix); |
| 3935 #endif | 4118 #endif |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3970 tmpNsName = xsltEvalAttrValueTemplate(ctxt, inst, | 4153 tmpNsName = xsltEvalAttrValueTemplate(ctxt, inst, |
| 3971 (const xmlChar *) "namespace", XSLT_NAMESPACE); | 4154 (const xmlChar *) "namespace", XSLT_NAMESPACE); |
| 3972 /* | 4155 /* |
| 3973 * SPEC XSLT 1.0: | 4156 * SPEC XSLT 1.0: |
| 3974 * "If the string is empty, then the expanded-name of the | 4157 * "If the string is empty, then the expanded-name of the |
| 3975 * attribute has a null namespace URI." | 4158 * attribute has a null namespace URI." |
| 3976 */ | 4159 */ |
| 3977 if ((tmpNsName != NULL) && (tmpNsName[0] != 0)) | 4160 if ((tmpNsName != NULL) && (tmpNsName[0] != 0)) |
| 3978 nsName = xmlDictLookup(ctxt->dict, BAD_CAST tmpNsName, -1); | 4161 nsName = xmlDictLookup(ctxt->dict, BAD_CAST tmpNsName, -1); |
| 3979 xmlFree(tmpNsName); | 4162 xmlFree(tmpNsName); |
| 3980 » }; | 4163 » } |
| 4164 |
| 4165 if (xmlStrEqual(nsName, BAD_CAST "http://www.w3.org/2000/xmlns/")) { |
| 4166 xsltTransformError(ctxt, NULL, inst, |
| 4167 "xsl:attribute: Namespace http://www.w3.org/2000/xmlns/ " |
| 4168 "forbidden.\n"); |
| 4169 goto error; |
| 4170 } |
| 4171 if (xmlStrEqual(nsName, XML_XML_NAMESPACE)) { |
| 4172 prefix = BAD_CAST "xml"; |
| 4173 } else if (xmlStrEqual(prefix, BAD_CAST "xml")) { |
| 4174 prefix = NULL; |
| 4175 } |
| 3981 } else { | 4176 } else { |
| 3982 xmlNsPtr ns; | 4177 xmlNsPtr ns; |
| 3983 /* | 4178 /* |
| 3984 * SPEC XSLT 1.0: | 4179 * SPEC XSLT 1.0: |
| 3985 * "If the namespace attribute is not present, then the QName is | 4180 * "If the namespace attribute is not present, then the QName is |
| 3986 * expanded into an expanded-name using the namespace declarations | 4181 * expanded into an expanded-name using the namespace declarations |
| 3987 * in effect for the xsl:element element, including any default | 4182 * in effect for the xsl:element element, including any default |
| 3988 * namespace declaration. | 4183 * namespace declaration. |
| 3989 */ | 4184 */ |
| 3990 ns = xmlSearchNs(inst->doc, inst, prefix); | 4185 ns = xmlSearchNs(inst->doc, inst, prefix); |
| 3991 if (ns == NULL) { | 4186 if (ns == NULL) { |
| 3992 /* | 4187 /* |
| 3993 * TODO: Check this in the compilation layer in case it's a | 4188 * TODO: Check this in the compilation layer in case it's a |
| 3994 * static value. | 4189 * static value. |
| 3995 */ | 4190 */ |
| 3996 » if (prefix != NULL) { | 4191 if (prefix != NULL) { |
| 3997 » » xsltTransformError(ctxt, NULL, inst, | 4192 xsltTransformError(ctxt, NULL, inst, |
| 3998 » » "xsl:element: The QName '%s:%s' has no " | 4193 "xsl:element: The QName '%s:%s' has no " |
| 3999 » » "namespace binding in scope in the stylesheet; " | 4194 "namespace binding in scope in the stylesheet; " |
| 4000 » » "this is an error, since the namespace was not " | 4195 "this is an error, since the namespace was not " |
| 4001 » » "specified by the instruction itself.\n", prefix, name); | 4196 "specified by the instruction itself.\n", prefix, name); |
| 4002 » } | 4197 } |
| 4003 } else | 4198 } else |
| 4004 nsName = ns->href; | 4199 nsName = ns->href; |
| 4005 } | 4200 } |
| 4006 /* | 4201 /* |
| 4007 * Find/create a matching ns-decl in the result tree. | 4202 * Find/create a matching ns-decl in the result tree. |
| 4008 */ | 4203 */ |
| 4009 if (nsName != NULL) { | 4204 if (nsName != NULL) { |
| 4010 » copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, prefix, copy); | 4205 » if (xmlStrEqual(prefix, BAD_CAST "xmlns")) { |
| 4206 /* Don't use a prefix of "xmlns" */ |
| 4207 » xmlChar *pref = xmlStrdup(BAD_CAST "ns_1"); |
| 4208 |
| 4209 » copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, pref, copy); |
| 4210 |
| 4211 » xmlFree(pref); |
| 4212 » } else { |
| 4213 » copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, prefix, |
| 4214 » » copy); |
| 4215 » } |
| 4011 } else if ((copy->parent != NULL) && | 4216 } else if ((copy->parent != NULL) && |
| 4012 (copy->parent->type == XML_ELEMENT_NODE) && | 4217 (copy->parent->type == XML_ELEMENT_NODE) && |
| 4013 (copy->parent->ns != NULL)) | 4218 (copy->parent->ns != NULL)) |
| 4014 { | 4219 { |
| 4015 /* | 4220 /* |
| 4016 * "Undeclare" the default namespace. | 4221 * "Undeclare" the default namespace. |
| 4017 */ | 4222 */ |
| 4018 xsltGetSpecialNamespace(ctxt, inst, NULL, NULL, copy); | 4223 xsltGetSpecialNamespace(ctxt, inst, NULL, NULL, copy); |
| 4019 } | 4224 } |
| 4020 | 4225 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4173 xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node, | 4378 xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node, |
| 4174 xmlNodePtr inst, xsltStylePreCompPtr castedComp) { | 4379 xmlNodePtr inst, xsltStylePreCompPtr castedComp) { |
| 4175 #ifdef XSLT_REFACTORED | 4380 #ifdef XSLT_REFACTORED |
| 4176 xsltStyleItemCopyOfPtr comp = (xsltStyleItemCopyOfPtr) castedComp; | 4381 xsltStyleItemCopyOfPtr comp = (xsltStyleItemCopyOfPtr) castedComp; |
| 4177 #else | 4382 #else |
| 4178 xsltStylePreCompPtr comp = castedComp; | 4383 xsltStylePreCompPtr comp = castedComp; |
| 4179 #endif | 4384 #endif |
| 4180 xmlXPathObjectPtr res = NULL; | 4385 xmlXPathObjectPtr res = NULL; |
| 4181 xmlNodeSetPtr list = NULL; | 4386 xmlNodeSetPtr list = NULL; |
| 4182 int i; | 4387 int i; |
| 4183 xmlDocPtr oldXPContextDoc; | |
| 4184 xmlNsPtr *oldXPNamespaces; | |
| 4185 xmlNodePtr oldXPContextNode; | |
| 4186 int oldXPProximityPosition, oldXPContextSize, oldXPNsNr; | |
| 4187 xmlXPathContextPtr xpctxt; | |
| 4188 | 4388 |
| 4189 if ((ctxt == NULL) || (node == NULL) || (inst == NULL)) | 4389 if ((ctxt == NULL) || (node == NULL) || (inst == NULL)) |
| 4190 return; | 4390 return; |
| 4191 if ((comp == NULL) || (comp->select == NULL) || (comp->comp == NULL)) { | 4391 if ((comp == NULL) || (comp->select == NULL) || (comp->comp == NULL)) { |
| 4192 xsltTransformError(ctxt, NULL, inst, | 4392 xsltTransformError(ctxt, NULL, inst, |
| 4193 "xsl:copy-of : compilation failed\n"); | 4393 "xsl:copy-of : compilation failed\n"); |
| 4194 return; | 4394 return; |
| 4195 } | 4395 } |
| 4196 | 4396 |
| 4197 /* | 4397 /* |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4213 */ | 4413 */ |
| 4214 | 4414 |
| 4215 #ifdef WITH_XSLT_DEBUG_PROCESS | 4415 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 4216 XSLT_TRACE(ctxt,XSLT_TRACE_COPY_OF,xsltGenericDebug(xsltGenericDebugContext, | 4416 XSLT_TRACE(ctxt,XSLT_TRACE_COPY_OF,xsltGenericDebug(xsltGenericDebugContext, |
| 4217 "xsltCopyOf: select %s\n", comp->select)); | 4417 "xsltCopyOf: select %s\n", comp->select)); |
| 4218 #endif | 4418 #endif |
| 4219 | 4419 |
| 4220 /* | 4420 /* |
| 4221 * Evaluate the "select" expression. | 4421 * Evaluate the "select" expression. |
| 4222 */ | 4422 */ |
| 4223 xpctxt = ctxt->xpathCtxt; | 4423 res = xsltPreCompEval(ctxt, node, comp); |
| 4224 oldXPContextDoc = xpctxt->doc; | |
| 4225 oldXPContextNode = xpctxt->node; | |
| 4226 oldXPProximityPosition = xpctxt->proximityPosition; | |
| 4227 oldXPContextSize = xpctxt->contextSize; | |
| 4228 oldXPNsNr = xpctxt->nsNr; | |
| 4229 oldXPNamespaces = xpctxt->namespaces; | |
| 4230 | |
| 4231 xpctxt->node = node; | |
| 4232 if (comp != NULL) { | |
| 4233 | |
| 4234 #ifdef XSLT_REFACTORED | |
| 4235 » if (comp->inScopeNs != NULL) { | |
| 4236 » xpctxt->namespaces = comp->inScopeNs->list; | |
| 4237 » xpctxt->nsNr = comp->inScopeNs->xpathNumber; | |
| 4238 » } else { | |
| 4239 » xpctxt->namespaces = NULL; | |
| 4240 » xpctxt->nsNr = 0; | |
| 4241 » } | |
| 4242 #else | |
| 4243 » xpctxt->namespaces = comp->nsList; | |
| 4244 » xpctxt->nsNr = comp->nsNr; | |
| 4245 #endif | |
| 4246 } else { | |
| 4247 » xpctxt->namespaces = NULL; | |
| 4248 » xpctxt->nsNr = 0; | |
| 4249 } | |
| 4250 | |
| 4251 res = xmlXPathCompiledEval(comp->comp, xpctxt); | |
| 4252 | |
| 4253 xpctxt->doc = oldXPContextDoc; | |
| 4254 xpctxt->node = oldXPContextNode; | |
| 4255 xpctxt->contextSize = oldXPContextSize; | |
| 4256 xpctxt->proximityPosition = oldXPProximityPosition; | |
| 4257 xpctxt->nsNr = oldXPNsNr; | |
| 4258 xpctxt->namespaces = oldXPNamespaces; | |
| 4259 | 4424 |
| 4260 if (res != NULL) { | 4425 if (res != NULL) { |
| 4261 if (res->type == XPATH_NODESET) { | 4426 if (res->type == XPATH_NODESET) { |
| 4262 /* | 4427 /* |
| 4263 * Node-set | 4428 * Node-set |
| 4264 * -------- | 4429 * -------- |
| 4265 */ | 4430 */ |
| 4266 #ifdef WITH_XSLT_DEBUG_PROCESS | 4431 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 4267 XSLT_TRACE(ctxt,XSLT_TRACE_COPY_OF,xsltGenericDebug(xsltGenericDebug
Context, | 4432 XSLT_TRACE(ctxt,XSLT_TRACE_COPY_OF,xsltGenericDebug(xsltGenericDebug
Context, |
| 4268 "xsltCopyOf: result is a node set\n")); | 4433 "xsltCopyOf: result is a node set\n")); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4357 void | 4522 void |
| 4358 xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node, | 4523 xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node, |
| 4359 xmlNodePtr inst, xsltStylePreCompPtr castedComp) | 4524 xmlNodePtr inst, xsltStylePreCompPtr castedComp) |
| 4360 { | 4525 { |
| 4361 #ifdef XSLT_REFACTORED | 4526 #ifdef XSLT_REFACTORED |
| 4362 xsltStyleItemValueOfPtr comp = (xsltStyleItemValueOfPtr) castedComp; | 4527 xsltStyleItemValueOfPtr comp = (xsltStyleItemValueOfPtr) castedComp; |
| 4363 #else | 4528 #else |
| 4364 xsltStylePreCompPtr comp = castedComp; | 4529 xsltStylePreCompPtr comp = castedComp; |
| 4365 #endif | 4530 #endif |
| 4366 xmlXPathObjectPtr res = NULL; | 4531 xmlXPathObjectPtr res = NULL; |
| 4367 xmlNodePtr copy = NULL; | |
| 4368 xmlChar *value = NULL; | 4532 xmlChar *value = NULL; |
| 4369 xmlDocPtr oldXPContextDoc; | |
| 4370 xmlNsPtr *oldXPNamespaces; | |
| 4371 xmlNodePtr oldXPContextNode; | |
| 4372 int oldXPProximityPosition, oldXPContextSize, oldXPNsNr; | |
| 4373 xmlXPathContextPtr xpctxt; | |
| 4374 | 4533 |
| 4375 if ((ctxt == NULL) || (node == NULL) || (inst == NULL)) | 4534 if ((ctxt == NULL) || (node == NULL) || (inst == NULL)) |
| 4376 return; | 4535 return; |
| 4377 | 4536 |
| 4378 if ((comp == NULL) || (comp->select == NULL) || (comp->comp == NULL)) { | 4537 if ((comp == NULL) || (comp->select == NULL) || (comp->comp == NULL)) { |
| 4379 xsltTransformError(ctxt, NULL, inst, | 4538 xsltTransformError(ctxt, NULL, inst, |
| 4380 "Internal error in xsltValueOf(): " | 4539 "Internal error in xsltValueOf(): " |
| 4381 "The XSLT 'value-of' instruction was not compiled.\n"); | 4540 "The XSLT 'value-of' instruction was not compiled.\n"); |
| 4382 return; | 4541 return; |
| 4383 } | 4542 } |
| 4384 | 4543 |
| 4385 #ifdef WITH_XSLT_DEBUG_PROCESS | 4544 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 4386 XSLT_TRACE(ctxt,XSLT_TRACE_VALUE_OF,xsltGenericDebug(xsltGenericDebugContext
, | 4545 XSLT_TRACE(ctxt,XSLT_TRACE_VALUE_OF,xsltGenericDebug(xsltGenericDebugContext
, |
| 4387 "xsltValueOf: select %s\n", comp->select)); | 4546 "xsltValueOf: select %s\n", comp->select)); |
| 4388 #endif | 4547 #endif |
| 4389 | 4548 |
| 4390 xpctxt = ctxt->xpathCtxt; | 4549 res = xsltPreCompEval(ctxt, node, comp); |
| 4391 oldXPContextDoc = xpctxt->doc; | |
| 4392 oldXPContextNode = xpctxt->node; | |
| 4393 oldXPProximityPosition = xpctxt->proximityPosition; | |
| 4394 oldXPContextSize = xpctxt->contextSize; | |
| 4395 oldXPNsNr = xpctxt->nsNr; | |
| 4396 oldXPNamespaces = xpctxt->namespaces; | |
| 4397 | |
| 4398 xpctxt->node = node; | |
| 4399 if (comp != NULL) { | |
| 4400 | |
| 4401 #ifdef XSLT_REFACTORED | |
| 4402 » if (comp->inScopeNs != NULL) { | |
| 4403 » xpctxt->namespaces = comp->inScopeNs->list; | |
| 4404 » xpctxt->nsNr = comp->inScopeNs->xpathNumber; | |
| 4405 » } else { | |
| 4406 » xpctxt->namespaces = NULL; | |
| 4407 » xpctxt->nsNr = 0; | |
| 4408 » } | |
| 4409 #else | |
| 4410 » xpctxt->namespaces = comp->nsList; | |
| 4411 » xpctxt->nsNr = comp->nsNr; | |
| 4412 #endif | |
| 4413 } else { | |
| 4414 » xpctxt->namespaces = NULL; | |
| 4415 » xpctxt->nsNr = 0; | |
| 4416 } | |
| 4417 | |
| 4418 res = xmlXPathCompiledEval(comp->comp, xpctxt); | |
| 4419 | |
| 4420 xpctxt->doc = oldXPContextDoc; | |
| 4421 xpctxt->node = oldXPContextNode; | |
| 4422 xpctxt->contextSize = oldXPContextSize; | |
| 4423 xpctxt->proximityPosition = oldXPProximityPosition; | |
| 4424 xpctxt->nsNr = oldXPNsNr; | |
| 4425 xpctxt->namespaces = oldXPNamespaces; | |
| 4426 | 4550 |
| 4427 /* | 4551 /* |
| 4428 * Cast the XPath object to string. | 4552 * Cast the XPath object to string. |
| 4429 */ | 4553 */ |
| 4430 if (res != NULL) { | 4554 if (res != NULL) { |
| 4431 value = xmlXPathCastToString(res); | 4555 value = xmlXPathCastToString(res); |
| 4432 if (value == NULL) { | 4556 if (value == NULL) { |
| 4433 xsltTransformError(ctxt, NULL, inst, | 4557 xsltTransformError(ctxt, NULL, inst, |
| 4434 "Internal error in xsltValueOf(): " | 4558 "Internal error in xsltValueOf(): " |
| 4435 "failed to cast an XPath object to string.\n"); | 4559 "failed to cast an XPath object to string.\n"); |
| 4436 ctxt->state = XSLT_STATE_STOPPED; | 4560 ctxt->state = XSLT_STATE_STOPPED; |
| 4437 goto error; | 4561 goto error; |
| 4438 } | 4562 } |
| 4439 if (value[0] != 0) { | 4563 if (value[0] != 0) { |
| 4440 » copy = xsltCopyTextString(ctxt, | 4564 » xsltCopyTextString(ctxt, ctxt->insert, value, comp->noescape); |
| 4441 » » ctxt->insert, value, comp->noescape); | |
| 4442 } | 4565 } |
| 4443 } else { | 4566 } else { |
| 4444 xsltTransformError(ctxt, NULL, inst, | 4567 xsltTransformError(ctxt, NULL, inst, |
| 4445 "XPath evaluation returned no result.\n"); | 4568 "XPath evaluation returned no result.\n"); |
| 4446 ctxt->state = XSLT_STATE_STOPPED; | 4569 ctxt->state = XSLT_STATE_STOPPED; |
| 4447 goto error; | 4570 goto error; |
| 4448 } | 4571 } |
| 4449 | 4572 |
| 4450 #ifdef WITH_XSLT_DEBUG_PROCESS | 4573 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 4451 if (value) { | 4574 if (value) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4472 */ | 4595 */ |
| 4473 void | 4596 void |
| 4474 xsltNumber(xsltTransformContextPtr ctxt, xmlNodePtr node, | 4597 xsltNumber(xsltTransformContextPtr ctxt, xmlNodePtr node, |
| 4475 xmlNodePtr inst, xsltStylePreCompPtr castedComp) | 4598 xmlNodePtr inst, xsltStylePreCompPtr castedComp) |
| 4476 { | 4599 { |
| 4477 #ifdef XSLT_REFACTORED | 4600 #ifdef XSLT_REFACTORED |
| 4478 xsltStyleItemNumberPtr comp = (xsltStyleItemNumberPtr) castedComp; | 4601 xsltStyleItemNumberPtr comp = (xsltStyleItemNumberPtr) castedComp; |
| 4479 #else | 4602 #else |
| 4480 xsltStylePreCompPtr comp = castedComp; | 4603 xsltStylePreCompPtr comp = castedComp; |
| 4481 #endif | 4604 #endif |
| 4605 xmlXPathContextPtr xpctxt; |
| 4606 xmlNsPtr *oldXPNamespaces; |
| 4607 int oldXPNsNr; |
| 4608 |
| 4482 if (comp == NULL) { | 4609 if (comp == NULL) { |
| 4483 xsltTransformError(ctxt, NULL, inst, | 4610 xsltTransformError(ctxt, NULL, inst, |
| 4484 "xsl:number : compilation failed\n"); | 4611 "xsl:number : compilation failed\n"); |
| 4485 return; | 4612 return; |
| 4486 } | 4613 } |
| 4487 | 4614 |
| 4488 if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL)) | 4615 if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL)) |
| 4489 return; | 4616 return; |
| 4490 | 4617 |
| 4491 comp->numdata.doc = inst->doc; | 4618 comp->numdata.doc = inst->doc; |
| 4492 comp->numdata.node = inst; | 4619 comp->numdata.node = inst; |
| 4493 | 4620 |
| 4621 xpctxt = ctxt->xpathCtxt; |
| 4622 oldXPNsNr = xpctxt->nsNr; |
| 4623 oldXPNamespaces = xpctxt->namespaces; |
| 4624 |
| 4625 #ifdef XSLT_REFACTORED |
| 4626 if (comp->inScopeNs != NULL) { |
| 4627 xpctxt->namespaces = comp->inScopeNs->list; |
| 4628 xpctxt->nsNr = comp->inScopeNs->xpathNumber; |
| 4629 } else { |
| 4630 xpctxt->namespaces = NULL; |
| 4631 xpctxt->nsNr = 0; |
| 4632 } |
| 4633 #else |
| 4634 xpctxt->namespaces = comp->nsList; |
| 4635 xpctxt->nsNr = comp->nsNr; |
| 4636 #endif |
| 4637 |
| 4494 xsltNumberFormat(ctxt, &comp->numdata, node); | 4638 xsltNumberFormat(ctxt, &comp->numdata, node); |
| 4639 |
| 4640 xpctxt->nsNr = oldXPNsNr; |
| 4641 xpctxt->namespaces = oldXPNamespaces; |
| 4495 } | 4642 } |
| 4496 | 4643 |
| 4497 /** | 4644 /** |
| 4498 * xsltApplyImports: | 4645 * xsltApplyImports: |
| 4499 * @ctxt: an XSLT transformation context | 4646 * @ctxt: an XSLT transformation context |
| 4500 * @contextNode: the current node in the source tree. | 4647 * @contextNode: the current node in the source tree. |
| 4501 * @inst: the element node of the XSLT 'apply-imports' instruction | 4648 * @inst: the element node of the XSLT 'apply-imports' instruction |
| 4502 * @comp: the compiled instruction | 4649 * @comp: the compiled instruction |
| 4503 * | 4650 * |
| 4504 * Process the XSLT apply-imports element. | 4651 * Process the XSLT apply-imports element. |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4678 #ifdef XSLT_REFACTORED | 4825 #ifdef XSLT_REFACTORED |
| 4679 xsltStyleItemApplyTemplatesPtr comp = | 4826 xsltStyleItemApplyTemplatesPtr comp = |
| 4680 (xsltStyleItemApplyTemplatesPtr) castedComp; | 4827 (xsltStyleItemApplyTemplatesPtr) castedComp; |
| 4681 #else | 4828 #else |
| 4682 xsltStylePreCompPtr comp = castedComp; | 4829 xsltStylePreCompPtr comp = castedComp; |
| 4683 #endif | 4830 #endif |
| 4684 int i; | 4831 int i; |
| 4685 xmlNodePtr cur, delNode = NULL, oldContextNode; | 4832 xmlNodePtr cur, delNode = NULL, oldContextNode; |
| 4686 xmlNodeSetPtr list = NULL, oldList; | 4833 xmlNodeSetPtr list = NULL, oldList; |
| 4687 xsltStackElemPtr withParams = NULL; | 4834 xsltStackElemPtr withParams = NULL; |
| 4688 int oldXPProximityPosition, oldXPContextSize, oldXPNsNr; | 4835 int oldXPProximityPosition, oldXPContextSize; |
| 4689 const xmlChar *oldMode, *oldModeURI; | 4836 const xmlChar *oldMode, *oldModeURI; |
| 4690 xmlDocPtr oldXPDoc; | 4837 xmlDocPtr oldXPDoc; |
| 4691 xsltDocumentPtr oldDocInfo; | 4838 xsltDocumentPtr oldDocInfo; |
| 4692 xmlXPathContextPtr xpctxt; | 4839 xmlXPathContextPtr xpctxt; |
| 4693 xmlNsPtr *oldXPNamespaces; | |
| 4694 | 4840 |
| 4695 if (comp == NULL) { | 4841 if (comp == NULL) { |
| 4696 xsltTransformError(ctxt, NULL, inst, | 4842 xsltTransformError(ctxt, NULL, inst, |
| 4697 "xsl:apply-templates : compilation failed\n"); | 4843 "xsl:apply-templates : compilation failed\n"); |
| 4698 return; | 4844 return; |
| 4699 } | 4845 } |
| 4700 if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL)) | 4846 if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL)) |
| 4701 return; | 4847 return; |
| 4702 | 4848 |
| 4703 #ifdef WITH_XSLT_DEBUG_PROCESS | 4849 #ifdef WITH_XSLT_DEBUG_PROCESS |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4717 oldList = ctxt->nodeList; | 4863 oldList = ctxt->nodeList; |
| 4718 | 4864 |
| 4719 /* | 4865 /* |
| 4720 * The xpath context size and proximity position, as | 4866 * The xpath context size and proximity position, as |
| 4721 * well as the xpath and context documents, may be changed | 4867 * well as the xpath and context documents, may be changed |
| 4722 * so we save their initial state and will restore on exit | 4868 * so we save their initial state and will restore on exit |
| 4723 */ | 4869 */ |
| 4724 oldXPContextSize = xpctxt->contextSize; | 4870 oldXPContextSize = xpctxt->contextSize; |
| 4725 oldXPProximityPosition = xpctxt->proximityPosition; | 4871 oldXPProximityPosition = xpctxt->proximityPosition; |
| 4726 oldXPDoc = xpctxt->doc; | 4872 oldXPDoc = xpctxt->doc; |
| 4727 oldXPNsNr = xpctxt->nsNr; | |
| 4728 oldXPNamespaces = xpctxt->namespaces; | |
| 4729 | 4873 |
| 4730 /* | 4874 /* |
| 4731 * Set up contexts. | 4875 * Set up contexts. |
| 4732 */ | 4876 */ |
| 4733 ctxt->mode = comp->mode; | 4877 ctxt->mode = comp->mode; |
| 4734 ctxt->modeURI = comp->modeURI; | 4878 ctxt->modeURI = comp->modeURI; |
| 4735 | 4879 |
| 4736 if (comp->select != NULL) { | 4880 if (comp->select != NULL) { |
| 4737 xmlXPathObjectPtr res = NULL; | 4881 xmlXPathObjectPtr res = NULL; |
| 4738 | 4882 |
| 4739 if (comp->comp == NULL) { | 4883 if (comp->comp == NULL) { |
| 4740 xsltTransformError(ctxt, NULL, inst, | 4884 xsltTransformError(ctxt, NULL, inst, |
| 4741 "xsl:apply-templates : compilation failed\n"); | 4885 "xsl:apply-templates : compilation failed\n"); |
| 4742 goto error; | 4886 goto error; |
| 4743 } | 4887 } |
| 4744 #ifdef WITH_XSLT_DEBUG_PROCESS | 4888 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 4745 XSLT_TRACE(ctxt,XSLT_TRACE_APPLY_TEMPLATES,xsltGenericDebug(xsltGenericD
ebugContext, | 4889 XSLT_TRACE(ctxt,XSLT_TRACE_APPLY_TEMPLATES,xsltGenericDebug(xsltGenericD
ebugContext, |
| 4746 "xsltApplyTemplates: select %s\n", comp->select)); | 4890 "xsltApplyTemplates: select %s\n", comp->select)); |
| 4747 #endif | 4891 #endif |
| 4748 | 4892 |
| 4749 » /* | 4893 » res = xsltPreCompEval(ctxt, node, comp); |
| 4750 » * Set up XPath. | |
| 4751 » */ | |
| 4752 » xpctxt->node = node; /* Set the "context node" */ | |
| 4753 #ifdef XSLT_REFACTORED | |
| 4754 » if (comp->inScopeNs != NULL) { | |
| 4755 » xpctxt->namespaces = comp->inScopeNs->list; | |
| 4756 » xpctxt->nsNr = comp->inScopeNs->xpathNumber; | |
| 4757 » } else { | |
| 4758 » xpctxt->namespaces = NULL; | |
| 4759 » xpctxt->nsNr = 0; | |
| 4760 » } | |
| 4761 #else | |
| 4762 » xpctxt->namespaces = comp->nsList; | |
| 4763 » xpctxt->nsNr = comp->nsNr; | |
| 4764 #endif | |
| 4765 » res = xmlXPathCompiledEval(comp->comp, xpctxt); | |
| 4766 | 4894 |
| 4767 xpctxt->contextSize = oldXPContextSize; | |
| 4768 xpctxt->proximityPosition = oldXPProximityPosition; | |
| 4769 if (res != NULL) { | 4895 if (res != NULL) { |
| 4770 if (res->type == XPATH_NODESET) { | 4896 if (res->type == XPATH_NODESET) { |
| 4771 list = res->nodesetval; /* consume the node set */ | 4897 list = res->nodesetval; /* consume the node set */ |
| 4772 res->nodesetval = NULL; | 4898 res->nodesetval = NULL; |
| 4773 } else { | 4899 } else { |
| 4774 xsltTransformError(ctxt, NULL, inst, | 4900 xsltTransformError(ctxt, NULL, inst, |
| 4775 "The 'select' expression did not evaluate to a " | 4901 "The 'select' expression did not evaluate to a " |
| 4776 "node set.\n"); | 4902 "node set.\n"); |
| 4777 ctxt->state = XSLT_STATE_STOPPED; | 4903 ctxt->state = XSLT_STATE_STOPPED; |
| 4778 xmlXPathFreeObject(res); | 4904 xmlXPathFreeObject(res); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4825 effectiveDocInfo = list->nodeTab[0]->doc->_private; | 4951 effectiveDocInfo = list->nodeTab[0]->doc->_private; |
| 4826 } | 4952 } |
| 4827 #endif | 4953 #endif |
| 4828 } else { | 4954 } else { |
| 4829 /* | 4955 /* |
| 4830 * Build an XPath node set with the children | 4956 * Build an XPath node set with the children |
| 4831 */ | 4957 */ |
| 4832 list = xmlXPathNodeSetCreate(NULL); | 4958 list = xmlXPathNodeSetCreate(NULL); |
| 4833 if (list == NULL) | 4959 if (list == NULL) |
| 4834 goto error; | 4960 goto error; |
| 4835 » cur = node->children; | 4961 » if (node->type != XML_NAMESPACE_DECL) |
| 4962 » cur = node->children; |
| 4963 » else |
| 4964 » cur = NULL; |
| 4836 while (cur != NULL) { | 4965 while (cur != NULL) { |
| 4837 switch (cur->type) { | 4966 switch (cur->type) { |
| 4838 case XML_TEXT_NODE: | 4967 case XML_TEXT_NODE: |
| 4839 if ((IS_BLANK_NODE(cur)) && | 4968 if ((IS_BLANK_NODE(cur)) && |
| 4840 (cur->parent != NULL) && | 4969 (cur->parent != NULL) && |
| 4841 (cur->parent->type == XML_ELEMENT_NODE) && | 4970 (cur->parent->type == XML_ELEMENT_NODE) && |
| 4842 (ctxt->style->stripSpaces != NULL)) { | 4971 (ctxt->style->stripSpaces != NULL)) { |
| 4843 const xmlChar *val; | 4972 const xmlChar *val; |
| 4844 | 4973 |
| 4845 if (cur->parent->ns != NULL) { | 4974 if (cur->parent->ns != NULL) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4874 xmlXPathNodeSetAddUnique(list, cur); | 5003 xmlXPathNodeSetAddUnique(list, cur); |
| 4875 break; | 5004 break; |
| 4876 case XML_DTD_NODE: | 5005 case XML_DTD_NODE: |
| 4877 /* Unlink the DTD, it's still reachable | 5006 /* Unlink the DTD, it's still reachable |
| 4878 * using doc->intSubset */ | 5007 * using doc->intSubset */ |
| 4879 if (cur->next != NULL) | 5008 if (cur->next != NULL) |
| 4880 cur->next->prev = cur->prev; | 5009 cur->next->prev = cur->prev; |
| 4881 if (cur->prev != NULL) | 5010 if (cur->prev != NULL) |
| 4882 cur->prev->next = cur->next; | 5011 cur->prev->next = cur->next; |
| 4883 break; | 5012 break; |
| 5013 case XML_NAMESPACE_DECL: |
| 5014 break; |
| 4884 default: | 5015 default: |
| 4885 #ifdef WITH_XSLT_DEBUG_PROCESS | 5016 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 4886 XSLT_TRACE(ctxt,XSLT_TRACE_APPLY_TEMPLATES,xsltGenericDebug(
xsltGenericDebugContext, | 5017 XSLT_TRACE(ctxt,XSLT_TRACE_APPLY_TEMPLATES,xsltGenericDebug(
xsltGenericDebugContext, |
| 4887 "xsltApplyTemplates: skipping cur type %d\n", | 5018 "xsltApplyTemplates: skipping cur type %d\n", |
| 4888 cur->type)); | 5019 cur->type)); |
| 4889 #endif | 5020 #endif |
| 4890 delNode = cur; | 5021 delNode = cur; |
| 4891 } | 5022 } |
| 4892 cur = cur->next; | 5023 cur = cur->next; |
| 4893 if (delNode != NULL) { | 5024 if (delNode != NULL) { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5036 /* | 5167 /* |
| 5037 * Free the parameter list. | 5168 * Free the parameter list. |
| 5038 */ | 5169 */ |
| 5039 if (withParams != NULL) | 5170 if (withParams != NULL) |
| 5040 xsltFreeStackElemList(withParams); | 5171 xsltFreeStackElemList(withParams); |
| 5041 if (list != NULL) | 5172 if (list != NULL) |
| 5042 xmlXPathFreeNodeSet(list); | 5173 xmlXPathFreeNodeSet(list); |
| 5043 /* | 5174 /* |
| 5044 * Restore context states. | 5175 * Restore context states. |
| 5045 */ | 5176 */ |
| 5046 xpctxt->nsNr = oldXPNsNr; | |
| 5047 xpctxt->namespaces = oldXPNamespaces; | |
| 5048 xpctxt->doc = oldXPDoc; | 5177 xpctxt->doc = oldXPDoc; |
| 5049 xpctxt->contextSize = oldXPContextSize; | 5178 xpctxt->contextSize = oldXPContextSize; |
| 5050 xpctxt->proximityPosition = oldXPProximityPosition; | 5179 xpctxt->proximityPosition = oldXPProximityPosition; |
| 5051 | 5180 |
| 5052 ctxt->document = oldDocInfo; | 5181 ctxt->document = oldDocInfo; |
| 5053 ctxt->nodeList = oldList; | 5182 ctxt->nodeList = oldList; |
| 5054 ctxt->node = oldContextNode; | 5183 ctxt->node = oldContextNode; |
| 5055 ctxt->mode = oldMode; | 5184 ctxt->mode = oldMode; |
| 5056 ctxt->modeURI = oldModeURI; | 5185 ctxt->modeURI = oldModeURI; |
| 5057 } | 5186 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5093 #else | 5222 #else |
| 5094 if ((! IS_XSLT_ELEM(cur)) || (! IS_XSLT_NAME(cur, "when"))) { | 5223 if ((! IS_XSLT_ELEM(cur)) || (! IS_XSLT_NAME(cur, "when"))) { |
| 5095 xsltTransformError(ctxt, NULL, inst, | 5224 xsltTransformError(ctxt, NULL, inst, |
| 5096 "xsl:choose: xsl:when expected first\n"); | 5225 "xsl:choose: xsl:when expected first\n"); |
| 5097 return; | 5226 return; |
| 5098 } | 5227 } |
| 5099 #endif | 5228 #endif |
| 5100 | 5229 |
| 5101 { | 5230 { |
| 5102 int testRes = 0, res = 0; | 5231 int testRes = 0, res = 0; |
| 5103 xmlXPathContextPtr xpctxt = ctxt->xpathCtxt; | |
| 5104 xmlDocPtr oldXPContextDoc = xpctxt->doc; | |
| 5105 int oldXPProximityPosition = xpctxt->proximityPosition; | |
| 5106 int oldXPContextSize = xpctxt->contextSize; | |
| 5107 xmlNsPtr *oldXPNamespaces = xpctxt->namespaces; | |
| 5108 int oldXPNsNr = xpctxt->nsNr; | |
| 5109 | 5232 |
| 5110 #ifdef XSLT_REFACTORED | 5233 #ifdef XSLT_REFACTORED |
| 5111 xsltStyleItemWhenPtr wcomp = NULL; | 5234 xsltStyleItemWhenPtr wcomp = NULL; |
| 5112 #else | 5235 #else |
| 5113 xsltStylePreCompPtr wcomp = NULL; | 5236 xsltStylePreCompPtr wcomp = NULL; |
| 5114 #endif | 5237 #endif |
| 5115 | 5238 |
| 5116 /* | 5239 /* |
| 5117 * Process xsl:when --------------------------------------------------- | 5240 * Process xsl:when --------------------------------------------------- |
| 5118 */ | 5241 */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 5135 * TODO: Isn't comp->templ always NULL for xsl:choose? | 5258 * TODO: Isn't comp->templ always NULL for xsl:choose? |
| 5136 */ | 5259 */ |
| 5137 xslHandleDebugger(cur, contextNode, NULL, ctxt); | 5260 xslHandleDebugger(cur, contextNode, NULL, ctxt); |
| 5138 } | 5261 } |
| 5139 #endif | 5262 #endif |
| 5140 #ifdef WITH_XSLT_DEBUG_PROCESS | 5263 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 5141 XSLT_TRACE(ctxt,XSLT_TRACE_CHOOSE,xsltGenericDebug(xsltGenericDebugC
ontext, | 5264 XSLT_TRACE(ctxt,XSLT_TRACE_CHOOSE,xsltGenericDebug(xsltGenericDebugC
ontext, |
| 5142 "xsltChoose: test %s\n", wcomp->test)); | 5265 "xsltChoose: test %s\n", wcomp->test)); |
| 5143 #endif | 5266 #endif |
| 5144 | 5267 |
| 5145 xpctxt->node = contextNode; | |
| 5146 xpctxt->doc = oldXPContextDoc; | |
| 5147 xpctxt->proximityPosition = oldXPProximityPosition; | |
| 5148 xpctxt->contextSize = oldXPContextSize; | |
| 5149 | |
| 5150 #ifdef XSLT_REFACTORED | |
| 5151 if (wcomp->inScopeNs != NULL) { | |
| 5152 xpctxt->namespaces = wcomp->inScopeNs->list; | |
| 5153 xpctxt->nsNr = wcomp->inScopeNs->xpathNumber; | |
| 5154 } else { | |
| 5155 xpctxt->namespaces = NULL; | |
| 5156 xpctxt->nsNr = 0; | |
| 5157 } | |
| 5158 #else | |
| 5159 xpctxt->namespaces = wcomp->nsList; | |
| 5160 xpctxt->nsNr = wcomp->nsNr; | |
| 5161 #endif | |
| 5162 | |
| 5163 | |
| 5164 #ifdef XSLT_FAST_IF | 5268 #ifdef XSLT_FAST_IF |
| 5165 » res = xmlXPathCompiledEvalToBoolean(wcomp->comp, xpctxt); | 5269 » res = xsltPreCompEvalToBoolean(ctxt, contextNode, wcomp); |
| 5166 | 5270 |
| 5167 if (res == -1) { | 5271 if (res == -1) { |
| 5168 ctxt->state = XSLT_STATE_STOPPED; | 5272 ctxt->state = XSLT_STATE_STOPPED; |
| 5169 goto error; | 5273 goto error; |
| 5170 } | 5274 } |
| 5171 testRes = (res == 1) ? 1 : 0; | 5275 testRes = (res == 1) ? 1 : 0; |
| 5172 | 5276 |
| 5173 #else /* XSLT_FAST_IF */ | 5277 #else /* XSLT_FAST_IF */ |
| 5174 | 5278 |
| 5175 » res = xmlXPathCompiledEval(wcomp->comp, xpctxt); | 5279 » res = xsltPreCompEval(ctxt, cotextNode, wcomp); |
| 5176 | 5280 |
| 5177 if (res != NULL) { | 5281 if (res != NULL) { |
| 5178 if (res->type != XPATH_BOOLEAN) | 5282 if (res->type != XPATH_BOOLEAN) |
| 5179 res = xmlXPathConvertBoolean(res); | 5283 res = xmlXPathConvertBoolean(res); |
| 5180 if (res->type == XPATH_BOOLEAN) | 5284 if (res->type == XPATH_BOOLEAN) |
| 5181 testRes = res->boolval; | 5285 testRes = res->boolval; |
| 5182 else { | 5286 else { |
| 5183 #ifdef WITH_XSLT_DEBUG_PROCESS | 5287 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 5184 XSLT_TRACE(ctxt,XSLT_TRACE_CHOOSE,xsltGenericDebug(xsltGener
icDebugContext, | 5288 XSLT_TRACE(ctxt,XSLT_TRACE_CHOOSE,xsltGenericDebug(xsltGener
icDebugContext, |
| 5185 "xsltChoose: test didn't evaluate to a boolean\n")); | 5289 "xsltChoose: test didn't evaluate to a boolean\n")); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 5214 if (xslDebugStatus != XSLT_DEBUG_NONE) | 5318 if (xslDebugStatus != XSLT_DEBUG_NONE) |
| 5215 xslHandleDebugger(cur, contextNode, NULL, ctxt); | 5319 xslHandleDebugger(cur, contextNode, NULL, ctxt); |
| 5216 #endif | 5320 #endif |
| 5217 | 5321 |
| 5218 #ifdef WITH_XSLT_DEBUG_PROCESS | 5322 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 5219 XSLT_TRACE(ctxt,XSLT_TRACE_CHOOSE,xsltGenericDebug(xsltGenericDebugC
ontext, | 5323 XSLT_TRACE(ctxt,XSLT_TRACE_CHOOSE,xsltGenericDebug(xsltGenericDebugC
ontext, |
| 5220 "evaluating xsl:otherwise\n")); | 5324 "evaluating xsl:otherwise\n")); |
| 5221 #endif | 5325 #endif |
| 5222 goto test_is_true; | 5326 goto test_is_true; |
| 5223 } | 5327 } |
| 5224 xpctxt->node = contextNode; | |
| 5225 xpctxt->doc = oldXPContextDoc; | |
| 5226 xpctxt->proximityPosition = oldXPProximityPosition; | |
| 5227 xpctxt->contextSize = oldXPContextSize; | |
| 5228 xpctxt->namespaces = oldXPNamespaces; | |
| 5229 xpctxt->nsNr = oldXPNsNr; | |
| 5230 goto exit; | 5328 goto exit; |
| 5231 | 5329 |
| 5232 test_is_true: | 5330 test_is_true: |
| 5233 | 5331 |
| 5234 xpctxt->node = contextNode; | |
| 5235 xpctxt->doc = oldXPContextDoc; | |
| 5236 xpctxt->proximityPosition = oldXPProximityPosition; | |
| 5237 xpctxt->contextSize = oldXPContextSize; | |
| 5238 xpctxt->namespaces = oldXPNamespaces; | |
| 5239 xpctxt->nsNr = oldXPNsNr; | |
| 5240 goto process_sequence; | 5332 goto process_sequence; |
| 5241 } | 5333 } |
| 5242 | 5334 |
| 5243 process_sequence: | 5335 process_sequence: |
| 5244 | 5336 |
| 5245 /* | 5337 /* |
| 5246 * Instantiate the sequence constructor. | 5338 * Instantiate the sequence constructor. |
| 5247 */ | 5339 */ |
| 5248 xsltApplySequenceConstructor(ctxt, ctxt->node, cur->children, | 5340 xsltApplySequenceConstructor(ctxt, ctxt->node, cur->children, |
| 5249 NULL); | 5341 NULL); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5283 return; | 5375 return; |
| 5284 } | 5376 } |
| 5285 | 5377 |
| 5286 #ifdef WITH_XSLT_DEBUG_PROCESS | 5378 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 5287 XSLT_TRACE(ctxt,XSLT_TRACE_IF,xsltGenericDebug(xsltGenericDebugContext, | 5379 XSLT_TRACE(ctxt,XSLT_TRACE_IF,xsltGenericDebug(xsltGenericDebugContext, |
| 5288 "xsltIf: test %s\n", comp->test)); | 5380 "xsltIf: test %s\n", comp->test)); |
| 5289 #endif | 5381 #endif |
| 5290 | 5382 |
| 5291 #ifdef XSLT_FAST_IF | 5383 #ifdef XSLT_FAST_IF |
| 5292 { | 5384 { |
| 5293 xmlXPathContextPtr xpctxt = ctxt->xpathCtxt; | |
| 5294 xmlDocPtr oldXPContextDoc = xpctxt->doc; | |
| 5295 xmlNsPtr *oldXPNamespaces = xpctxt->namespaces; | |
| 5296 xmlNodePtr oldXPContextNode = xpctxt->node; | |
| 5297 int oldXPProximityPosition = xpctxt->proximityPosition; | |
| 5298 int oldXPContextSize = xpctxt->contextSize; | |
| 5299 int oldXPNsNr = xpctxt->nsNr; | |
| 5300 xmlDocPtr oldLocalFragmentTop = ctxt->localRVT; | 5385 xmlDocPtr oldLocalFragmentTop = ctxt->localRVT; |
| 5301 | 5386 |
| 5302 » xpctxt->node = contextNode; | 5387 » res = xsltPreCompEvalToBoolean(ctxt, contextNode, comp); |
| 5303 » if (comp != NULL) { | |
| 5304 | |
| 5305 #ifdef XSLT_REFACTORED | |
| 5306 » if (comp->inScopeNs != NULL) { | |
| 5307 » » xpctxt->namespaces = comp->inScopeNs->list; | |
| 5308 » » xpctxt->nsNr = comp->inScopeNs->xpathNumber; | |
| 5309 » } else { | |
| 5310 » » xpctxt->namespaces = NULL; | |
| 5311 » » xpctxt->nsNr = 0; | |
| 5312 » } | |
| 5313 #else | |
| 5314 » xpctxt->namespaces = comp->nsList; | |
| 5315 » xpctxt->nsNr = comp->nsNr; | |
| 5316 #endif | |
| 5317 » } else { | |
| 5318 » xpctxt->namespaces = NULL; | |
| 5319 » xpctxt->nsNr = 0; | |
| 5320 » } | |
| 5321 » /* | |
| 5322 » * This XPath function is optimized for boolean results. | |
| 5323 » */ | |
| 5324 » res = xmlXPathCompiledEvalToBoolean(comp->comp, xpctxt); | |
| 5325 | 5388 |
| 5326 /* | 5389 /* |
| 5327 * Cleanup fragments created during evaluation of the | 5390 * Cleanup fragments created during evaluation of the |
| 5328 * "select" expression. | 5391 * "select" expression. |
| 5329 */ | 5392 */ |
| 5330 if (oldLocalFragmentTop != ctxt->localRVT) | 5393 if (oldLocalFragmentTop != ctxt->localRVT) |
| 5331 xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop); | 5394 xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop); |
| 5332 | |
| 5333 xpctxt->doc = oldXPContextDoc; | |
| 5334 xpctxt->node = oldXPContextNode; | |
| 5335 xpctxt->contextSize = oldXPContextSize; | |
| 5336 xpctxt->proximityPosition = oldXPProximityPosition; | |
| 5337 xpctxt->nsNr = oldXPNsNr; | |
| 5338 xpctxt->namespaces = oldXPNamespaces; | |
| 5339 } | 5395 } |
| 5340 | 5396 |
| 5341 #ifdef WITH_XSLT_DEBUG_PROCESS | 5397 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 5342 XSLT_TRACE(ctxt,XSLT_TRACE_IF,xsltGenericDebug(xsltGenericDebugContext, | 5398 XSLT_TRACE(ctxt,XSLT_TRACE_IF,xsltGenericDebug(xsltGenericDebugContext, |
| 5343 "xsltIf: test evaluate to %d\n", res)); | 5399 "xsltIf: test evaluate to %d\n", res)); |
| 5344 #endif | 5400 #endif |
| 5345 | 5401 |
| 5346 if (res == -1) { | 5402 if (res == -1) { |
| 5347 ctxt->state = XSLT_STATE_STOPPED; | 5403 ctxt->state = XSLT_STATE_STOPPED; |
| 5348 goto error; | 5404 goto error; |
| 5349 } | 5405 } |
| 5350 if (res == 1) { | 5406 if (res == 1) { |
| 5351 /* | 5407 /* |
| 5352 * Instantiate the sequence constructor of xsl:if. | 5408 * Instantiate the sequence constructor of xsl:if. |
| 5353 */ | 5409 */ |
| 5354 xsltApplySequenceConstructor(ctxt, | 5410 xsltApplySequenceConstructor(ctxt, |
| 5355 contextNode, inst->children, NULL); | 5411 contextNode, inst->children, NULL); |
| 5356 } | 5412 } |
| 5357 | 5413 |
| 5358 #else /* XSLT_FAST_IF */ | 5414 #else /* XSLT_FAST_IF */ |
| 5359 { | 5415 { |
| 5360 xmlXPathObjectPtr xpobj = NULL; | |
| 5361 /* | 5416 /* |
| 5362 * OLD CODE: | 5417 * OLD CODE: |
| 5363 */ | 5418 */ |
| 5364 » { | 5419 » xmlXPathObjectPtr xpobj = xsltPreCompEval(ctxt, contextNode, comp); |
| 5365 » xmlXPathContextPtr xpctxt = ctxt->xpathCtxt; | |
| 5366 » xmlDocPtr oldXPContextDoc = xpctxt->doc; | |
| 5367 » xmlNsPtr *oldXPNamespaces = xpctxt->namespaces; | |
| 5368 » xmlNodePtr oldXPContextNode = xpctxt->node; | |
| 5369 » int oldXPProximityPosition = xpctxt->proximityPosition; | |
| 5370 » int oldXPContextSize = xpctxt->contextSize; | |
| 5371 » int oldXPNsNr = xpctxt->nsNr; | |
| 5372 | |
| 5373 » xpctxt->node = contextNode; | |
| 5374 » if (comp != NULL) { | |
| 5375 | |
| 5376 #ifdef XSLT_REFACTORED | |
| 5377 » » if (comp->inScopeNs != NULL) { | |
| 5378 » » xpctxt->namespaces = comp->inScopeNs->list; | |
| 5379 » » xpctxt->nsNr = comp->inScopeNs->xpathNumber; | |
| 5380 » » } else { | |
| 5381 » » xpctxt->namespaces = NULL; | |
| 5382 » » xpctxt->nsNr = 0; | |
| 5383 » » } | |
| 5384 #else | |
| 5385 » » xpctxt->namespaces = comp->nsList; | |
| 5386 » » xpctxt->nsNr = comp->nsNr; | |
| 5387 #endif | |
| 5388 » } else { | |
| 5389 » » xpctxt->namespaces = NULL; | |
| 5390 » » xpctxt->nsNr = 0; | |
| 5391 » } | |
| 5392 | |
| 5393 » /* | |
| 5394 » * This XPath function is optimized for boolean results. | |
| 5395 » */ | |
| 5396 » xpobj = xmlXPathCompiledEval(comp->comp, xpctxt); | |
| 5397 | |
| 5398 » xpctxt->doc = oldXPContextDoc; | |
| 5399 » xpctxt->node = oldXPContextNode; | |
| 5400 » xpctxt->contextSize = oldXPContextSize; | |
| 5401 » xpctxt->proximityPosition = oldXPProximityPosition; | |
| 5402 » xpctxt->nsNr = oldXPNsNr; | |
| 5403 » xpctxt->namespaces = oldXPNamespaces; | |
| 5404 » } | |
| 5405 if (xpobj != NULL) { | 5420 if (xpobj != NULL) { |
| 5406 if (xpobj->type != XPATH_BOOLEAN) | 5421 if (xpobj->type != XPATH_BOOLEAN) |
| 5407 xpobj = xmlXPathConvertBoolean(xpobj); | 5422 xpobj = xmlXPathConvertBoolean(xpobj); |
| 5408 if (xpobj->type == XPATH_BOOLEAN) { | 5423 if (xpobj->type == XPATH_BOOLEAN) { |
| 5409 res = xpobj->boolval; | 5424 res = xpobj->boolval; |
| 5410 | 5425 |
| 5411 #ifdef WITH_XSLT_DEBUG_PROCESS | 5426 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 5412 XSLT_TRACE(ctxt,XSLT_TRACE_IF,xsltGenericDebug(xsltGenericDebugC
ontext, | 5427 XSLT_TRACE(ctxt,XSLT_TRACE_IF,xsltGenericDebug(xsltGenericDebugC
ontext, |
| 5413 "xsltIf: test evaluate to %d\n", res)); | 5428 "xsltIf: test evaluate to %d\n", res)); |
| 5414 #endif | 5429 #endif |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5501 /* | 5516 /* |
| 5502 * The "current template rule" is cleared for the instantiation of | 5517 * The "current template rule" is cleared for the instantiation of |
| 5503 * xsl:for-each. | 5518 * xsl:for-each. |
| 5504 */ | 5519 */ |
| 5505 oldCurTemplRule = ctxt->currentTemplateRule; | 5520 oldCurTemplRule = ctxt->currentTemplateRule; |
| 5506 ctxt->currentTemplateRule = NULL; | 5521 ctxt->currentTemplateRule = NULL; |
| 5507 | 5522 |
| 5508 oldXPDoc = xpctxt->doc; | 5523 oldXPDoc = xpctxt->doc; |
| 5509 oldXPProximityPosition = xpctxt->proximityPosition; | 5524 oldXPProximityPosition = xpctxt->proximityPosition; |
| 5510 oldXPContextSize = xpctxt->contextSize; | 5525 oldXPContextSize = xpctxt->contextSize; |
| 5511 /* | |
| 5512 * Set up XPath. | |
| 5513 */ | |
| 5514 xpctxt->node = contextNode; | |
| 5515 #ifdef XSLT_REFACTORED | |
| 5516 if (comp->inScopeNs != NULL) { | |
| 5517 xpctxt->namespaces = comp->inScopeNs->list; | |
| 5518 xpctxt->nsNr = comp->inScopeNs->xpathNumber; | |
| 5519 } else { | |
| 5520 xpctxt->namespaces = NULL; | |
| 5521 xpctxt->nsNr = 0; | |
| 5522 } | |
| 5523 #else | |
| 5524 xpctxt->namespaces = comp->nsList; | |
| 5525 xpctxt->nsNr = comp->nsNr; | |
| 5526 #endif | |
| 5527 | 5526 |
| 5528 /* | 5527 /* |
| 5529 * Evaluate the 'select' expression. | 5528 * Evaluate the 'select' expression. |
| 5530 */ | 5529 */ |
| 5531 res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt); | 5530 res = xsltPreCompEval(ctxt, contextNode, comp); |
| 5532 | 5531 |
| 5533 if (res != NULL) { | 5532 if (res != NULL) { |
| 5534 if (res->type == XPATH_NODESET) | 5533 if (res->type == XPATH_NODESET) |
| 5535 list = res->nodesetval; | 5534 list = res->nodesetval; |
| 5536 else { | 5535 else { |
| 5537 xsltTransformError(ctxt, NULL, inst, | 5536 xsltTransformError(ctxt, NULL, inst, |
| 5538 "The 'select' expression does not evaluate to a node set.\n"); | 5537 "The 'select' expression does not evaluate to a node set.\n"); |
| 5539 | 5538 |
| 5540 #ifdef WITH_XSLT_DEBUG_PROCESS | 5539 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 5541 XSLT_TRACE(ctxt,XSLT_TRACE_FOR_EACH,xsltGenericDebug(xsltGenericDebu
gContext, | 5540 XSLT_TRACE(ctxt,XSLT_TRACE_FOR_EACH,xsltGenericDebug(xsltGenericDebu
gContext, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5552 | 5551 |
| 5553 if ((list == NULL) || (list->nodeNr <= 0)) | 5552 if ((list == NULL) || (list->nodeNr <= 0)) |
| 5554 goto exit; | 5553 goto exit; |
| 5555 | 5554 |
| 5556 #ifdef WITH_XSLT_DEBUG_PROCESS | 5555 #ifdef WITH_XSLT_DEBUG_PROCESS |
| 5557 XSLT_TRACE(ctxt,XSLT_TRACE_FOR_EACH,xsltGenericDebug(xsltGenericDebugContext
, | 5556 XSLT_TRACE(ctxt,XSLT_TRACE_FOR_EACH,xsltGenericDebug(xsltGenericDebugContext
, |
| 5558 "xsltForEach: select evaluates to %d nodes\n", list->nodeNr)); | 5557 "xsltForEach: select evaluates to %d nodes\n", list->nodeNr)); |
| 5559 #endif | 5558 #endif |
| 5560 | 5559 |
| 5561 /* | 5560 /* |
| 5562 * Restore XPath states for the "current node". | |
| 5563 */ | |
| 5564 xpctxt->contextSize = oldXPContextSize; | |
| 5565 xpctxt->proximityPosition = oldXPProximityPosition; | |
| 5566 xpctxt->node = contextNode; | |
| 5567 | |
| 5568 /* | |
| 5569 * Set the list; this has to be done already here for xsltDoSortFunction(). | 5561 * Set the list; this has to be done already here for xsltDoSortFunction(). |
| 5570 */ | 5562 */ |
| 5571 ctxt->nodeList = list; | 5563 ctxt->nodeList = list; |
| 5572 /* | 5564 /* |
| 5573 * Handle xsl:sort instructions and skip them for further processing. | 5565 * Handle xsl:sort instructions and skip them for further processing. |
| 5574 * BUG TODO: We are not using namespaced potentially defined on the | 5566 * BUG TODO: We are not using namespaced potentially defined on the |
| 5575 * xsl:sort element; XPath expression might fail. | 5567 * xsl:sort element; XPath expression might fail. |
| 5576 */ | 5568 */ |
| 5577 curInst = inst->children; | 5569 curInst = inst->children; |
| 5578 if (IS_XSLT_ELEM(curInst) && IS_XSLT_NAME(curInst, "sort")) { | 5570 if (IS_XSLT_ELEM(curInst) && IS_XSLT_NAME(curInst, "sort")) { |
| (...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6466 XSLT_NAMESPACE, | 6458 XSLT_NAMESPACE, |
| 6467 (xsltTransformFunction) xsltDebug); | 6459 (xsltTransformFunction) xsltDebug); |
| 6468 xsltRegisterExtElement(ctxt, (const xmlChar *) "otherwise", | 6460 xsltRegisterExtElement(ctxt, (const xmlChar *) "otherwise", |
| 6469 XSLT_NAMESPACE, | 6461 XSLT_NAMESPACE, |
| 6470 (xsltTransformFunction) xsltDebug); | 6462 (xsltTransformFunction) xsltDebug); |
| 6471 xsltRegisterExtElement(ctxt, (const xmlChar *) "fallback", | 6463 xsltRegisterExtElement(ctxt, (const xmlChar *) "fallback", |
| 6472 XSLT_NAMESPACE, | 6464 XSLT_NAMESPACE, |
| 6473 (xsltTransformFunction) xsltDebug); | 6465 (xsltTransformFunction) xsltDebug); |
| 6474 | 6466 |
| 6475 } | 6467 } |
| OLD | NEW |