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"
32 #define DEBUG_VARIABLE
34 /************************************************************************
38 ************************************************************************/
43 * Create a new XSLT ParserContext
45 * Returns the newly allocated xsltParserStackElem or NULL in case of error
47 static xsltStackElemPtr
48 xsltNewStackElem(void) {
51 cur = (xsltStackElemPtr) xmlMalloc(sizeof(xsltStackElem));
53 xsltGenericError(xsltGenericErrorContext,
54 "xsltNewStackElem : malloc failed\n");
57 memset(cur, 0, sizeof(xsltStackElem));
64 * @elem: an XSLT stack element
66 * Free up the memory allocated by @elem
69 xsltFreeStackElem(xsltStackElemPtr elem) {
72 if (elem->name != NULL)
74 if (elem->nameURI != NULL)
75 xmlFree(elem->nameURI);
76 if (elem->select != NULL)
77 xmlFree(elem->select);
78 if (elem->value != NULL)
79 xmlXPathFreeObject(elem->value);
81 memset(elem, -1, sizeof(xsltStackElem));
86 * xsltFreeStackElemList:
87 * @elem: an XSLT stack element
89 * Free up the memory allocated by @elem
92 xsltFreeStackElemList(xsltStackElemPtr elem) {
93 xsltStackElemPtr next;
97 xsltFreeStackElem(elem);
103 * xsltCheckStackElem:
104 * @ctxt: xn XSLT transformation context
105 * @name: the variable name
106 * @nameURI: the variable namespace URI
108 * check wether the variable or param is already defined
110 * Returns 1 if present, 0 if not, -1 in case of failure.
113 xsltCheckStackElem(xsltTransformContextPtr ctxt, const xmlChar *name,
114 const xmlChar *nameURI) {
115 xsltStackElemPtr cur;
117 if ((ctxt == NULL) || (name == NULL))
121 while (cur != NULL) {
122 if (xmlStrEqual(name, cur->name)) {
123 if (((nameURI == NULL) && (cur->nameURI == NULL)) ||
124 ((nameURI != NULL) && (cur->nameURI != NULL) &&
125 (xmlStrEqual(nameURI, cur->nameURI)))) {
136 * @ctxt: xn XSLT transformation context
137 * @elem: a stack element
139 * add a new element at this level of the stack.
141 * Returns 0 in case of success, -1 in case of failure.
144 xsltAddStackElem(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) {
145 if ((ctxt == NULL) || (elem == NULL))
148 elem->next = ctxt->varsTab[ctxt->varsNr - 1];
149 ctxt->varsTab[ctxt->varsNr - 1] = elem;
155 * xsltAddStackElemList:
156 * @ctxt: xn XSLT transformation context
157 * @elems: a stack element list
159 * add the new element list at this level of the stack.
161 * Returns 0 in case of success, -1 in case of failure.
164 xsltAddStackElemList(xsltTransformContextPtr ctxt, xsltStackElemPtr elems) {
165 xsltStackElemPtr cur;
167 if ((ctxt == NULL) || (elems == NULL))
170 /* TODO: check doublons */
171 if (ctxt->varsTab[ctxt->varsNr - 1] != NULL) {
172 cur = ctxt->varsTab[ctxt->varsNr - 1];
173 while (cur->next != NULL)
177 elems->next = ctxt->varsTab[ctxt->varsNr - 1];
178 ctxt->varsTab[ctxt->varsNr - 1] = elems;
186 * @ctxt: an XSLT transformation context
187 * @name: the local part of the name
188 * @nameURI: the URI part of the name
190 * Locate an element in the stack based on its name.
192 static xsltStackElemPtr
193 xsltStackLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
194 const xmlChar *nameURI) {
195 xsltStackElemPtr ret = NULL;
197 xsltStackElemPtr cur;
199 if ((ctxt == NULL) || (name == NULL))
203 * Do the lookup from the top of the stack, but
204 * don't use params being computed in a call-param
206 i = ctxt->varsNr - 1;
209 cur = ctxt->varsTab[i];
210 while (cur != NULL) {
211 if (xmlStrEqual(cur->name, name)) {
212 if (nameURI == NULL) {
213 if (cur->nameURI == NULL) {
217 if ((cur->nameURI != NULL) &&
218 (xmlStrEqual(cur->nameURI, nameURI))) {
230 /************************************************************************
232 * Module interfaces *
234 ************************************************************************/
238 * @ctxt: the XSLT transformation context
239 * @elem: the variable or parameter.
241 * Evaluate a variable value.
243 * Returns 0 in case of success, -1 in case of error
246 xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) {
247 int oldProximityPosition, oldContextSize;
248 if ((ctxt == NULL) || (elem == NULL))
251 #ifdef DEBUG_VARIABLE
252 xsltGenericDebug(xsltGenericDebugContext,
253 "Evaluating variable %s\n", elem->name);
255 if (elem->select != NULL) {
256 xmlXPathCompExprPtr comp;
257 xmlXPathObjectPtr result;
259 comp = xmlXPathCompile(elem->select);
262 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
263 oldContextSize = ctxt->xpathCtxt->contextSize;
264 ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
265 /* TODO: do we need to propagate the namespaces here ? */
266 ctxt->xpathCtxt->namespaces = NULL;
267 ctxt->xpathCtxt->nsNr = 0;
268 result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
269 ctxt->xpathCtxt->contextSize = oldContextSize;
270 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
271 xmlXPathFreeCompExpr(comp);
272 if (result == NULL) {
273 xsltGenericError(xsltGenericErrorContext,
274 "Evaluating variable %s failed\n", elem->name);
276 #ifdef DEBUG_VARIABLE
277 #ifdef LIBXML_DEBUG_ENABLED
278 if ((xsltGenericDebugContext == stdout) ||
279 (xsltGenericDebugContext == stderr))
280 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
284 if (elem->value != NULL)
285 xmlXPathFreeObject(elem->value);
286 elem->value = result;
290 if (elem->tree == NULL) {
291 elem->value = xmlXPathNewCString("");
294 * This is a result tree fragment.
296 xmlNodePtr container;
297 xmlNodePtr oldInsert, oldNode;
299 container = xmlNewDocNode(ctxt->output, NULL,
300 (const xmlChar *) "fake", NULL);
301 if (container == NULL)
304 oldInsert = ctxt->insert;
305 oldNode = ctxt->node;
306 ctxt->insert = container;
307 xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, 0);
308 ctxt->insert = oldInsert;
309 ctxt->node = oldNode;
311 if (elem->value != NULL)
312 xmlXPathFreeObject(elem->value);
313 elem->value = xmlXPathNewValueTree(container);
314 if (elem->value == NULL) {
315 elem->value = xmlXPathNewCString("");
317 #ifdef DEBUG_VARIABLE
318 #ifdef LIBXML_DEBUG_ENABLED
319 if ((xsltGenericDebugContext == stdout) ||
320 (xsltGenericDebugContext == stderr))
321 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
332 * xsltEvalGlobalVariables:
333 * @ctxt: the XSLT transformation context
335 * Evaluate the global variables of a stylesheet. This need to be
336 * done on parsed stylesheets before starting to apply transformations
338 * Returns 0 in case of success, -1 in case of error
341 xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
342 xsltStackElemPtr elem;
343 xsltStylesheetPtr style;
348 #ifdef DEBUG_VARIABLE
349 xsltGenericDebug(xsltGenericDebugContext,
350 "Evaluating global variables\n");
352 ctxt->node = (xmlNodePtr) ctxt->document->doc;
354 while (style != NULL) {
355 elem = style->variables;
357 while (elem != NULL) {
358 if (elem->computed == 0)
359 xsltEvalVariable(ctxt, elem);
363 style = xsltNextImport(style);
369 * xsltRegisterGlobalVariable:
370 * @style: the XSLT transformation context
371 * @name: the variable name
372 * @ns_uri: the variable namespace URI
373 * @select: the expression which need to be evaluated to generate a value
374 * @tree: the subtree if select is NULL
375 * @param: this is a parameter actually
376 * @value: the string value if available
378 * Register a new variable value. If @value is NULL it unregisters
381 * Returns 0 in case of success, -1 in case of error
384 xsltRegisterGlobalVariable(xsltStylesheetPtr style, const xmlChar *name,
385 const xmlChar *ns_uri, const xmlChar *select,
386 xmlNodePtr tree, int param, const xmlChar *value) {
387 xsltStackElemPtr elem;
393 #ifdef DEBUG_VARIABLE
395 xsltGenericDebug(xsltGenericDebugContext,
396 "Defining global param %s\n", name);
398 xsltGenericDebug(xsltGenericDebugContext,
399 "Defining global variable %s\n", name);
401 elem = xsltNewStackElem();
405 elem->type = XSLT_ELEM_PARAM;
407 elem->type = XSLT_ELEM_VARIABLE;
408 elem->name = xmlStrdup(name);
409 elem->select = xmlStrdup(select);
411 elem->nameURI = xmlStrdup(ns_uri);
413 elem->next = style->variables;
414 style->variables = elem;
417 elem->value = xmlXPathNewString(value);
423 * xsltEvalUserParams:
424 * @ctxt: the XSLT transformation context
425 * @params: a NULL terminated arry of parameters names/values tuples
427 * Evaluate the global variables of a stylesheet. This need to be
428 * done on parsed stylesheets before starting to apply transformations
430 * Returns 0 in case of success, -1 in case of error
433 xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) {
434 xsltStylesheetPtr style;
437 const xmlChar *value;
438 xmlChar *ncname, *prefix;
446 while (params[indx] != NULL) {
447 name = (const xmlChar *)params[indx++];
448 value = (const xmlChar *)params[indx++];
449 if ((name == NULL) || (value == NULL))
452 #ifdef DEBUG_VARIABLE
453 xsltGenericDebug(xsltGenericDebugContext,
454 "Evaluating user parameter %s=%s\n", name, value);
456 ncname = xmlSplitQName2(name, &prefix);
457 if (ncname != NULL) {
458 if (prefix != NULL) {
461 ns = xmlSearchNs(style->doc, xmlDocGetRootElement(style->doc),
464 xsltGenericError(xsltGenericErrorContext,
465 "user param : no namespace bound to prefix %s\n", prefix);
467 xsltRegisterGlobalVariable(style, ncname, ns->href, NULL,
472 xsltRegisterGlobalVariable(style, ncname, NULL, NULL, NULL,
477 xsltRegisterGlobalVariable(style, name, NULL, NULL, NULL, 1, value);
487 * @ctxt: the XSLT transformation context
488 * @name: the variable name
489 * @ns_uri: the variable namespace URI
490 * @select: the expression which need to be evaluated to generate a value
491 * @tree: the tree if select is NULL
492 * @param: this is a parameter actually
494 * Computes a new variable value.
496 * Returns the xsltStackElemPtr or NULL in case of error
498 static xsltStackElemPtr
499 xsltBuildVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
500 const xmlChar *ns_uri, const xmlChar *select,
501 xmlNodePtr tree, int param) {
502 xsltStackElemPtr elem;
508 #ifdef DEBUG_VARIABLE
509 xsltGenericDebug(xsltGenericDebugContext,
510 "Building variable %s", name);
512 xsltGenericDebug(xsltGenericDebugContext,
513 " select %s", select);
514 xsltGenericDebug(xsltGenericDebugContext, "\n");
516 elem = xsltNewStackElem();
520 elem->type = XSLT_ELEM_PARAM;
522 elem->type = XSLT_ELEM_VARIABLE;
523 elem->name = xmlStrdup(name);
525 elem->select = xmlStrdup(select);
529 elem->nameURI = xmlStrdup(ns_uri);
531 xsltEvalVariable(ctxt, elem);
536 * xsltRegisterVariable:
537 * @ctxt: the XSLT transformation context
538 * @name: the variable name
539 * @ns_uri: the variable namespace URI
540 * @select: the expression which need to be evaluated to generate a value
541 * @tree: the tree if select is NULL
542 * @param: this is a parameter actually
544 * Computes and register a new variable value.
546 * Returns 0 in case of success, -1 in case of error
549 xsltRegisterVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
550 const xmlChar *ns_uri, const xmlChar *select,
551 xmlNodePtr tree, int param) {
552 xsltStackElemPtr elem;
558 if (xsltCheckStackElem(ctxt, name, ns_uri) != 0) {
560 xsltGenericError(xsltGenericErrorContext,
561 "xsl:variable : redefining %s\n", name);
563 #ifdef DEBUG_VARIABLE
565 xsltGenericDebug(xsltGenericDebugContext,
566 "param %s defined by caller", name);
570 elem = xsltBuildVariable(ctxt, name, ns_uri, select, tree, param);
571 xsltAddStackElem(ctxt, elem);
576 * xsltGlobalVariableLookup:
577 * @ctxt: the XSLT transformation context
578 * @name: the variable name
579 * @ns_uri: the variable namespace URI
581 * Search in the Variable array of the context for the given
584 * Returns the value or NULL if not found
586 static xmlXPathObjectPtr
587 xsltGlobalVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
588 const xmlChar *ns_uri) {
589 xsltStylesheetPtr style;
590 xsltStackElemPtr elem = NULL;
593 while (style != NULL) {
594 elem = style->variables;
596 while (elem != NULL) {
597 if (xmlStrEqual(elem->name, name)) {
598 if (ns_uri == NULL) {
599 if (elem->nameURI == NULL)
602 if ((elem->nameURI != NULL) &&
603 (xmlStrEqual(elem->nameURI, ns_uri)))
610 if (elem != NULL) break;
612 style = xsltNextImport(style);
617 if (!elem->computed) {
618 #ifdef DEBUG_VARIABLE
619 xsltGenericDebug(xsltGenericDebugContext,
620 "uncomputed global variable %s\n", name);
622 xsltEvalVariable(ctxt, elem);
624 if (elem->value != NULL)
625 return(xmlXPathObjectCopy(elem->value));
626 #ifdef DEBUG_VARIABLE
627 xsltGenericDebug(xsltGenericDebugContext,
628 "global variable not found %s\n", name);
634 * xsltVariableLookup:
635 * @ctxt: the XSLT transformation context
636 * @name: the variable name
637 * @ns_uri: the variable namespace URI
639 * Search in the Variable array of the context for the given
642 * Returns the value or NULL if not found
645 xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
646 const xmlChar *ns_uri) {
647 xsltStackElemPtr elem;
652 elem = xsltStackLookup(ctxt, name, ns_uri);
654 return(xsltGlobalVariableLookup(ctxt, name, ns_uri));
656 if (!elem->computed) {
657 #ifdef DEBUG_VARIABLE
658 xsltGenericDebug(xsltGenericDebugContext,
659 "uncomputed variable %s\n", name);
661 xsltEvalVariable(ctxt, elem);
663 if (elem->value != NULL)
664 return(xmlXPathObjectCopy(elem->value));
665 #ifdef DEBUG_VARIABLE
666 xsltGenericDebug(xsltGenericDebugContext,
667 "variable not found %s\n", name);
673 * xsltParseStylesheetCallerParam:
674 * @ctxt: the XSLT transformation context
675 * @cur: the "param" element
677 * parse an XSLT transformation param declaration, compute
678 * its value but doesn't record it.
680 * It returns the new xsltStackElemPtr or NULL
684 xsltParseStylesheetCallerParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
685 xmlChar *name, *ncname, *prefix;
687 xmlNodePtr tree = NULL;
688 xsltStackElemPtr elem = NULL;
690 if ((cur == NULL) || (ctxt == NULL))
693 name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
695 xsltGenericError(xsltGenericErrorContext,
696 "xsl:param : missing name attribute\n");
700 #ifdef DEBUG_VARIABLE
701 xsltGenericDebug(xsltGenericDebugContext,
702 "Parsing param %s\n", name);
705 select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
706 if (select == NULL) {
707 tree = cur->children;
709 #ifdef DEBUG_VARIABLE
710 xsltGenericDebug(xsltGenericDebugContext,
711 " select %s\n", select);
713 if (cur->children != NULL)
714 xsltGenericError(xsltGenericErrorContext,
715 "xsl:param : content shuld be empty since select is present \n");
718 ncname = xmlSplitQName2(name, &prefix);
720 if (ncname != NULL) {
721 if (prefix != NULL) {
724 ns = xmlSearchNs(cur->doc, cur, prefix);
726 xsltGenericError(xsltGenericErrorContext,
727 "xsl:param : no namespace bound to prefix %s\n", prefix);
729 elem = xsltBuildVariable(ctxt, ncname, ns->href, select,
734 elem = xsltBuildVariable(ctxt, ncname, NULL, select, tree, 1);
738 elem = xsltBuildVariable(ctxt, name, NULL, select, tree, 1);
748 * xsltParseStylesheetParam:
749 * @ctxt: the XSLT transformation context
750 * @cur: the "param" element
752 * parse an XSLT transformation param declaration and record
757 xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
758 xmlChar *name, *ncname, *prefix;
760 xmlNodePtr tree = NULL;
762 if ((cur == NULL) || (ctxt == NULL))
765 name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
767 xsltGenericError(xsltGenericErrorContext,
768 "xsl:param : missing name attribute\n");
772 #ifdef DEBUG_VARIABLE
773 xsltGenericDebug(xsltGenericDebugContext,
774 "Parsing param %s\n", name);
777 select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
778 if (select == NULL) {
779 tree = cur->children;
781 #ifdef DEBUG_VARIABLE
782 xsltGenericDebug(xsltGenericDebugContext,
783 " select %s\n", select);
785 if (cur->children != NULL)
786 xsltGenericError(xsltGenericErrorContext,
787 "xsl:param : content shuld be empty since select is present \n");
790 ncname = xmlSplitQName2(name, &prefix);
792 if (ncname != NULL) {
793 if (prefix != NULL) {
796 ns = xmlSearchNs(cur->doc, cur, prefix);
798 xsltGenericError(xsltGenericErrorContext,
799 "xsl:param : no namespace bound to prefix %s\n", prefix);
801 xsltRegisterVariable(ctxt, ncname, ns->href, select, tree, 1);
805 xsltRegisterVariable(ctxt, ncname, NULL, select, tree, 1);
809 xsltRegisterVariable(ctxt, name, NULL, select, tree, 1);
819 * xsltParseGlobalVariable:
820 * @style: the XSLT stylesheet
821 * @cur: the "variable" element
823 * parse an XSLT transformation variable declaration and record
828 xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur) {
829 xmlChar *name, *ncname, *prefix;
831 xmlNodePtr tree = NULL;
833 if ((cur == NULL) || (style == NULL))
836 name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
838 xsltGenericError(xsltGenericErrorContext,
839 "xsl:variable : missing name attribute\n");
843 #ifdef DEBUG_VARIABLE
844 xsltGenericDebug(xsltGenericDebugContext,
845 "Parsing global variable %s\n", name);
848 select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
849 if (select == NULL) {
850 tree = cur->children;
852 if (cur->children != NULL)
853 xsltGenericError(xsltGenericErrorContext,
854 "xsl:variable : content shuld be empty since select is present \n");
857 ncname = xmlSplitQName2(name, &prefix);
859 if (ncname != NULL) {
860 if (prefix != NULL) {
863 ns = xmlSearchNs(cur->doc, cur, prefix);
865 xsltGenericError(xsltGenericErrorContext,
866 "xsl:variable : no namespace bound to prefix %s\n", prefix);
868 xsltRegisterGlobalVariable(style, ncname, ns->href, select,
873 xsltRegisterGlobalVariable(style, ncname, NULL, select, tree,
878 xsltRegisterGlobalVariable(style, name, NULL, select, tree, 0, NULL);
888 * xsltParseGlobalParam:
889 * @style: the XSLT stylesheet
890 * @cur: the "param" element
892 * parse an XSLT transformation param declaration and record
897 xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
898 xmlChar *name, *ncname, *prefix;
900 xmlNodePtr tree = NULL;
902 if ((cur == NULL) || (style == NULL))
905 name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
907 xsltGenericError(xsltGenericErrorContext,
908 "xsl:param : missing name attribute\n");
912 #ifdef DEBUG_VARIABLE
913 xsltGenericDebug(xsltGenericDebugContext,
914 "Parsing global param %s\n", name);
917 select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
918 if (select == NULL) {
919 tree = cur->children;
921 if (cur->children != NULL)
922 xsltGenericError(xsltGenericErrorContext,
923 "xsl:param : content shuld be empty since select is present \n");
926 ncname = xmlSplitQName2(name, &prefix);
928 if (ncname != NULL) {
929 if (prefix != NULL) {
932 ns = xmlSearchNs(cur->doc, cur, prefix);
934 xsltGenericError(xsltGenericErrorContext,
935 "xsl:param : no namespace bound to prefix %s\n", prefix);
937 xsltRegisterGlobalVariable(style, ncname, ns->href, select,
942 xsltRegisterGlobalVariable(style, ncname, NULL, select, tree,
947 xsltRegisterGlobalVariable(style, name, NULL, select, tree, 1, NULL);
956 * xsltParseStylesheetVariable:
957 * @ctxt: the XSLT transformation context
958 * @cur: the "variable" element
960 * parse an XSLT transformation variable declaration and record
965 xsltParseStylesheetVariable(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
966 xmlChar *name, *ncname, *prefix;
968 xmlNodePtr tree = NULL;
970 if ((cur == NULL) || (ctxt == NULL))
973 name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
975 xsltGenericError(xsltGenericErrorContext,
976 "xsl:variable : missing name attribute\n");
980 #ifdef DEBUG_VARIABLE
981 xsltGenericDebug(xsltGenericDebugContext,
982 "Parsing variable %s\n", name);
985 select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
986 if (select == NULL) {
987 tree = cur->children;
989 if (cur->children != NULL)
990 xsltGenericError(xsltGenericErrorContext,
991 "xsl:variable : content should be empty since select is present \n");
994 ncname = xmlSplitQName2(name, &prefix);
996 if (ncname != NULL) {
997 if (prefix != NULL) {
1000 ns = xmlSearchNs(cur->doc, cur, prefix);
1002 xsltGenericError(xsltGenericErrorContext,
1003 "xsl:variable : no namespace bound to prefix %s\n", prefix);
1005 xsltRegisterVariable(ctxt, ncname, ns->href, select, tree, 0);
1009 xsltRegisterVariable(ctxt, ncname, NULL, select, tree, 0);
1013 xsltRegisterVariable(ctxt, name, NULL, select, tree, 0);
1023 * xsltVariableLookup:
1024 * @ctxt: a void * but the the XSLT transformation context actually
1025 * @name: the variable name
1026 * @ns_uri: the variable namespace URI
1028 * This is the entry point when a varibale is needed by the XPath
1031 * Returns the value or NULL if not found
1034 xsltXPathVariableLookup(void *ctxt, const xmlChar *name,
1035 const xmlChar *ns_uri) {
1036 xsltTransformContextPtr context;
1037 xmlXPathObjectPtr ret;
1039 if ((ctxt == NULL) || (name == NULL))
1042 #ifdef DEBUG_VARIABLE
1043 xsltGenericDebug(xsltGenericDebugContext,
1044 "Lookup variable %s\n", name);
1046 context = (xsltTransformContextPtr) ctxt;
1047 ret = xsltVariableLookup(context, name, ns_uri);
1049 xsltGenericError(xsltGenericErrorContext,
1050 "unregistered variable %s\n", name);
1052 #ifdef DEBUG_VARIABLE
1054 xsltGenericDebug(xsltGenericDebugContext,
1055 "found variable %s\n", name);