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.
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>
25 #include "xsltInternals.h"
26 #include "xsltutils.h"
27 #include "variables.h"
28 #include "transform.h"
32 #ifdef WITH_XSLT_DEBUG
33 #define WITH_XSLT_DEBUG_VARIABLE
36 /************************************************************************
40 ************************************************************************/
45 * Create a new XSLT ParserContext
47 * Returns the newly allocated xsltParserStackElem or NULL in case of error
49 static xsltStackElemPtr
50 xsltNewStackElem(void) {
53 cur = (xsltStackElemPtr) xmlMalloc(sizeof(xsltStackElem));
55 xsltGenericError(xsltGenericErrorContext,
56 "xsltNewStackElem : malloc failed\n");
71 * @elem: an XSLT stack element
73 * Makes a copy of the stack element
75 * Returns the copy of NULL
77 static xsltStackElemPtr
78 xsltCopyStackElem(xsltStackElemPtr elem) {
81 cur = (xsltStackElemPtr) xmlMalloc(sizeof(xsltStackElem));
83 xsltGenericError(xsltGenericErrorContext,
84 "xsltNewStackElem : malloc failed\n");
87 cur->name = xmlStrdup(elem->name);
88 cur->nameURI = xmlStrdup(elem->nameURI);
89 cur->select = xmlStrdup(elem->select);
90 cur->tree = elem->tree;
91 cur->comp = elem->comp;
99 * @elem: an XSLT stack element
101 * Free up the memory allocated by @elem
104 xsltFreeStackElem(xsltStackElemPtr elem) {
107 if (elem->name != NULL)
109 if (elem->nameURI != NULL)
110 xmlFree(elem->nameURI);
111 if (elem->select != NULL)
112 xmlFree(elem->select);
113 if (elem->value != NULL)
114 xmlXPathFreeObject(elem->value);
120 * xsltFreeStackElemList:
121 * @elem: an XSLT stack element
123 * Free up the memory allocated by @elem
126 xsltFreeStackElemList(xsltStackElemPtr elem) {
127 xsltStackElemPtr next;
129 while(elem != NULL) {
131 xsltFreeStackElem(elem);
137 * xsltCheckStackElem:
138 * @ctxt: xn XSLT transformation context
139 * @name: the variable name
140 * @nameURI: the variable namespace URI
142 * check wether the variable or param is already defined
144 * Returns 1 if present, 0 if not, -1 in case of failure.
147 xsltCheckStackElem(xsltTransformContextPtr ctxt, const xmlChar *name,
148 const xmlChar *nameURI) {
149 xsltStackElemPtr cur;
151 if ((ctxt == NULL) || (name == NULL))
155 while (cur != NULL) {
156 if (xmlStrEqual(name, cur->name)) {
157 if (((nameURI == NULL) && (cur->nameURI == NULL)) ||
158 ((nameURI != NULL) && (cur->nameURI != NULL) &&
159 (xmlStrEqual(nameURI, cur->nameURI)))) {
170 * @ctxt: xn XSLT transformation context
171 * @elem: a stack element
173 * add a new element at this level of the stack.
175 * Returns 0 in case of success, -1 in case of failure.
178 xsltAddStackElem(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) {
179 if ((ctxt == NULL) || (elem == NULL))
182 elem->next = ctxt->varsTab[ctxt->varsNr - 1];
183 ctxt->varsTab[ctxt->varsNr - 1] = elem;
189 * xsltAddStackElemList:
190 * @ctxt: xn XSLT transformation context
191 * @elems: a stack element list
193 * add the new element list at this level of the stack.
195 * Returns 0 in case of success, -1 in case of failure.
198 xsltAddStackElemList(xsltTransformContextPtr ctxt, xsltStackElemPtr elems) {
199 xsltStackElemPtr cur;
201 if ((ctxt == NULL) || (elems == NULL))
204 /* TODO: check doublons */
205 if (ctxt->varsTab[ctxt->varsNr - 1] != NULL) {
206 cur = ctxt->varsTab[ctxt->varsNr - 1];
207 while (cur->next != NULL)
211 elems->next = ctxt->varsTab[ctxt->varsNr - 1];
212 ctxt->varsTab[ctxt->varsNr - 1] = elems;
220 * @ctxt: an XSLT transformation context
221 * @name: the local part of the name
222 * @nameURI: the URI part of the name
224 * Locate an element in the stack based on its name.
226 static xsltStackElemPtr
227 xsltStackLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
228 const xmlChar *nameURI) {
229 xsltStackElemPtr ret = NULL;
231 xsltStackElemPtr cur;
233 if ((ctxt == NULL) || (name == NULL))
237 * Do the lookup from the top of the stack, but
238 * don't use params being computed in a call-param
240 i = ctxt->varsNr - 1;
243 cur = ctxt->varsTab[i];
244 while (cur != NULL) {
245 if (xmlStrEqual(cur->name, name)) {
246 if (nameURI == NULL) {
247 if (cur->nameURI == NULL) {
251 if ((cur->nameURI != NULL) &&
252 (xmlStrEqual(cur->nameURI, nameURI))) {
264 /************************************************************************
266 * Module interfaces *
268 ************************************************************************/
272 * @ctxt: the XSLT transformation context
273 * @elem: the variable or parameter.
275 * Evaluate a variable value.
277 * Returns the XPath Object value or NULL in case of error
279 static xmlXPathObjectPtr
280 xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem,
281 xsltStylePreCompPtr precomp) {
282 xmlXPathObjectPtr result = NULL;
283 int oldProximityPosition, oldContextSize;
284 if ((ctxt == NULL) || (elem == NULL))
287 #ifdef WITH_XSLT_DEBUG_VARIABLE
288 xsltGenericDebug(xsltGenericDebugContext,
289 "Evaluating variable %s\n", elem->name);
291 if (elem->select != NULL) {
292 xmlXPathCompExprPtr comp = NULL;
294 if ((precomp != NULL) && (precomp->comp != NULL)) {
295 comp = precomp->comp;
297 comp = xmlXPathCompile(elem->select);
301 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
302 oldContextSize = ctxt->xpathCtxt->contextSize;
303 ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
304 if (precomp != NULL) {
305 ctxt->inst = precomp->inst;
306 ctxt->xpathCtxt->namespaces = precomp->nsList;
307 ctxt->xpathCtxt->nsNr = precomp->nsNr;
310 ctxt->xpathCtxt->namespaces = NULL;
311 ctxt->xpathCtxt->nsNr = 0;
313 result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
314 ctxt->xpathCtxt->contextSize = oldContextSize;
315 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
316 if ((precomp == NULL) || (precomp->comp == NULL))
317 xmlXPathFreeCompExpr(comp);
318 if (result == NULL) {
319 xsltGenericError(xsltGenericErrorContext,
320 "Evaluating variable %s failed\n", elem->name);
321 #ifdef WITH_XSLT_DEBUG_VARIABLE
322 #ifdef LIBXML_DEBUG_ENABLED
324 if ((xsltGenericDebugContext == stdout) ||
325 (xsltGenericDebugContext == stderr))
326 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
332 if (elem->tree == NULL) {
333 result = xmlXPathNewCString("");
336 * This is a result tree fragment.
338 xmlNodePtr container;
339 xmlNodePtr oldInsert, oldNode;
341 container = xmlNewDocNode(ctxt->output, NULL,
342 (const xmlChar *) "fake", NULL);
343 if (container == NULL)
346 oldInsert = ctxt->insert;
347 oldNode = ctxt->node;
348 ctxt->insert = container;
349 xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, 0);
350 ctxt->insert = oldInsert;
351 ctxt->node = oldNode;
353 result = xmlXPathNewValueTree(container);
354 if (result == NULL) {
355 result = xmlXPathNewCString("");
357 #ifdef WITH_XSLT_DEBUG_VARIABLE
358 #ifdef LIBXML_DEBUG_ENABLED
359 if ((xsltGenericDebugContext == stdout) ||
360 (xsltGenericDebugContext == stderr))
361 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
371 * xsltEvalGlobalVariable:
372 * @ctxt: the XSLT transformation context
373 * @elem: the variable or parameter.
375 * Evaluate a global variable value.
377 * Returns the XPath Object value or NULL in case of error
379 static xmlXPathObjectPtr
380 xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt) {
381 xmlXPathObjectPtr result = NULL;
382 xsltStylePreCompPtr precomp;
383 int oldProximityPosition, oldContextSize;
386 if ((ctxt == NULL) || (elem == NULL))
392 #ifdef WITH_XSLT_DEBUG_VARIABLE
393 xsltGenericDebug(xsltGenericDebugContext,
394 "Evaluating global variable %s\n", elem->name);
397 precomp = elem->comp;
398 if (elem->select != NULL) {
399 xmlXPathCompExprPtr comp = NULL;
401 if ((precomp != NULL) && (precomp->comp != NULL)) {
402 comp = precomp->comp;
404 comp = xmlXPathCompile(elem->select);
408 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
409 oldContextSize = ctxt->xpathCtxt->contextSize;
410 oldInst = ctxt->inst;
411 if (precomp != NULL) {
412 ctxt->inst = precomp->inst;
413 ctxt->xpathCtxt->namespaces = precomp->nsList;
414 ctxt->xpathCtxt->nsNr = precomp->nsNr;
417 ctxt->xpathCtxt->namespaces = NULL;
418 ctxt->xpathCtxt->nsNr = 0;
420 ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
421 result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
422 ctxt->xpathCtxt->contextSize = oldContextSize;
423 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
424 ctxt->inst = oldInst;
425 if ((precomp == NULL) || (precomp->comp == NULL))
426 xmlXPathFreeCompExpr(comp);
427 if (result == NULL) {
428 xsltGenericError(xsltGenericErrorContext,
429 "Evaluating global variable %s failed\n", elem->name);
430 #ifdef WITH_XSLT_DEBUG_VARIABLE
431 #ifdef LIBXML_DEBUG_ENABLED
433 if ((xsltGenericDebugContext == stdout) ||
434 (xsltGenericDebugContext == stderr))
435 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
441 if (elem->tree == NULL) {
442 result = xmlXPathNewCString("");
445 * This is a result tree fragment.
447 xmlNodePtr container;
448 xmlNodePtr oldInsert, oldNode;
450 container = xmlNewDocNode(ctxt->output, NULL,
451 (const xmlChar *) "fake", NULL);
452 if (container == NULL)
455 oldInsert = ctxt->insert;
456 oldNode = ctxt->node;
457 ctxt->insert = container;
458 xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, 0);
459 ctxt->insert = oldInsert;
460 ctxt->node = oldNode;
462 result = xmlXPathNewValueTree(container);
463 if (result == NULL) {
464 result = xmlXPathNewCString("");
466 #ifdef WITH_XSLT_DEBUG_VARIABLE
467 #ifdef LIBXML_DEBUG_ENABLED
468 if ((xsltGenericDebugContext == stdout) ||
469 (xsltGenericDebugContext == stderr))
470 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
476 if (result != NULL) {
477 elem->value = result;
484 * xsltEvalGlobalVariables:
485 * @ctxt: the XSLT transformation context
487 * Evaluate the global variables of a stylesheet. This need to be
488 * done on parsed stylesheets before starting to apply transformations
490 * Returns 0 in case of success, -1 in case of error
493 xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
494 xsltStackElemPtr elem;
495 xsltStylesheetPtr style;
500 #ifdef WITH_XSLT_DEBUG_VARIABLE
501 xsltGenericDebug(xsltGenericDebugContext,
502 "Registering global variables\n");
504 ctxt->node = (xmlNodePtr) ctxt->document->doc;
505 ctxt->xpathCtxt->contextSize = 1;
506 ctxt->xpathCtxt->proximityPosition = 1;
509 * Walk the list from the stylesheets and populate the hash table
512 while (style != NULL) {
513 elem = style->variables;
515 #ifdef WITH_XSLT_DEBUG_VARIABLE
516 if ((style->doc != NULL) && (style->doc->URL != NULL)) {
517 xsltGenericDebug(xsltGenericDebugContext,
518 "Registering global variables from %s\n",
523 while (elem != NULL) {
524 xsltStackElemPtr def;
527 * Global variables are stored in the variables pool.
529 def = (xsltStackElemPtr)
530 xmlHashLookup2(ctxt->globalVars,
531 elem->name, elem->nameURI);
535 def = xsltCopyStackElem(elem);
536 res = xmlHashAddEntry2(ctxt->globalVars,
537 elem->name, elem->nameURI, def);
538 } else if ((elem->comp != NULL) &&
539 (elem->comp->type == XSLT_FUNC_VARIABLE)) {
540 xsltGenericError(xsltGenericErrorContext,
541 "Global variable %s already defined\n", elem->name);
546 style = xsltNextImport(style);
550 * This part does the actual evaluation
552 ctxt->node = (xmlNodePtr) ctxt->document->doc;
553 ctxt->xpathCtxt->contextSize = 1;
554 ctxt->xpathCtxt->proximityPosition = 1;
555 xmlHashScan(ctxt->globalVars,
556 (xmlHashScanner) xsltEvalGlobalVariable, ctxt);
562 * xsltRegisterGlobalVariable:
563 * @style: the XSLT transformation context
564 * @name: the variable name
565 * @ns_uri: the variable namespace URI
566 * @select: the expression which need to be evaluated to generate a value
567 * @tree: the subtree if select is NULL
568 * @comp: the precompiled value
569 * @value: the string value if available
571 * Register a new variable value. If @value is NULL it unregisters
574 * Returns 0 in case of success, -1 in case of error
577 xsltRegisterGlobalVariable(xsltStylesheetPtr style, const xmlChar *name,
578 const xmlChar *ns_uri, const xmlChar *select,
579 xmlNodePtr tree, xsltStylePreCompPtr comp,
580 const xmlChar *value) {
581 xsltStackElemPtr elem, tmp;
589 #ifdef WITH_XSLT_DEBUG_VARIABLE
590 if (comp->type == XSLT_FUNC_PARAM)
591 xsltGenericDebug(xsltGenericDebugContext,
592 "Defining global param %s\n", name);
594 xsltGenericDebug(xsltGenericDebugContext,
595 "Defining global variable %s\n", name);
598 elem = xsltNewStackElem();
602 elem->name = xmlStrdup(name);
603 elem->select = xmlStrdup(select);
605 elem->nameURI = xmlStrdup(ns_uri);
607 tmp = style->variables;
610 style->variables = elem;
612 while (tmp->next != NULL)
619 elem->value = xmlXPathNewString(value);
625 * xsltEvalUserParams:
626 * @ctxt: the XSLT transformation context
627 * @params: a NULL terminated arry of parameters names/values tuples
629 * Evaluate the global variables of a stylesheet. This need to be
630 * done on parsed stylesheets before starting to apply transformations
632 * Returns 0 in case of success, -1 in case of error
635 xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) {
636 xsltStylesheetPtr style;
639 const xmlChar *value;
640 xmlChar *ncname, *prefix;
642 xmlXPathCompExprPtr comp;
643 xmlXPathObjectPtr result;
644 int oldProximityPosition, oldContextSize;
652 while (params[indx] != NULL) {
653 name = (const xmlChar *)params[indx++];
654 value = (const xmlChar *)params[indx++];
655 if ((name == NULL) || (value == NULL))
658 #ifdef WITH_XSLT_DEBUG_VARIABLE
659 xsltGenericDebug(xsltGenericDebugContext,
660 "Evaluating user parameter %s=%s\n", name, value);
666 ncname = xmlSplitQName2(name, &prefix);
668 if (ncname != NULL) {
669 if (prefix != NULL) {
672 ns = xmlSearchNs(style->doc, xmlDocGetRootElement(style->doc),
675 xsltGenericError(xsltGenericErrorContext,
676 "user param : no namespace bound to prefix %s\n", prefix);
688 ncname = xmlStrdup(name);
695 comp = xmlXPathCompile(value);
697 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
698 oldContextSize = ctxt->xpathCtxt->contextSize;
699 ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
702 * There is really no in scope namespace for parameters on the
705 ctxt->xpathCtxt->namespaces = NULL;
706 ctxt->xpathCtxt->nsNr = 0;
707 result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
708 ctxt->xpathCtxt->contextSize = oldContextSize;
709 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
710 xmlXPathFreeCompExpr(comp);
712 if (result == NULL) {
713 xsltGenericError(xsltGenericErrorContext,
714 "Evaluating user parameter %s failed\n", name);
716 xsltStackElemPtr elem;
719 #ifdef WITH_XSLT_DEBUG_VARIABLE
720 #ifdef LIBXML_DEBUG_ENABLED
721 if ((xsltGenericDebugContext == stdout) ||
722 (xsltGenericDebugContext == stderr))
723 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
728 elem = xsltNewStackElem();
730 elem->name = xmlStrdup(ncname);
732 elem->select = xmlStrdup(value);
736 elem->nameURI = xmlStrdup(href);
739 elem->value = result;
742 * Global parameters are stored in the XPath context
745 res = xmlHashAddEntry2(ctxt->globalVars,
748 xsltFreeStackElem(elem);
749 xsltGenericError(xsltGenericErrorContext,
750 "Global parameter %s already defined\n", ncname);
761 * @ctxt: the XSLT transformation context
762 * @comp: the precompiled form
763 * @tree: the tree if select is NULL
765 * Computes a new variable value.
767 * Returns the xsltStackElemPtr or NULL in case of error
769 static xsltStackElemPtr
770 xsltBuildVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
772 xsltStackElemPtr elem;
774 #ifdef WITH_XSLT_DEBUG_VARIABLE
775 xsltGenericDebug(xsltGenericDebugContext,
776 "Building variable %s", comp->name);
777 if (comp->select != NULL)
778 xsltGenericDebug(xsltGenericDebugContext,
779 " select %s", comp->select);
780 xsltGenericDebug(xsltGenericDebugContext, "\n");
783 elem = xsltNewStackElem();
787 elem->name = xmlStrdup(comp->name);
788 if (comp->select != NULL)
789 elem->select = xmlStrdup(comp->select);
793 elem->nameURI = xmlStrdup(comp->ns);
795 if (elem->computed == 0) {
796 elem->value = xsltEvalVariable(ctxt, elem, comp);
797 if (elem->value != NULL)
804 * xsltRegisterVariable:
805 * @ctxt: the XSLT transformation context
806 * @name: the variable name
807 * @ns_uri: the variable namespace URI
808 * @select: the expression which need to be evaluated to generate a value
809 * @tree: the tree if select is NULL
810 * @param: this is a parameter actually
812 * Computes and register a new variable value.
814 * Returns 0 in case of success, -1 in case of error
817 xsltRegisterVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
818 xmlNodePtr tree, int param) {
819 xsltStackElemPtr elem;
821 if (xsltCheckStackElem(ctxt, comp->name, comp->ns) != 0) {
823 xsltGenericError(xsltGenericErrorContext,
824 "xsl:variable : redefining %s\n", comp->name);
826 #ifdef WITH_XSLT_DEBUG_VARIABLE
828 xsltGenericDebug(xsltGenericDebugContext,
829 "param %s defined by caller", comp->name);
833 elem = xsltBuildVariable(ctxt, comp, tree);
834 xsltAddStackElem(ctxt, elem);
839 * xsltGlobalVariableLookup:
840 * @ctxt: the XSLT transformation context
841 * @name: the variable name
842 * @ns_uri: the variable namespace URI
844 * Search in the Variable array of the context for the given
847 * Returns the value or NULL if not found
849 static xmlXPathObjectPtr
850 xsltGlobalVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
851 const xmlChar *ns_uri) {
852 xsltStackElemPtr elem;
853 xmlXPathObjectPtr ret = NULL;
856 * Lookup the global variables in XPath global variable hash table
858 if ((ctxt->xpathCtxt == NULL) || (ctxt->globalVars == NULL))
860 elem = (xsltStackElemPtr)
861 xmlHashLookup2(ctxt->globalVars, name, ns_uri);
863 #ifdef WITH_XSLT_DEBUG_VARIABLE
864 xsltGenericDebug(xsltGenericDebugContext,
865 "global variable not found %s\n", name);
869 if (elem->computed == 0)
870 ret = xsltEvalGlobalVariable(elem, ctxt);
873 return(xmlXPathObjectCopy(ret));
877 * xsltVariableLookup:
878 * @ctxt: the XSLT transformation context
879 * @name: the variable name
880 * @ns_uri: the variable namespace URI
882 * Search in the Variable array of the context for the given
885 * Returns the value or NULL if not found
888 xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
889 const xmlChar *ns_uri) {
890 xsltStackElemPtr elem;
895 elem = xsltStackLookup(ctxt, name, ns_uri);
897 return(xsltGlobalVariableLookup(ctxt, name, ns_uri));
899 if (elem->computed == 0) {
900 #ifdef WITH_XSLT_DEBUG_VARIABLE
901 xsltGenericDebug(xsltGenericDebugContext,
902 "uncomputed variable %s\n", name);
904 elem->value = xsltEvalVariable(ctxt, elem, NULL);
907 if (elem->value != NULL)
908 return(xmlXPathObjectCopy(elem->value));
909 #ifdef WITH_XSLT_DEBUG_VARIABLE
910 xsltGenericDebug(xsltGenericDebugContext,
911 "variable not found %s\n", name);
917 * xsltParseStylesheetCallerParam:
918 * @ctxt: the XSLT transformation context
919 * @cur: the "param" element
921 * parse an XSLT transformation param declaration, compute
922 * its value but doesn't record it.
924 * It returns the new xsltStackElemPtr or NULL
928 xsltParseStylesheetCallerParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
929 xmlNodePtr tree = NULL;
930 xsltStackElemPtr elem = NULL;
931 xsltStylePreCompPtr comp;
933 if ((cur == NULL) || (ctxt == NULL))
935 comp = (xsltStylePreCompPtr) cur->_private;
937 xsltGenericError(xsltGenericErrorContext,
938 "xsl:param : compilation error\n");
942 if (comp->name == NULL) {
943 xsltGenericError(xsltGenericErrorContext,
944 "xsl:param : missing name attribute\n");
948 #ifdef WITH_XSLT_DEBUG_VARIABLE
949 xsltGenericDebug(xsltGenericDebugContext,
950 "Handling param %s\n", comp->name);
953 if (comp->select == NULL) {
954 tree = cur->children;
956 #ifdef WITH_XSLT_DEBUG_VARIABLE
957 xsltGenericDebug(xsltGenericDebugContext,
958 " select %s\n", comp->select);
963 elem = xsltBuildVariable(ctxt, comp, tree);
969 * xsltParseGlobalVariable:
970 * @style: the XSLT stylesheet
971 * @cur: the "variable" element
973 * parse an XSLT transformation variable declaration and record
978 xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur) {
979 xsltStylePreCompPtr comp;
981 if ((cur == NULL) || (style == NULL))
984 xsltStylePreCompute(style, cur);
985 comp = (xsltStylePreCompPtr) cur->_private;
987 xsltGenericError(xsltGenericErrorContext,
988 "xsl:variable : compilation had failed\n");
992 if (comp->name == NULL) {
993 xsltGenericError(xsltGenericErrorContext,
994 "xsl:variable : missing name attribute\n");
998 #ifdef WITH_XSLT_DEBUG_VARIABLE
999 xsltGenericDebug(xsltGenericDebugContext,
1000 "Registering global variable %s\n", comp->name);
1003 xsltRegisterGlobalVariable(style, comp->name, comp->ns, comp->select,
1004 cur->children, comp, NULL);
1008 * xsltParseGlobalParam:
1009 * @style: the XSLT stylesheet
1010 * @cur: the "param" element
1012 * parse an XSLT transformation param declaration and record
1017 xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
1018 xsltStylePreCompPtr comp;
1020 if ((cur == NULL) || (style == NULL))
1023 xsltStylePreCompute(style, cur);
1024 comp = (xsltStylePreCompPtr) cur->_private;
1026 xsltGenericError(xsltGenericErrorContext,
1027 "xsl:param : compilation had failed\n");
1031 if (comp->name == NULL) {
1032 xsltGenericError(xsltGenericErrorContext,
1033 "xsl:param : missing name attribute\n");
1037 #ifdef WITH_XSLT_DEBUG_VARIABLE
1038 xsltGenericDebug(xsltGenericDebugContext,
1039 "Registering global param %s\n", comp->name);
1042 xsltRegisterGlobalVariable(style, comp->name, comp->ns, comp->select,
1043 cur->children, comp, NULL);
1047 * xsltParseStylesheetVariable:
1048 * @ctxt: the XSLT transformation context
1049 * @cur: the "variable" element
1051 * parse an XSLT transformation variable declaration and record
1056 xsltParseStylesheetVariable(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
1057 xsltStylePreCompPtr comp;
1059 if ((cur == NULL) || (ctxt == NULL))
1062 comp = (xsltStylePreCompPtr) cur->_private;
1064 xsltGenericError(xsltGenericErrorContext,
1065 "xsl:variable : compilation had failed\n");
1069 if (comp->name == NULL) {
1070 xsltGenericError(xsltGenericErrorContext,
1071 "xsl:variable : missing name attribute\n");
1075 #ifdef WITH_XSLT_DEBUG_VARIABLE
1076 xsltGenericDebug(xsltGenericDebugContext,
1077 "Registering variable %s\n", comp->name);
1080 xsltRegisterVariable(ctxt, comp, cur->children, 0);
1084 * xsltParseStylesheetParam:
1085 * @ctxt: the XSLT transformation context
1086 * @cur: the "param" element
1088 * parse an XSLT transformation param declaration and record
1093 xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
1094 xsltStylePreCompPtr comp;
1096 if ((cur == NULL) || (ctxt == NULL))
1099 comp = (xsltStylePreCompPtr) cur->_private;
1101 xsltGenericError(xsltGenericErrorContext,
1102 "xsl:param : compilation had failed\n");
1106 if (comp->name == NULL) {
1107 xsltGenericError(xsltGenericErrorContext,
1108 "xsl:param : missing name attribute\n");
1112 #ifdef WITH_XSLT_DEBUG_VARIABLE
1113 xsltGenericDebug(xsltGenericDebugContext,
1114 "Registering param %s\n", comp->name);
1117 xsltRegisterVariable(ctxt, comp, cur->children, 1);
1121 * xsltFreeGlobalVariables:
1122 * @ctxt: the XSLT transformation context
1124 * Free up the data associated to the global variables
1129 xsltFreeGlobalVariables(xsltTransformContextPtr ctxt) {
1130 xmlHashFree(ctxt->globalVars, (xmlHashDeallocator) xsltFreeStackElem);
1134 * xsltXPathVariableLookup:
1135 * @ctxt: a void * but the the XSLT transformation context actually
1136 * @name: the variable name
1137 * @ns_uri: the variable namespace URI
1139 * This is the entry point when a varibale is needed by the XPath
1142 * Returns the value or NULL if not found
1145 xsltXPathVariableLookup(void *ctxt, const xmlChar *name,
1146 const xmlChar *ns_uri) {
1147 xsltTransformContextPtr context;
1148 xmlXPathObjectPtr ret;
1150 if ((ctxt == NULL) || (name == NULL))
1153 #ifdef WITH_XSLT_DEBUG_VARIABLE
1154 xsltGenericDebug(xsltGenericDebugContext,
1155 "Lookup variable %s\n", name);
1157 context = (xsltTransformContextPtr) ctxt;
1158 ret = xsltVariableLookup(context, name, ns_uri);
1160 xsltGenericError(xsltGenericErrorContext,
1161 "unregistered variable %s\n", name);
1163 #ifdef WITH_XSLT_DEBUG_VARIABLE
1165 xsltGenericDebug(xsltGenericDebugContext,
1166 "found variable %s\n", name);