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 "xsltCopyStackElem : 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) || (ctxt->varsNr == 0))
237 * Do the lookup from the top of the stack, but
238 * don't use params being computed in a call-param
242 for (i = ctxt->varsNr; i > ctxt->varsBase; i--) {
243 cur = ctxt->varsTab[i-1];
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.
274 * @precomp: pointer to precompiled data
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;
287 xmlNsPtr *oldNamespaces;
289 if ((ctxt == NULL) || (elem == NULL))
292 #ifdef WITH_XSLT_DEBUG_VARIABLE
293 xsltGenericDebug(xsltGenericDebugContext,
294 "Evaluating variable %s\n", elem->name);
296 if (elem->select != NULL) {
297 xmlXPathCompExprPtr comp = NULL;
299 if ((precomp != NULL) && (precomp->comp != NULL)) {
300 comp = precomp->comp;
302 comp = xmlXPathCompile(elem->select);
306 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
307 oldContextSize = ctxt->xpathCtxt->contextSize;
308 ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
309 oldInst = ctxt->inst;
310 oldNsNr = ctxt->xpathCtxt->nsNr;
311 oldNamespaces = ctxt->xpathCtxt->namespaces;
312 if (precomp != NULL) {
313 ctxt->inst = precomp->inst;
314 ctxt->xpathCtxt->namespaces = precomp->nsList;
315 ctxt->xpathCtxt->nsNr = precomp->nsNr;
318 ctxt->xpathCtxt->namespaces = NULL;
319 ctxt->xpathCtxt->nsNr = 0;
321 result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
322 ctxt->xpathCtxt->contextSize = oldContextSize;
323 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
324 ctxt->xpathCtxt->nsNr = oldNsNr;
325 ctxt->xpathCtxt->namespaces = oldNamespaces;
326 ctxt->inst = oldInst;
327 if ((precomp == NULL) || (precomp->comp == NULL))
328 xmlXPathFreeCompExpr(comp);
329 if (result == NULL) {
330 xsltGenericError(xsltGenericErrorContext,
331 "Evaluating variable %s failed\n", elem->name);
332 #ifdef WITH_XSLT_DEBUG_VARIABLE
333 #ifdef LIBXML_DEBUG_ENABLED
335 if ((xsltGenericDebugContext == stdout) ||
336 (xsltGenericDebugContext == stderr))
337 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
343 if (elem->tree == NULL) {
344 result = xmlXPathNewCString("");
347 * This is a result tree fragment.
349 xmlNodePtr container;
350 xmlNodePtr oldInsert;
352 container = xmlNewDocNode(ctxt->output, NULL,
353 (const xmlChar *) "fake", NULL);
354 if (container == NULL)
357 oldInsert = ctxt->insert;
358 ctxt->insert = container;
359 xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, NULL, NULL);
360 ctxt->insert = oldInsert;
362 result = xmlXPathNewValueTree(container);
363 if (result == NULL) {
364 result = xmlXPathNewCString("");
366 #ifdef WITH_XSLT_DEBUG_VARIABLE
367 #ifdef LIBXML_DEBUG_ENABLED
368 if ((xsltGenericDebugContext == stdout) ||
369 (xsltGenericDebugContext == stderr))
370 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
380 * xsltEvalGlobalVariable:
381 * @elem: the variable or parameter.
382 * @ctxt: the XSLT transformation context
384 * Evaluate a global variable value.
386 * Returns the XPath Object value or NULL in case of error
388 static xmlXPathObjectPtr
389 xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt) {
390 xmlXPathObjectPtr result = NULL;
391 xsltStylePreCompPtr precomp;
392 int oldProximityPosition, oldContextSize;
395 xmlNsPtr *oldNamespaces;
397 if ((ctxt == NULL) || (elem == NULL))
403 #ifdef WITH_XSLT_DEBUG_VARIABLE
404 xsltGenericDebug(xsltGenericDebugContext,
405 "Evaluating global variable %s\n", elem->name);
408 precomp = elem->comp;
409 if (elem->select != NULL) {
410 xmlXPathCompExprPtr comp = NULL;
412 if ((precomp != NULL) && (precomp->comp != NULL)) {
413 comp = precomp->comp;
415 comp = xmlXPathCompile(elem->select);
419 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
420 oldContextSize = ctxt->xpathCtxt->contextSize;
421 oldInst = ctxt->inst;
422 oldNsNr = ctxt->xpathCtxt->nsNr;
423 oldNamespaces = ctxt->xpathCtxt->namespaces;
424 if (precomp != NULL) {
425 ctxt->inst = precomp->inst;
426 ctxt->xpathCtxt->namespaces = precomp->nsList;
427 ctxt->xpathCtxt->nsNr = precomp->nsNr;
430 ctxt->xpathCtxt->namespaces = NULL;
431 ctxt->xpathCtxt->nsNr = 0;
433 ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
434 result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
435 ctxt->xpathCtxt->contextSize = oldContextSize;
436 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
437 ctxt->inst = oldInst;
438 ctxt->xpathCtxt->nsNr = oldNsNr;
439 ctxt->xpathCtxt->namespaces = oldNamespaces;
440 if ((precomp == NULL) || (precomp->comp == NULL))
441 xmlXPathFreeCompExpr(comp);
442 if (result == NULL) {
443 xsltGenericError(xsltGenericErrorContext,
444 "Evaluating global variable %s failed\n", elem->name);
445 #ifdef WITH_XSLT_DEBUG_VARIABLE
446 #ifdef LIBXML_DEBUG_ENABLED
448 if ((xsltGenericDebugContext == stdout) ||
449 (xsltGenericDebugContext == stderr))
450 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
456 if (elem->tree == NULL) {
457 result = xmlXPathNewCString("");
460 * This is a result tree fragment.
462 xmlNodePtr container;
463 xmlNodePtr oldInsert;
465 container = xmlNewDocNode(ctxt->output, NULL,
466 (const xmlChar *) "fake", NULL);
467 if (container == NULL)
470 oldInsert = ctxt->insert;
471 ctxt->insert = container;
472 xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, NULL, NULL);
473 ctxt->insert = oldInsert;
475 result = xmlXPathNewValueTree(container);
476 if (result == NULL) {
477 result = xmlXPathNewCString("");
479 #ifdef WITH_XSLT_DEBUG_VARIABLE
480 #ifdef LIBXML_DEBUG_ENABLED
481 if ((xsltGenericDebugContext == stdout) ||
482 (xsltGenericDebugContext == stderr))
483 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
489 if (result != NULL) {
490 elem->value = result;
497 * xsltEvalGlobalVariables:
498 * @ctxt: the XSLT transformation context
500 * Evaluate the global variables of a stylesheet. This need to be
501 * done on parsed stylesheets before starting to apply transformations
503 * Returns 0 in case of success, -1 in case of error
506 xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
507 xsltStackElemPtr elem;
508 xsltStylesheetPtr style;
513 #ifdef WITH_XSLT_DEBUG_VARIABLE
514 xsltGenericDebug(xsltGenericDebugContext,
515 "Registering global variables\n");
517 ctxt->node = (xmlNodePtr) ctxt->document->doc;
518 ctxt->xpathCtxt->contextSize = 1;
519 ctxt->xpathCtxt->proximityPosition = 1;
522 * Walk the list from the stylesheets and populate the hash table
525 while (style != NULL) {
526 elem = style->variables;
528 #ifdef WITH_XSLT_DEBUG_VARIABLE
529 if ((style->doc != NULL) && (style->doc->URL != NULL)) {
530 xsltGenericDebug(xsltGenericDebugContext,
531 "Registering global variables from %s\n",
536 while (elem != NULL) {
537 xsltStackElemPtr def;
540 * Global variables are stored in the variables pool.
542 def = (xsltStackElemPtr)
543 xmlHashLookup2(ctxt->globalVars,
544 elem->name, elem->nameURI);
548 def = xsltCopyStackElem(elem);
549 res = xmlHashAddEntry2(ctxt->globalVars,
550 elem->name, elem->nameURI, def);
551 } else if ((elem->comp != NULL) &&
552 (elem->comp->type == XSLT_FUNC_VARIABLE)) {
553 xsltGenericError(xsltGenericErrorContext,
554 "Global variable %s already defined\n", elem->name);
559 style = xsltNextImport(style);
563 * This part does the actual evaluation
565 ctxt->node = (xmlNodePtr) ctxt->document->doc;
566 ctxt->xpathCtxt->contextSize = 1;
567 ctxt->xpathCtxt->proximityPosition = 1;
568 xmlHashScan(ctxt->globalVars,
569 (xmlHashScanner) xsltEvalGlobalVariable, ctxt);
575 * xsltRegisterGlobalVariable:
576 * @style: the XSLT transformation context
577 * @name: the variable name
578 * @ns_uri: the variable namespace URI
579 * @select: the expression which need to be evaluated to generate a value
580 * @tree: the subtree if select is NULL
581 * @comp: the precompiled value
582 * @value: the string value if available
584 * Register a new variable value. If @value is NULL it unregisters
587 * Returns 0 in case of success, -1 in case of error
590 xsltRegisterGlobalVariable(xsltStylesheetPtr style, const xmlChar *name,
591 const xmlChar *ns_uri, const xmlChar *select,
592 xmlNodePtr tree, xsltStylePreCompPtr comp,
593 const xmlChar *value) {
594 xsltStackElemPtr elem, tmp;
602 #ifdef WITH_XSLT_DEBUG_VARIABLE
603 if (comp->type == XSLT_FUNC_PARAM)
604 xsltGenericDebug(xsltGenericDebugContext,
605 "Defining global param %s\n", name);
607 xsltGenericDebug(xsltGenericDebugContext,
608 "Defining global variable %s\n", name);
611 elem = xsltNewStackElem();
615 elem->name = xmlStrdup(name);
616 elem->select = xmlStrdup(select);
618 elem->nameURI = xmlStrdup(ns_uri);
620 tmp = style->variables;
623 style->variables = elem;
625 while (tmp->next != NULL)
632 elem->value = xmlXPathNewString(value);
638 * xsltEvalUserParams:
639 * @ctxt: the XSLT transformation context
640 * @params: a NULL terminated arry of parameters names/values tuples
642 * Evaluate the global variables of a stylesheet. This needs to be
643 * done on parsed stylesheets before starting to apply transformations
645 * Returns 0 in case of success, -1 in case of error
648 xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) {
649 xsltStylesheetPtr style;
652 const xmlChar *value;
653 xmlChar *ncname, *prefix;
655 xmlXPathCompExprPtr comp;
656 xmlXPathObjectPtr result;
657 int oldProximityPosition, oldContextSize;
659 xmlNsPtr *oldNamespaces;
667 while (params[indx] != NULL) {
668 name = (const xmlChar *)params[indx++];
669 value = (const xmlChar *)params[indx++];
670 if ((name == NULL) || (value == NULL))
673 #ifdef WITH_XSLT_DEBUG_VARIABLE
674 xsltGenericDebug(xsltGenericDebugContext,
675 "Evaluating user parameter %s=%s\n", name, value);
681 ncname = xmlSplitQName2(name, &prefix);
683 if (ncname != NULL) {
684 if (prefix != NULL) {
687 ns = xmlSearchNs(style->doc, xmlDocGetRootElement(style->doc),
690 xsltGenericError(xsltGenericErrorContext,
691 "user param : no namespace bound to prefix %s\n", prefix);
703 ncname = xmlStrdup(name);
710 comp = xmlXPathCompile(value);
712 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
713 oldContextSize = ctxt->xpathCtxt->contextSize;
714 ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
717 * There is really no in scope namespace for parameters on the
720 oldNsNr = ctxt->xpathCtxt->nsNr;
721 oldNamespaces = ctxt->xpathCtxt->namespaces;
722 ctxt->xpathCtxt->namespaces = NULL;
723 ctxt->xpathCtxt->nsNr = 0;
724 result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
725 ctxt->xpathCtxt->contextSize = oldContextSize;
726 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
727 ctxt->xpathCtxt->nsNr = oldNsNr;
728 ctxt->xpathCtxt->namespaces = oldNamespaces;
729 xmlXPathFreeCompExpr(comp);
731 if (result == NULL) {
732 xsltGenericError(xsltGenericErrorContext,
733 "Evaluating user parameter %s failed\n", name);
735 xsltStackElemPtr elem;
738 #ifdef WITH_XSLT_DEBUG_VARIABLE
739 #ifdef LIBXML_DEBUG_ENABLED
740 if ((xsltGenericDebugContext == stdout) ||
741 (xsltGenericDebugContext == stderr))
742 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
747 elem = xsltNewStackElem();
749 elem->name = xmlStrdup(ncname);
751 elem->select = xmlStrdup(value);
755 elem->nameURI = xmlStrdup(href);
758 elem->value = result;
761 * Global parameters are stored in the XPath context
764 res = xmlHashAddEntry2(ctxt->globalVars,
767 xsltFreeStackElem(elem);
768 xsltGenericError(xsltGenericErrorContext,
769 "Global parameter %s already defined\n", ncname);
780 * @ctxt: the XSLT transformation context
781 * @comp: the precompiled form
782 * @tree: the tree if select is NULL
784 * Computes a new variable value.
786 * Returns the xsltStackElemPtr or NULL in case of error
788 static xsltStackElemPtr
789 xsltBuildVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
791 xsltStackElemPtr elem;
793 #ifdef WITH_XSLT_DEBUG_VARIABLE
794 xsltGenericDebug(xsltGenericDebugContext,
795 "Building variable %s", comp->name);
796 if (comp->select != NULL)
797 xsltGenericDebug(xsltGenericDebugContext,
798 " select %s", comp->select);
799 xsltGenericDebug(xsltGenericDebugContext, "\n");
802 elem = xsltNewStackElem();
806 elem->name = xmlStrdup(comp->name);
807 if (comp->select != NULL)
808 elem->select = xmlStrdup(comp->select);
812 elem->nameURI = xmlStrdup(comp->ns);
814 if (elem->computed == 0) {
815 elem->value = xsltEvalVariable(ctxt, elem, comp);
816 if (elem->value != NULL)
823 * xsltRegisterVariable:
824 * @ctxt: the XSLT transformation context
825 * @comp: pointer to precompiled data
826 * @tree: the tree if select is NULL
827 * @param: this is a parameter actually
829 * Computes and register a new variable value.
831 * Returns 0 in case of success, -1 in case of error
834 xsltRegisterVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
835 xmlNodePtr tree, int param) {
836 xsltStackElemPtr elem;
838 if (xsltCheckStackElem(ctxt, comp->name, comp->ns) != 0) {
840 xsltGenericError(xsltGenericErrorContext,
841 "xsl:variable : redefining %s\n", comp->name);
843 #ifdef WITH_XSLT_DEBUG_VARIABLE
845 xsltGenericDebug(xsltGenericDebugContext,
846 "param %s defined by caller\n", comp->name);
850 elem = xsltBuildVariable(ctxt, comp, tree);
851 xsltAddStackElem(ctxt, elem);
856 * xsltGlobalVariableLookup:
857 * @ctxt: the XSLT transformation context
858 * @name: the variable name
859 * @ns_uri: the variable namespace URI
861 * Search in the Variable array of the context for the given
864 * Returns the value or NULL if not found
866 static xmlXPathObjectPtr
867 xsltGlobalVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
868 const xmlChar *ns_uri) {
869 xsltStackElemPtr elem;
870 xmlXPathObjectPtr ret = NULL;
873 * Lookup the global variables in XPath global variable hash table
875 if ((ctxt->xpathCtxt == NULL) || (ctxt->globalVars == NULL))
877 elem = (xsltStackElemPtr)
878 xmlHashLookup2(ctxt->globalVars, name, ns_uri);
880 #ifdef WITH_XSLT_DEBUG_VARIABLE
881 xsltGenericDebug(xsltGenericDebugContext,
882 "global variable not found %s\n", name);
886 if (elem->computed == 0)
887 ret = xsltEvalGlobalVariable(elem, ctxt);
890 return(xmlXPathObjectCopy(ret));
894 * xsltVariableLookup:
895 * @ctxt: the XSLT transformation context
896 * @name: the variable name
897 * @ns_uri: the variable namespace URI
899 * Search in the Variable array of the context for the given
902 * Returns the value or NULL if not found
905 xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
906 const xmlChar *ns_uri) {
907 xsltStackElemPtr elem;
912 elem = xsltStackLookup(ctxt, name, ns_uri);
914 return(xsltGlobalVariableLookup(ctxt, name, ns_uri));
916 if (elem->computed == 0) {
917 #ifdef WITH_XSLT_DEBUG_VARIABLE
918 xsltGenericDebug(xsltGenericDebugContext,
919 "uncomputed variable %s\n", name);
921 elem->value = xsltEvalVariable(ctxt, elem, NULL);
924 if (elem->value != NULL)
925 return(xmlXPathObjectCopy(elem->value));
926 #ifdef WITH_XSLT_DEBUG_VARIABLE
927 xsltGenericDebug(xsltGenericDebugContext,
928 "variable not found %s\n", name);
934 * xsltParseStylesheetCallerParam:
935 * @ctxt: the XSLT transformation context
936 * @cur: the "param" element
938 * parse an XSLT transformation param declaration, compute
939 * its value but doesn't record it.
941 * It returns the new xsltStackElemPtr or NULL
945 xsltParseStylesheetCallerParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
946 xmlNodePtr tree = NULL;
947 xsltStackElemPtr elem = NULL;
948 xsltStylePreCompPtr comp;
950 if ((cur == NULL) || (ctxt == NULL))
952 comp = (xsltStylePreCompPtr) cur->_private;
954 xsltGenericError(xsltGenericErrorContext,
955 "xsl:param : compilation error\n");
959 if (comp->name == NULL) {
960 xsltGenericError(xsltGenericErrorContext,
961 "xsl:param : missing name attribute\n");
965 #ifdef WITH_XSLT_DEBUG_VARIABLE
966 xsltGenericDebug(xsltGenericDebugContext,
967 "Handling param %s\n", comp->name);
970 if (comp->select == NULL) {
971 tree = cur->children;
973 #ifdef WITH_XSLT_DEBUG_VARIABLE
974 xsltGenericDebug(xsltGenericDebugContext,
975 " select %s\n", comp->select);
980 elem = xsltBuildVariable(ctxt, comp, tree);
986 * xsltParseGlobalVariable:
987 * @style: the XSLT stylesheet
988 * @cur: the "variable" element
990 * parse an XSLT transformation variable declaration and record
995 xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur) {
996 xsltStylePreCompPtr comp;
998 if ((cur == NULL) || (style == NULL))
1001 xsltStylePreCompute(style, cur);
1002 comp = (xsltStylePreCompPtr) cur->_private;
1004 xsltGenericError(xsltGenericErrorContext,
1005 "xsl:variable : compilation failed\n");
1009 if (comp->name == NULL) {
1010 xsltGenericError(xsltGenericErrorContext,
1011 "xsl:variable : missing name attribute\n");
1015 #ifdef WITH_XSLT_DEBUG_VARIABLE
1016 xsltGenericDebug(xsltGenericDebugContext,
1017 "Registering global variable %s\n", comp->name);
1020 xsltRegisterGlobalVariable(style, comp->name, comp->ns, comp->select,
1021 cur->children, comp, NULL);
1025 * xsltParseGlobalParam:
1026 * @style: the XSLT stylesheet
1027 * @cur: the "param" element
1029 * parse an XSLT transformation param declaration and record
1034 xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
1035 xsltStylePreCompPtr comp;
1037 if ((cur == NULL) || (style == NULL))
1040 xsltStylePreCompute(style, cur);
1041 comp = (xsltStylePreCompPtr) cur->_private;
1043 xsltGenericError(xsltGenericErrorContext,
1044 "xsl:param : compilation failed\n");
1048 if (comp->name == NULL) {
1049 xsltGenericError(xsltGenericErrorContext,
1050 "xsl:param : missing name attribute\n");
1054 #ifdef WITH_XSLT_DEBUG_VARIABLE
1055 xsltGenericDebug(xsltGenericDebugContext,
1056 "Registering global param %s\n", comp->name);
1059 xsltRegisterGlobalVariable(style, comp->name, comp->ns, comp->select,
1060 cur->children, comp, NULL);
1064 * xsltParseStylesheetVariable:
1065 * @ctxt: the XSLT transformation context
1066 * @cur: the "variable" element
1068 * parse an XSLT transformation variable declaration and record
1073 xsltParseStylesheetVariable(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
1074 xsltStylePreCompPtr comp;
1076 if ((cur == NULL) || (ctxt == NULL))
1079 comp = (xsltStylePreCompPtr) cur->_private;
1081 xsltGenericError(xsltGenericErrorContext,
1082 "xsl:variable : compilation failed\n");
1086 if (comp->name == NULL) {
1087 xsltGenericError(xsltGenericErrorContext,
1088 "xsl:variable : missing name attribute\n");
1092 #ifdef WITH_XSLT_DEBUG_VARIABLE
1093 xsltGenericDebug(xsltGenericDebugContext,
1094 "Registering variable %s\n", comp->name);
1097 xsltRegisterVariable(ctxt, comp, cur->children, 0);
1101 * xsltParseStylesheetParam:
1102 * @ctxt: the XSLT transformation context
1103 * @cur: the "param" element
1105 * parse an XSLT transformation param declaration and record
1110 xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
1111 xsltStylePreCompPtr comp;
1113 if ((cur == NULL) || (ctxt == NULL))
1116 comp = (xsltStylePreCompPtr) cur->_private;
1118 xsltGenericError(xsltGenericErrorContext,
1119 "xsl:param : compilation failed\n");
1123 if (comp->name == NULL) {
1124 xsltGenericError(xsltGenericErrorContext,
1125 "xsl:param : missing name attribute\n");
1129 #ifdef WITH_XSLT_DEBUG_VARIABLE
1130 xsltGenericDebug(xsltGenericDebugContext,
1131 "Registering param %s\n", comp->name);
1134 xsltRegisterVariable(ctxt, comp, cur->children, 1);
1138 * xsltFreeGlobalVariables:
1139 * @ctxt: the XSLT transformation context
1141 * Free up the data associated to the global variables
1146 xsltFreeGlobalVariables(xsltTransformContextPtr ctxt) {
1147 xmlHashFree(ctxt->globalVars, (xmlHashDeallocator) xsltFreeStackElem);
1151 * xsltXPathVariableLookup:
1152 * @ctxt: a void * but the the XSLT transformation context actually
1153 * @name: the variable name
1154 * @ns_uri: the variable namespace URI
1156 * This is the entry point when a varibale is needed by the XPath
1159 * Returns the value or NULL if not found
1162 xsltXPathVariableLookup(void *ctxt, const xmlChar *name,
1163 const xmlChar *ns_uri) {
1164 xsltTransformContextPtr context;
1165 xmlXPathObjectPtr ret;
1167 if ((ctxt == NULL) || (name == NULL))
1170 #ifdef WITH_XSLT_DEBUG_VARIABLE
1171 xsltGenericDebug(xsltGenericDebugContext,
1172 "Lookup variable %s\n", name);
1174 context = (xsltTransformContextPtr) ctxt;
1175 ret = xsltVariableLookup(context, name, ns_uri);
1177 xsltGenericError(xsltGenericErrorContext,
1178 "unregistered variable %s\n", name);
1180 #ifdef WITH_XSLT_DEBUG_VARIABLE
1182 xsltGenericDebug(xsltGenericDebugContext,
1183 "found variable %s\n", name);