2 * variables.c: Implementation of the variable storage and lookup
5 * http://www.w3.org/TR/1999/REC-xslt-19991116
7 * See Copyright for the status of this software.
9 * Daniel.Veillard@imag.fr
12 #include "xsltconfig.h"
16 #include <libxml/xmlmemory.h>
17 #include <libxml/tree.h>
18 #include <libxml/valid.h>
19 #include <libxml/hash.h>
20 #include <libxml/xmlerror.h>
21 #include <libxml/xpath.h>
22 #include <libxml/xpathInternals.h>
23 #include <libxml/parserInternals.h>
24 #include <libxml/xmlversion.h>
26 #include "xsltInternals.h"
27 #include "xsltutils.h"
28 #include "variables.h"
29 #include "transform.h"
33 #ifdef WITH_XSLT_DEBUG
34 #define WITH_XSLT_DEBUG_VARIABLE
37 /************************************************************************
41 ************************************************************************/
46 * Create a new XSLT ParserContext
48 * Returns the newly allocated xsltParserStackElem or NULL in case of error
50 static xsltStackElemPtr
51 xsltNewStackElem(void) {
54 cur = (xsltStackElemPtr) xmlMalloc(sizeof(xsltStackElem));
56 xsltGenericError(xsltGenericErrorContext,
57 "xsltNewStackElem : malloc failed\n");
72 * @elem: an XSLT stack element
74 * Makes a copy of the stack element
76 * Returns the copy of NULL
78 static xsltStackElemPtr
79 xsltCopyStackElem(xsltStackElemPtr elem) {
82 cur = (xsltStackElemPtr) xmlMalloc(sizeof(xsltStackElem));
84 xsltGenericError(xsltGenericErrorContext,
85 "xsltNewStackElem : malloc failed\n");
88 cur->name = xmlStrdup(elem->name);
89 cur->nameURI = xmlStrdup(elem->nameURI);
90 cur->select = xmlStrdup(elem->select);
91 cur->tree = elem->tree;
92 cur->comp = elem->comp;
100 * @elem: an XSLT stack element
102 * Free up the memory allocated by @elem
105 xsltFreeStackElem(xsltStackElemPtr elem) {
108 if (elem->name != NULL)
110 if (elem->nameURI != NULL)
111 xmlFree(elem->nameURI);
112 if (elem->select != NULL)
113 xmlFree(elem->select);
114 if (elem->value != NULL)
115 xmlXPathFreeObject(elem->value);
121 * xsltFreeStackElemList:
122 * @elem: an XSLT stack element
124 * Free up the memory allocated by @elem
127 xsltFreeStackElemList(xsltStackElemPtr elem) {
128 xsltStackElemPtr next;
130 while(elem != NULL) {
132 xsltFreeStackElem(elem);
138 * xsltCheckStackElem:
139 * @ctxt: xn XSLT transformation context
140 * @name: the variable name
141 * @nameURI: the variable namespace URI
143 * check wether the variable or param is already defined
145 * Returns 1 if present, 0 if not, -1 in case of failure.
148 xsltCheckStackElem(xsltTransformContextPtr ctxt, const xmlChar *name,
149 const xmlChar *nameURI) {
150 xsltStackElemPtr cur;
152 if ((ctxt == NULL) || (name == NULL))
156 while (cur != NULL) {
157 if (xmlStrEqual(name, cur->name)) {
158 if (((nameURI == NULL) && (cur->nameURI == NULL)) ||
159 ((nameURI != NULL) && (cur->nameURI != NULL) &&
160 (xmlStrEqual(nameURI, cur->nameURI)))) {
171 * @ctxt: xn XSLT transformation context
172 * @elem: a stack element
174 * add a new element at this level of the stack.
176 * Returns 0 in case of success, -1 in case of failure.
179 xsltAddStackElem(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) {
180 if ((ctxt == NULL) || (elem == NULL))
183 elem->next = ctxt->varsTab[ctxt->varsNr - 1];
184 ctxt->varsTab[ctxt->varsNr - 1] = elem;
190 * xsltAddStackElemList:
191 * @ctxt: xn XSLT transformation context
192 * @elems: a stack element list
194 * add the new element list at this level of the stack.
196 * Returns 0 in case of success, -1 in case of failure.
199 xsltAddStackElemList(xsltTransformContextPtr ctxt, xsltStackElemPtr elems) {
200 xsltStackElemPtr cur;
202 if ((ctxt == NULL) || (elems == NULL))
205 /* TODO: check doublons */
206 if (ctxt->varsTab[ctxt->varsNr - 1] != NULL) {
207 cur = ctxt->varsTab[ctxt->varsNr - 1];
208 while (cur->next != NULL)
212 elems->next = ctxt->varsTab[ctxt->varsNr - 1];
213 ctxt->varsTab[ctxt->varsNr - 1] = elems;
221 * @ctxt: an XSLT transformation context
222 * @name: the local part of the name
223 * @nameURI: the URI part of the name
225 * Locate an element in the stack based on its name.
227 static xsltStackElemPtr
228 xsltStackLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
229 const xmlChar *nameURI) {
230 xsltStackElemPtr ret = NULL;
232 xsltStackElemPtr cur;
234 if ((ctxt == NULL) || (name == NULL))
238 * Do the lookup from the top of the stack, but
239 * don't use params being computed in a call-param
241 i = ctxt->varsNr - 1;
244 cur = ctxt->varsTab[i];
245 while (cur != NULL) {
246 if (xmlStrEqual(cur->name, name)) {
247 if (nameURI == NULL) {
248 if (cur->nameURI == NULL) {
252 if ((cur->nameURI != NULL) &&
253 (xmlStrEqual(cur->nameURI, nameURI))) {
265 /************************************************************************
267 * Module interfaces *
269 ************************************************************************/
273 * @ctxt: the XSLT transformation context
274 * @elem: the variable or parameter.
276 * Evaluate a variable value.
278 * Returns the XPath Object value or NULL in case of error
280 static xmlXPathObjectPtr
281 xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem,
282 xsltStylePreCompPtr precomp) {
283 xmlXPathObjectPtr result = NULL;
284 int oldProximityPosition, oldContextSize;
285 if ((ctxt == NULL) || (elem == NULL))
288 #ifdef WITH_XSLT_DEBUG_VARIABLE
289 xsltGenericDebug(xsltGenericDebugContext,
290 "Evaluating variable %s\n", elem->name);
292 if (elem->select != NULL) {
293 xmlXPathCompExprPtr comp = NULL;
295 if ((precomp != NULL) && (precomp->comp != NULL)) {
296 comp = precomp->comp;
298 comp = xmlXPathCompile(elem->select);
302 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
303 oldContextSize = ctxt->xpathCtxt->contextSize;
304 ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
305 /* TODO: do we need to propagate the namespaces here ? */
306 ctxt->xpathCtxt->namespaces = NULL;
307 ctxt->xpathCtxt->nsNr = 0;
308 result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
309 ctxt->xpathCtxt->contextSize = oldContextSize;
310 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
311 if ((precomp == NULL) || (precomp->comp == NULL))
312 xmlXPathFreeCompExpr(comp);
313 if (result == NULL) {
314 xsltGenericError(xsltGenericErrorContext,
315 "Evaluating variable %s failed\n", elem->name);
316 #ifdef WITH_XSLT_DEBUG_VARIABLE
317 #ifdef LIBXML_DEBUG_ENABLED
319 if ((xsltGenericDebugContext == stdout) ||
320 (xsltGenericDebugContext == stderr))
321 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
327 if (elem->tree == NULL) {
328 result = xmlXPathNewCString("");
331 * This is a result tree fragment.
333 xmlNodePtr container;
334 xmlNodePtr oldInsert, oldNode;
336 container = xmlNewDocNode(ctxt->output, NULL,
337 (const xmlChar *) "fake", NULL);
338 if (container == NULL)
341 oldInsert = ctxt->insert;
342 oldNode = ctxt->node;
343 ctxt->insert = container;
344 xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, 0);
345 ctxt->insert = oldInsert;
346 ctxt->node = oldNode;
348 result = xmlXPathNewValueTree(container);
349 if (result == NULL) {
350 result = xmlXPathNewCString("");
352 #ifdef WITH_XSLT_DEBUG_VARIABLE
353 #ifdef LIBXML_DEBUG_ENABLED
354 if ((xsltGenericDebugContext == stdout) ||
355 (xsltGenericDebugContext == stderr))
356 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
366 * xsltEvalGlobalVariable:
367 * @ctxt: the XSLT transformation context
368 * @elem: the variable or parameter.
370 * Evaluate a global variable value.
372 * Returns the XPath Object value or NULL in case of error
374 static xmlXPathObjectPtr
375 xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt) {
376 xmlXPathObjectPtr result = NULL;
377 xsltStylePreCompPtr precomp;
378 int oldProximityPosition, oldContextSize;
381 if ((ctxt == NULL) || (elem == NULL))
387 #ifdef WITH_XSLT_DEBUG_VARIABLE
388 xsltGenericDebug(xsltGenericDebugContext,
389 "Evaluating global variable %s\n", elem->name);
392 precomp = elem->comp;
393 if (elem->select != NULL) {
394 xmlXPathCompExprPtr comp = NULL;
396 if ((precomp != NULL) && (precomp->comp != NULL)) {
397 comp = precomp->comp;
399 comp = xmlXPathCompile(elem->select);
403 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
404 oldContextSize = ctxt->xpathCtxt->contextSize;
405 oldInst = ctxt->inst;
407 ctxt->inst = precomp->inst;
410 ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
411 /* TODO: do we need to propagate the namespaces here ? */
412 ctxt->xpathCtxt->namespaces = NULL;
413 ctxt->xpathCtxt->nsNr = 0;
414 result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
415 ctxt->xpathCtxt->contextSize = oldContextSize;
416 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
417 ctxt->inst = oldInst;
418 if ((precomp == NULL) || (precomp->comp == NULL))
419 xmlXPathFreeCompExpr(comp);
420 if (result == NULL) {
421 xsltGenericError(xsltGenericErrorContext,
422 "Evaluating global variable %s failed\n", elem->name);
423 #ifdef WITH_XSLT_DEBUG_VARIABLE
424 #ifdef LIBXML_DEBUG_ENABLED
426 if ((xsltGenericDebugContext == stdout) ||
427 (xsltGenericDebugContext == stderr))
428 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
434 if (elem->tree == NULL) {
435 result = xmlXPathNewCString("");
438 * This is a result tree fragment.
440 xmlNodePtr container;
441 xmlNodePtr oldInsert, oldNode;
443 container = xmlNewDocNode(ctxt->output, NULL,
444 (const xmlChar *) "fake", NULL);
445 if (container == NULL)
448 oldInsert = ctxt->insert;
449 oldNode = ctxt->node;
450 ctxt->insert = container;
451 xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, 0);
452 ctxt->insert = oldInsert;
453 ctxt->node = oldNode;
455 result = xmlXPathNewValueTree(container);
456 if (result == NULL) {
457 result = xmlXPathNewCString("");
459 #ifdef WITH_XSLT_DEBUG_VARIABLE
460 #ifdef LIBXML_DEBUG_ENABLED
461 if ((xsltGenericDebugContext == stdout) ||
462 (xsltGenericDebugContext == stderr))
463 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
469 if (result != NULL) {
470 elem->value = result;
477 * xsltEvalGlobalVariables:
478 * @ctxt: the XSLT transformation context
480 * Evaluate the global variables of a stylesheet. This need to be
481 * done on parsed stylesheets before starting to apply transformations
483 * Returns 0 in case of success, -1 in case of error
486 xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
487 xsltStackElemPtr elem;
488 xsltStylesheetPtr style;
493 #ifdef WITH_XSLT_DEBUG_VARIABLE
494 xsltGenericDebug(xsltGenericDebugContext,
495 "Registering global variables\n");
497 ctxt->node = (xmlNodePtr) ctxt->document->doc;
498 ctxt->xpathCtxt->contextSize = 1;
499 ctxt->xpathCtxt->proximityPosition = 1;
502 * Walk the list from the stylesheets and populate the hash table
505 while (style != NULL) {
506 elem = style->variables;
508 #ifdef WITH_XSLT_DEBUG_VARIABLE
509 if ((style->doc != NULL) && (style->doc->URL != NULL)) {
511 xsltGenericDebug(xsltGenericDebugContext,
512 "Registering global variables from %s\n",
516 while (elem != NULL) {
517 xsltStackElemPtr def;
520 * Global variables are stored in the variables pool.
522 def = (xsltStackElemPtr)
523 xmlHashLookup2(ctxt->globalVars,
524 elem->name, elem->nameURI);
528 def = xsltCopyStackElem(elem);
529 res = xmlHashAddEntry2(ctxt->globalVars,
530 elem->name, elem->nameURI, def);
531 } else if ((elem->comp != NULL) &&
532 (elem->comp->type == XSLT_FUNC_VARIABLE)) {
533 xsltGenericError(xsltGenericErrorContext,
534 "Global variable %s already defined\n", elem->name);
539 style = xsltNextImport(style);
543 * This part does the actual evaluation
545 ctxt->node = (xmlNodePtr) ctxt->document->doc;
546 ctxt->xpathCtxt->contextSize = 1;
547 ctxt->xpathCtxt->proximityPosition = 1;
548 xmlHashScan(ctxt->globalVars,
549 (xmlHashScanner) xsltEvalGlobalVariable, ctxt);
555 * xsltRegisterGlobalVariable:
556 * @style: the XSLT transformation context
557 * @name: the variable name
558 * @ns_uri: the variable namespace URI
559 * @select: the expression which need to be evaluated to generate a value
560 * @tree: the subtree if select is NULL
561 * @comp: the precompiled value
562 * @value: the string value if available
564 * Register a new variable value. If @value is NULL it unregisters
567 * Returns 0 in case of success, -1 in case of error
570 xsltRegisterGlobalVariable(xsltStylesheetPtr style, const xmlChar *name,
571 const xmlChar *ns_uri, const xmlChar *select,
572 xmlNodePtr tree, xsltStylePreCompPtr comp,
573 const xmlChar *value) {
574 xsltStackElemPtr elem, tmp;
582 #ifdef WITH_XSLT_DEBUG_VARIABLE
583 if (comp->type == XSLT_FUNC_PARAM)
584 xsltGenericDebug(xsltGenericDebugContext,
585 "Defining global param %s\n", name);
587 xsltGenericDebug(xsltGenericDebugContext,
588 "Defining global variable %s\n", name);
590 elem = xsltNewStackElem();
594 elem->name = xmlStrdup(name);
595 elem->select = xmlStrdup(select);
597 elem->nameURI = xmlStrdup(ns_uri);
599 tmp = style->variables;
602 style->variables = elem;
604 while (tmp->next != NULL)
611 elem->value = xmlXPathNewString(value);
617 * xsltEvalUserParams:
618 * @ctxt: the XSLT transformation context
619 * @params: a NULL terminated arry of parameters names/values tuples
621 * Evaluate the global variables of a stylesheet. This need to be
622 * done on parsed stylesheets before starting to apply transformations
624 * Returns 0 in case of success, -1 in case of error
627 xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) {
628 xsltStylesheetPtr style;
631 const xmlChar *value;
632 xmlChar *ncname, *prefix;
634 xmlXPathCompExprPtr comp;
635 xmlXPathObjectPtr result;
636 int oldProximityPosition, oldContextSize;
644 while (params[indx] != NULL) {
645 name = (const xmlChar *)params[indx++];
646 value = (const xmlChar *)params[indx++];
647 if ((name == NULL) || (value == NULL))
650 #ifdef WITH_XSLT_DEBUG_VARIABLE
651 xsltGenericDebug(xsltGenericDebugContext,
652 "Evaluating user parameter %s=%s\n", name, value);
657 ncname = xmlSplitQName2(name, &prefix);
659 if (ncname != NULL) {
660 if (prefix != NULL) {
663 ns = xmlSearchNs(style->doc, xmlDocGetRootElement(style->doc),
666 xsltGenericError(xsltGenericErrorContext,
667 "user param : no namespace bound to prefix %s\n", prefix);
679 ncname = xmlStrdup(name);
686 comp = xmlXPathCompile(value);
688 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
689 oldContextSize = ctxt->xpathCtxt->contextSize;
690 ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
691 /* TODO: do we need to propagate the namespaces here ? */
692 ctxt->xpathCtxt->namespaces = NULL;
693 ctxt->xpathCtxt->nsNr = 0;
694 result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
695 ctxt->xpathCtxt->contextSize = oldContextSize;
696 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
697 xmlXPathFreeCompExpr(comp);
699 if (result == NULL) {
700 xsltGenericError(xsltGenericErrorContext,
701 "Evaluating user parameter %s failed\n", name);
703 xsltStackElemPtr elem;
706 #ifdef WITH_XSLT_DEBUG_VARIABLE
707 #ifdef LIBXML_DEBUG_ENABLED
708 if ((xsltGenericDebugContext == stdout) ||
709 (xsltGenericDebugContext == stderr))
710 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
714 elem = xsltNewStackElem();
716 elem->name = xmlStrdup(ncname);
718 elem->select = xmlStrdup(value);
722 elem->nameURI = xmlStrdup(href);
725 elem->value = result;
728 * Global parameters are stored in the XPath context
731 res = xmlHashAddEntry2(ctxt->globalVars,
734 xsltFreeStackElem(elem);
735 xsltGenericError(xsltGenericErrorContext,
736 "Global parameter %s already defined\n", ncname);
747 * @ctxt: the XSLT transformation context
748 * @comp: the precompiled form
749 * @tree: the tree if select is NULL
751 * Computes a new variable value.
753 * Returns the xsltStackElemPtr or NULL in case of error
755 static xsltStackElemPtr
756 xsltBuildVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
758 xsltStackElemPtr elem;
760 #ifdef WITH_XSLT_DEBUG_VARIABLE
761 xsltGenericDebug(xsltGenericDebugContext,
762 "Building variable %s", comp->name);
763 if (comp->select != NULL)
764 xsltGenericDebug(xsltGenericDebugContext,
765 " select %s", comp->select);
766 xsltGenericDebug(xsltGenericDebugContext, "\n");
768 elem = xsltNewStackElem();
772 elem->name = xmlStrdup(comp->name);
773 if (comp->select != NULL)
774 elem->select = xmlStrdup(comp->select);
778 elem->nameURI = xmlStrdup(comp->ns);
780 if (elem->computed == 0) {
781 elem->value = xsltEvalVariable(ctxt, elem, comp);
782 if (elem->value != NULL)
789 * xsltRegisterVariable:
790 * @ctxt: the XSLT transformation context
791 * @name: the variable name
792 * @ns_uri: the variable namespace URI
793 * @select: the expression which need to be evaluated to generate a value
794 * @tree: the tree if select is NULL
795 * @param: this is a parameter actually
797 * Computes and register a new variable value.
799 * Returns 0 in case of success, -1 in case of error
802 xsltRegisterVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
803 xmlNodePtr tree, int param) {
804 xsltStackElemPtr elem;
806 if (xsltCheckStackElem(ctxt, comp->name, comp->ns) != 0) {
808 xsltGenericError(xsltGenericErrorContext,
809 "xsl:variable : redefining %s\n", comp->name);
811 #ifdef WITH_XSLT_DEBUG_VARIABLE
813 xsltGenericDebug(xsltGenericDebugContext,
814 "param %s defined by caller", comp->name);
818 elem = xsltBuildVariable(ctxt, comp, tree);
819 xsltAddStackElem(ctxt, elem);
824 * xsltGlobalVariableLookup:
825 * @ctxt: the XSLT transformation context
826 * @name: the variable name
827 * @ns_uri: the variable namespace URI
829 * Search in the Variable array of the context for the given
832 * Returns the value or NULL if not found
834 static xmlXPathObjectPtr
835 xsltGlobalVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
836 const xmlChar *ns_uri) {
837 xsltStackElemPtr elem;
838 xmlXPathObjectPtr ret = NULL;
841 * Lookup the global variables in XPath global variable hash table
843 if ((ctxt->xpathCtxt == NULL) || (ctxt->globalVars == NULL))
845 elem = (xsltStackElemPtr)
846 xmlHashLookup2(ctxt->globalVars, name, ns_uri);
848 #ifdef WITH_XSLT_DEBUG_VARIABLE
849 xsltGenericDebug(xsltGenericDebugContext,
850 "global variable not found %s\n", name);
854 if (elem->computed == 0)
855 ret = xsltEvalGlobalVariable(elem, ctxt);
858 return(xmlXPathObjectCopy(ret));
862 * xsltVariableLookup:
863 * @ctxt: the XSLT transformation context
864 * @name: the variable name
865 * @ns_uri: the variable namespace URI
867 * Search in the Variable array of the context for the given
870 * Returns the value or NULL if not found
873 xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
874 const xmlChar *ns_uri) {
875 xsltStackElemPtr elem;
880 elem = xsltStackLookup(ctxt, name, ns_uri);
882 return(xsltGlobalVariableLookup(ctxt, name, ns_uri));
884 if (elem->computed == 0) {
885 #ifdef WITH_XSLT_DEBUG_VARIABLE
886 xsltGenericDebug(xsltGenericDebugContext,
887 "uncomputed variable %s\n", name);
889 elem->value = xsltEvalVariable(ctxt, elem, NULL);
892 if (elem->value != NULL)
893 return(xmlXPathObjectCopy(elem->value));
894 #ifdef WITH_XSLT_DEBUG_VARIABLE
895 xsltGenericDebug(xsltGenericDebugContext,
896 "variable not found %s\n", name);
902 * xsltParseStylesheetCallerParam:
903 * @ctxt: the XSLT transformation context
904 * @cur: the "param" element
906 * parse an XSLT transformation param declaration, compute
907 * its value but doesn't record it.
909 * It returns the new xsltStackElemPtr or NULL
913 xsltParseStylesheetCallerParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
914 xmlNodePtr tree = NULL;
915 xsltStackElemPtr elem = NULL;
916 xsltStylePreCompPtr comp;
918 if ((cur == NULL) || (ctxt == NULL))
920 comp = (xsltStylePreCompPtr) cur->_private;
922 xsltGenericError(xsltGenericErrorContext,
923 "xsl:param : compilation error\n");
927 if (comp->name == NULL) {
928 xsltGenericError(xsltGenericErrorContext,
929 "xsl:param : missing name attribute\n");
932 #ifdef WITH_XSLT_DEBUG_VARIABLE
933 xsltGenericDebug(xsltGenericDebugContext,
934 "Handling param %s\n", comp->name);
938 if (comp->select == NULL) {
939 tree = cur->children;
941 #ifdef WITH_XSLT_DEBUG_VARIABLE
942 xsltGenericDebug(xsltGenericDebugContext,
943 " select %s\n", comp->select);
948 elem = xsltBuildVariable(ctxt, comp, tree);
954 * xsltParseGlobalVariable:
955 * @style: the XSLT stylesheet
956 * @cur: the "variable" element
958 * parse an XSLT transformation variable declaration and record
963 xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur) {
964 xsltStylePreCompPtr comp;
966 if ((cur == NULL) || (style == NULL))
969 xsltStylePreCompute(style, cur);
970 comp = (xsltStylePreCompPtr) cur->_private;
972 xsltGenericError(xsltGenericErrorContext,
973 "xsl:variable : compilation had failed\n");
977 if (comp->name == NULL) {
978 xsltGenericError(xsltGenericErrorContext,
979 "xsl:variable : missing name attribute\n");
983 #ifdef WITH_XSLT_DEBUG_VARIABLE
984 xsltGenericDebug(xsltGenericDebugContext,
985 "Registering global variable %s\n", comp->name);
988 xsltRegisterGlobalVariable(style, comp->name, comp->ns, comp->select,
989 cur->children, comp, NULL);
993 * xsltParseGlobalParam:
994 * @style: the XSLT stylesheet
995 * @cur: the "param" element
997 * parse an XSLT transformation param declaration and record
1002 xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
1003 xsltStylePreCompPtr comp;
1005 if ((cur == NULL) || (style == NULL))
1008 xsltStylePreCompute(style, cur);
1009 comp = (xsltStylePreCompPtr) cur->_private;
1011 xsltGenericError(xsltGenericErrorContext,
1012 "xsl:param : compilation had failed\n");
1016 if (comp->name == NULL) {
1017 xsltGenericError(xsltGenericErrorContext,
1018 "xsl:param : missing name attribute\n");
1022 #ifdef WITH_XSLT_DEBUG_VARIABLE
1023 xsltGenericDebug(xsltGenericDebugContext,
1024 "Registering global param %s\n", comp->name);
1027 xsltRegisterGlobalVariable(style, comp->name, comp->ns, comp->select,
1028 cur->children, comp, NULL);
1032 * xsltParseStylesheetVariable:
1033 * @ctxt: the XSLT transformation context
1034 * @cur: the "variable" element
1036 * parse an XSLT transformation variable declaration and record
1041 xsltParseStylesheetVariable(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
1042 xsltStylePreCompPtr comp;
1044 if ((cur == NULL) || (ctxt == NULL))
1047 comp = (xsltStylePreCompPtr) cur->_private;
1049 xsltGenericError(xsltGenericErrorContext,
1050 "xsl:variable : compilation had failed\n");
1054 if (comp->name == NULL) {
1055 xsltGenericError(xsltGenericErrorContext,
1056 "xsl:variable : missing name attribute\n");
1060 #ifdef WITH_XSLT_DEBUG_VARIABLE
1061 xsltGenericDebug(xsltGenericDebugContext,
1062 "Registering variable %s\n", comp->name);
1065 xsltRegisterVariable(ctxt, comp, cur->children, 0);
1069 * xsltParseStylesheetParam:
1070 * @ctxt: the XSLT transformation context
1071 * @cur: the "param" element
1073 * parse an XSLT transformation param declaration and record
1078 xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
1079 xsltStylePreCompPtr comp;
1081 if ((cur == NULL) || (ctxt == NULL))
1084 comp = (xsltStylePreCompPtr) cur->_private;
1086 xsltGenericError(xsltGenericErrorContext,
1087 "xsl:param : compilation had failed\n");
1091 if (comp->name == NULL) {
1092 xsltGenericError(xsltGenericErrorContext,
1093 "xsl:param : missing name attribute\n");
1097 #ifdef WITH_XSLT_DEBUG_VARIABLE
1098 xsltGenericDebug(xsltGenericDebugContext,
1099 "Registering param %s\n", comp->name);
1102 xsltRegisterVariable(ctxt, comp, cur->children, 1);
1106 * xsltFreeGlobalVariables:
1107 * @ctxt: the XSLT transformation context
1109 * Free up the data associated to the global variables
1114 xsltFreeGlobalVariables(xsltTransformContextPtr ctxt) {
1115 xmlHashFree(ctxt->globalVars, (xmlHashDeallocator) xsltFreeStackElem);
1119 * xsltXPathVariableLookup:
1120 * @ctxt: a void * but the the XSLT transformation context actually
1121 * @name: the variable name
1122 * @ns_uri: the variable namespace URI
1124 * This is the entry point when a varibale is needed by the XPath
1127 * Returns the value or NULL if not found
1130 xsltXPathVariableLookup(void *ctxt, const xmlChar *name,
1131 const xmlChar *ns_uri) {
1132 xsltTransformContextPtr context;
1133 xmlXPathObjectPtr ret;
1135 if ((ctxt == NULL) || (name == NULL))
1138 #ifdef WITH_XSLT_DEBUG_VARIABLE
1139 xsltGenericDebug(xsltGenericDebugContext,
1140 "Lookup variable %s\n", name);
1142 context = (xsltTransformContextPtr) ctxt;
1143 ret = xsltVariableLookup(context, name, ns_uri);
1145 xsltGenericError(xsltGenericErrorContext,
1146 "unregistered variable %s\n", name);
1148 #ifdef WITH_XSLT_DEBUG_VARIABLE
1150 xsltGenericDebug(xsltGenericDebugContext,
1151 "found variable %s\n", name);