2 * preproc.c: Preprocessing of style operations
5 * http://www.w3.org/TR/1999/REC-xslt-19991116
7 * Michael Kay "XSLT Programmer's Reference" pp 637-643
8 * Writing Multiple Output Files
10 * XSLT-1.1 Working Draft
11 * http://www.w3.org/TR/xslt11#multiple-output
13 * See Copyright for the status of this software.
15 * Daniel.Veillard@imag.fr
18 #include "xsltconfig.h"
22 #include <libxml/xmlmemory.h>
23 #include <libxml/parser.h>
24 #include <libxml/tree.h>
25 #include <libxml/valid.h>
26 #include <libxml/hash.h>
27 #include <libxml/uri.h>
28 #include <libxml/xmlerror.h>
30 #include "xsltutils.h"
31 #include "xsltInternals.h"
32 #include "transform.h"
33 #include "templates.h"
34 #include "variables.h"
35 #include "numbersInternals.h"
43 /************************************************************************
45 * handling of precomputed data *
47 ************************************************************************/
50 * xsltNewStylePreComp:
51 * @ctxt: an XSLT processing context
52 * @type: the construct type
54 * Create a new XSLT Style precomputed block
56 * Returns the newly allocated xsltStylePreCompPtr or NULL in case of error
58 static xsltStylePreCompPtr
59 xsltNewStylePreComp(xsltTransformContextPtr ctxt, xsltStyleType type) {
60 xsltStylePreCompPtr cur;
62 cur = (xsltStylePreCompPtr) xmlMalloc(sizeof(xsltStylePreComp));
64 xsltGenericError(xsltGenericErrorContext,
65 "xsltNewStylePreComp : malloc failed\n");
68 memset(cur, 0, sizeof(xsltStylePreComp));
73 cur->func = xsltCopy;break;
75 cur->func = xsltSort;break;
77 cur->func = xsltText;break;
78 case XSLT_FUNC_ELEMENT:
79 cur->func = xsltElement;break;
80 case XSLT_FUNC_ATTRIBUTE:
81 cur->func = xsltAttribute;break;
82 case XSLT_FUNC_COMMENT:
83 cur->func = xsltComment;break;
85 cur->func = xsltProcessingInstruction;break;
86 case XSLT_FUNC_COPYOF:
87 cur->func = xsltCopyOf;break;
88 case XSLT_FUNC_VALUEOF:
89 cur->func = xsltValueOf;break;
90 case XSLT_FUNC_NUMBER:
91 cur->func = xsltNumber;break;
92 case XSLT_FUNC_APPLYIMPORTS:
93 cur->func = xsltApplyImports;break;
94 case XSLT_FUNC_CALLTEMPLATE:
95 cur->func = xsltCallTemplate;break;
96 case XSLT_FUNC_APPLYTEMPLATES:
97 cur->func = xsltApplyTemplates;break;
98 case XSLT_FUNC_CHOOSE:
99 cur->func = xsltChoose;break;
101 cur->func = xsltIf;break;
102 case XSLT_FUNC_FOREACH:
103 cur->func = xsltForEach;break;
104 case XSLT_FUNC_DOCUMENT:
105 cur->func = xsltDocumentElem;break;
107 if (cur->func == NULL) {
108 xsltGenericError(xsltGenericErrorContext,
109 "xsltNewStylePreComp : no function for type %d\n", type);
111 cur->next = ctxt->preComps;
112 ctxt->preComps = cur;
118 * xsltFreeStylePreComp:
119 * @comp: an XSLT Style precomputed block
121 * Free up the memory allocated by @comp
124 xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
127 if (comp->inst != NULL)
128 comp->inst->_private = NULL;
129 if (comp->stype != NULL)
130 xmlFree(comp->stype);
131 if (comp->order != NULL)
132 xmlFree(comp->order);
133 if (comp->use != NULL)
135 if (comp->name != NULL)
137 if (comp->ns != NULL)
139 if (comp->mode != NULL)
141 if (comp->modeURI != NULL)
142 xmlFree(comp->modeURI);
143 if (comp->test != NULL)
145 if (comp->select != NULL)
146 xmlFree(comp->select);
148 if (comp->filename != NULL)
149 xmlFree(comp->filename);
151 if (comp->numdata.level != NULL)
152 xmlFree(comp->numdata.level);
153 if (comp->numdata.count != NULL)
154 xmlFree(comp->numdata.count);
155 if (comp->numdata.from != NULL)
156 xmlFree(comp->numdata.from);
157 if (comp->numdata.value != NULL)
158 xmlFree(comp->numdata.value);
159 if (comp->numdata.format != NULL)
160 xmlFree(comp->numdata.format);
161 if (comp->comp != NULL)
162 xmlXPathFreeCompExpr(comp->comp);
163 if (comp->nsList != NULL)
164 xmlFree(comp->nsList);
166 memset(comp, -1, sizeof(xsltStylePreComp));
172 /************************************************************************
174 * XSLT-1.1 extensions *
176 ************************************************************************/
180 * @ctxt: an XSLT processing context
181 * @inst: the instruction in the stylesheet
183 * Pre process an XSLT-1.1 document element
186 xsltDocumentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
187 xsltStylePreCompPtr comp;
188 xmlChar *filename = NULL;
189 xmlChar *base = NULL;
192 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_DOCUMENT);
195 inst->_private = comp;
199 if (xmlStrEqual(inst->name, (const xmlChar *) "output")) {
201 xsltGenericDebug(xsltGenericDebugContext,
202 "Found saxon:output extension\n");
204 filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
205 (const xmlChar *)"file",
206 XSLT_SAXON_NAMESPACE, &comp->has_filename);
207 } else if (xmlStrEqual(inst->name, (const xmlChar *) "write")) {
209 xsltGenericDebug(xsltGenericDebugContext,
210 "Found xalan:write extension\n");
212 filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
213 (const xmlChar *)"select",
214 XSLT_XALAN_NAMESPACE, &comp->has_filename);
215 } else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) {
216 filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
217 (const xmlChar *)"href",
218 XSLT_XT_NAMESPACE, &comp->has_filename);
219 if (filename == NULL) {
221 xsltGenericDebug(xsltGenericDebugContext,
222 "Found xslt11:document construct\n");
224 filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
225 (const xmlChar *)"href",
226 XSLT_NAMESPACE, &comp->has_filename);
230 xsltGenericDebug(xsltGenericDebugContext,
231 "Found xt:document extension\n");
236 if (!comp->has_filename) {
237 xsltGenericError(xsltGenericErrorContext,
238 "xsltDocumentComp: could not find the href\n");
242 if (filename != NULL) {
246 base = xmlNodeGetBase(inst->doc, inst);
247 URL = xmlBuildURI(filename, base);
249 xsltGenericError(xsltGenericErrorContext,
250 "xsltDocumentComp: URL computation failed %s\n", filename);
251 comp->filename = xmlStrdup(filename);
253 comp->filename = URL;
256 comp->filename = NULL;
262 if (filename != NULL)
266 /************************************************************************
268 * Most of the XSLT-1.0 transformations *
270 ************************************************************************/
274 * @ctxt: a XSLT process context
275 * @inst: the xslt sort node
277 * Process the xslt sort node on the source node
280 xsltSortComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
281 xsltStylePreCompPtr comp;
284 if ((ctxt == NULL) || (inst == NULL))
286 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_SORT);
289 inst->_private = comp;
292 comp->stype = xsltEvalStaticAttrValueTemplate(ctxt, inst,
293 (const xmlChar *)"data-type",
294 XSLT_NAMESPACE, &comp->has_stype);
295 if (comp->stype != NULL) {
296 if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
298 else if (xmlStrEqual(comp->stype, (const xmlChar *) "number"))
301 xsltGenericError(xsltGenericErrorContext,
302 "xsltSortComp: no support for data-type = %s\n", comp->stype);
306 comp->order = xsltEvalStaticAttrValueTemplate(ctxt, inst,
307 (const xmlChar *)"order",
308 XSLT_NAMESPACE, &comp->has_order);
309 if (comp->order != NULL) {
310 if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
311 comp->descending = 0;
312 else if (xmlStrEqual(comp->order, (const xmlChar *) "descending"))
313 comp->descending = 1;
315 xsltGenericError(xsltGenericErrorContext,
316 "xsltSortComp: invalid value %s for order\n", comp->order);
317 comp->descending = -1;
320 /* TODO: xsl:sort lang attribute */
321 /* TODO: xsl:sort case-order attribute */
323 comp->select = xmlGetNsProp(inst,(const xmlChar *)"select", XSLT_NAMESPACE);
324 if (comp->select == NULL) {
325 comp->select = xmlNodeGetContent(inst);
326 if (comp->select == NULL) {
327 xsltGenericError(xsltGenericErrorContext,
328 "xsltSortComp: select is not defined\n");
335 * @ctxt: a XSLT process context
336 * @inst: the xslt copy node
338 * Process the xslt copy node on the source node
341 xsltCopyComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
342 xsltStylePreCompPtr comp;
345 if ((ctxt == NULL) || (inst == NULL))
347 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COPY);
350 inst->_private = comp;
354 comp->use = xmlGetNsProp(inst, (const xmlChar *)"use-attribute-sets",
356 if (comp->use == NULL)
364 * @ctxt: a XSLT process context
365 * @inst: the xslt text node
367 * Process the xslt text node on the source node
370 xsltTextComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
371 xsltStylePreCompPtr comp;
374 if ((ctxt == NULL) || (inst == NULL))
376 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_TEXT);
379 inst->_private = comp;
383 prop = xmlGetNsProp(inst,
384 (const xmlChar *)"disable-output-escaping",
387 if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
389 } else if (!xmlStrEqual(prop,
390 (const xmlChar *)"no")){
391 xsltGenericError(xsltGenericErrorContext,
392 "xslt:text: disable-output-escaping allow only yes or no\n");
400 * @ctxt: a XSLT process context
401 * @inst: the xslt element node
403 * Process the xslt element node on the source node
406 xsltElementComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
407 xsltStylePreCompPtr comp;
409 if ((ctxt == NULL) || (inst == NULL))
411 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_ELEMENT);
414 inst->_private = comp;
418 * TODO: more computation can be done there, especially namespace lookup
420 comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst,
421 (const xmlChar *)"name",
422 XSLT_NAMESPACE, &comp->has_name);
423 comp->ns = xsltEvalStaticAttrValueTemplate(ctxt, inst,
424 (const xmlChar *)"namespace",
425 XSLT_NAMESPACE, &comp->has_ns);
427 comp->use = xsltEvalStaticAttrValueTemplate(ctxt, inst,
428 (const xmlChar *)"use-attribute-sets",
429 XSLT_NAMESPACE, &comp->has_use);
434 * @ctxt: a XSLT process context
435 * @inst: the xslt attribute node
437 * Process the xslt attribute node on the source node
440 xsltAttributeComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
441 xsltStylePreCompPtr comp;
443 if ((ctxt == NULL) || (inst == NULL))
445 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_ATTRIBUTE);
448 inst->_private = comp;
452 * TODO: more computation can be done there, especially namespace lookup
454 comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst,
455 (const xmlChar *)"name",
456 XSLT_NAMESPACE, &comp->has_name);
457 comp->ns = xsltEvalStaticAttrValueTemplate(ctxt, inst,
458 (const xmlChar *)"namespace",
459 XSLT_NAMESPACE, &comp->has_ns);
465 * @ctxt: a XSLT process context
466 * @inst: the xslt comment node
468 * Process the xslt comment node on the source node
471 xsltCommentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
472 xsltStylePreCompPtr comp;
474 if ((ctxt == NULL) || (inst == NULL))
476 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COMMENT);
479 inst->_private = comp;
484 * xsltProcessingInstructionComp:
485 * @ctxt: a XSLT process context
486 * @inst: the xslt processing-instruction node
488 * Process the xslt processing-instruction node on the source node
491 xsltProcessingInstructionComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
492 xsltStylePreCompPtr comp;
494 if ((ctxt == NULL) || (inst == NULL))
496 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_PI);
499 inst->_private = comp;
502 comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst,
503 (const xmlChar *)"name",
504 XSLT_NAMESPACE, &comp->has_name);
509 * @ctxt: a XSLT process context
510 * @inst: the xslt copy-of node
512 * Process the xslt copy-of node on the source node
515 xsltCopyOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
516 xsltStylePreCompPtr comp;
518 if ((ctxt == NULL) || (inst == NULL))
520 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COPYOF);
523 inst->_private = comp;
526 comp->select = xmlGetNsProp(inst, (const xmlChar *)"select",
528 if (comp->select == NULL) {
529 xsltGenericError(xsltGenericErrorContext,
530 "xslt:copy-of : select is missing\n");
536 * @ctxt: a XSLT process context
537 * @inst: the xslt value-of node
539 * Process the xslt value-of node on the source node
542 xsltValueOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
543 xsltStylePreCompPtr comp;
546 if ((ctxt == NULL) || (inst == NULL))
548 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_VALUEOF);
551 inst->_private = comp;
554 prop = xmlGetNsProp(inst,
555 (const xmlChar *)"disable-output-escaping",
558 if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
560 } else if (!xmlStrEqual(prop,
561 (const xmlChar *)"no")){
562 xsltGenericError(xsltGenericErrorContext,
563 "value-of: disable-output-escaping allow only yes or no\n");
567 comp->select = xmlGetNsProp(inst, (const xmlChar *)"select",
569 if (comp->select == NULL) {
570 xsltGenericError(xsltGenericErrorContext,
571 "xslt:value-of : select is missing\n");
577 * @ctxt: a XSLT process context
578 * @cur: the xslt number node
580 * Process the xslt number node on the source node
583 xsltNumberComp(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
584 xsltStylePreCompPtr comp;
587 if ((ctxt == NULL) || (cur == NULL))
589 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_NUMBER);
592 cur->_private = comp;
594 if ((ctxt == NULL) || (cur == NULL))
597 comp->numdata.doc = cur->doc;
598 comp->numdata.node = cur;
599 comp->numdata.value = xmlGetNsProp(cur, (const xmlChar *)"value",
602 prop = xmlGetNsProp(cur, (const xmlChar *)"format", XSLT_NAMESPACE);
604 comp->numdata.format = prop;
606 comp->numdata.format = xmlStrdup(BAD_CAST("1"));
609 comp->numdata.count = xmlGetNsProp(cur, (const xmlChar *)"count",
611 comp->numdata.from = xmlGetNsProp(cur, (const xmlChar *)"from",
614 prop = xmlGetNsProp(cur, (const xmlChar *)"level", XSLT_NAMESPACE);
616 if (xmlStrEqual(prop, BAD_CAST("single")) ||
617 xmlStrEqual(prop, BAD_CAST("multiple")) ||
618 xmlStrEqual(prop, BAD_CAST("any"))) {
619 comp->numdata.level = prop;
621 xsltGenericError(xsltGenericErrorContext,
622 "xsl:number : invalid value %s for level\n", prop);
627 prop = xmlGetNsProp(cur, (const xmlChar *)"lang", XSLT_NAMESPACE);
629 TODO; /* xsl:number lang attribute */
633 prop = xmlGetNsProp(cur, (const xmlChar *)"letter-value", XSLT_NAMESPACE);
635 if (xmlStrEqual(prop, BAD_CAST("alphabetic"))) {
636 TODO; /* xsl:number letter-value attribute alphabetic */
637 } else if (xmlStrEqual(prop, BAD_CAST("traditional"))) {
638 TODO; /* xsl:number letter-value attribute traditional */
640 xsltGenericError(xsltGenericErrorContext,
641 "xsl:number : invalid value %s for letter-value\n", prop);
646 prop = xmlGetNsProp(cur, (const xmlChar *)"grouping-separator", XSLT_NAMESPACE);
648 comp->numdata.groupingCharacter = prop[0];
652 prop = xmlGetNsProp(cur, (const xmlChar *)"grouping-size", XSLT_NAMESPACE);
654 sscanf((char *)prop, "%d", &comp->numdata.digitsPerGroup);
657 comp->numdata.groupingCharacter = 0;
660 /* Set default values */
661 if (comp->numdata.value == NULL) {
662 if (comp->numdata.level == NULL) {
663 comp->numdata.level = xmlStrdup(BAD_CAST("single"));
670 * xsltApplyImportsComp:
671 * @ctxt: a XSLT process context
672 * @inst: the xslt apply-imports node
674 * Process the xslt apply-imports node on the source node
677 xsltApplyImportsComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
678 xsltStylePreCompPtr comp;
680 if ((ctxt == NULL) || (inst == NULL))
682 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_APPLYIMPORTS);
685 inst->_private = comp;
690 * xsltCallTemplateComp:
691 * @ctxt: a XSLT process context
692 * @inst: the xslt call-template node
694 * Process the xslt call-template node on the source node
697 xsltCallTemplateComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
698 xsltStylePreCompPtr comp;
700 xmlChar *ncname = NULL;
701 xmlChar *prefix = NULL;
704 if ((ctxt == NULL) || (inst == NULL))
706 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_CALLTEMPLATE);
709 inst->_private = comp;
713 * The full template resolution can be done statically
715 prop = xmlGetNsProp(inst, (const xmlChar *)"name", XSLT_NAMESPACE);
717 xsltGenericError(xsltGenericErrorContext,
718 "xslt:call-template : name is missing\n");
721 ncname = xmlSplitQName2(prop, &prefix);
722 if (ncname == NULL) {
727 if (prefix != NULL) {
728 ns = xmlSearchNs(ctxt->insert->doc, ctxt->insert, prefix);
730 xsltGenericError(xsltGenericErrorContext,
731 "no namespace bound to prefix %s\n", prefix);
735 comp->templ = xsltFindTemplate(ctxt, ncname, ns->href);
737 comp->templ = xsltFindTemplate(ctxt, ncname, NULL);
739 if (comp->templ == NULL) {
740 xsltGenericError(xsltGenericErrorContext,
741 "xslt:call-template : template %s not found\n", ncname);
745 /* TODO: with-param could be optimized too */
756 * xsltApplyTemplatesComp:
757 * @ctxt: a XSLT process context
758 * @inst: the apply-templates node
760 * Process the apply-templates node on the source node
763 xsltApplyTemplatesComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
764 xsltStylePreCompPtr comp;
767 if ((ctxt == NULL) || (inst == NULL))
769 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_APPLYTEMPLATES);
772 inst->_private = comp;
778 prop = xmlGetNsProp(inst, (const xmlChar *)"mode", XSLT_NAMESPACE);
780 xmlChar *prefix = NULL;
782 comp->mode = xmlSplitQName2(prop, &prefix);
783 if (comp->mode != NULL) {
784 if (prefix != NULL) {
787 ns = xmlSearchNs(inst->doc, inst, prefix);
789 xsltGenericError(xsltGenericErrorContext,
790 "no namespace bound to prefix %s\n", prefix);
794 comp->modeURI = NULL;
796 comp->modeURI = xmlStrdup(ns->href);
802 comp->modeURI = NULL;
806 comp->modeURI = NULL;
809 comp->select = xmlGetNsProp(inst, (const xmlChar *)"select",
812 /* TODO: handle (or skip) the xsl:sort and xsl:with-param */
817 * @ctxt: a XSLT process context
818 * @inst: the xslt choose node
820 * Process the xslt choose node on the source node
823 xsltChooseComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
824 xsltStylePreCompPtr comp;
826 if ((ctxt == NULL) || (inst == NULL))
828 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_CHOOSE);
831 inst->_private = comp;
837 * @ctxt: a XSLT process context
838 * @inst: the xslt if node
840 * Process the xslt if node on the source node
843 xsltIfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
844 xsltStylePreCompPtr comp;
846 if ((ctxt == NULL) || (inst == NULL))
848 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_IF);
851 inst->_private = comp;
854 comp->test = xmlGetNsProp(inst, (const xmlChar *)"test", XSLT_NAMESPACE);
855 if (comp->test == NULL) {
856 xsltGenericError(xsltGenericErrorContext,
857 "xsltIf: test is not defined\n");
864 * @ctxt: a XSLT process context
865 * @inst: the xslt for-each node
867 * Process the xslt for-each node on the source node
870 xsltForEachComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
871 xsltStylePreCompPtr comp;
873 if ((ctxt == NULL) || (inst == NULL))
875 comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_FOREACH);
878 inst->_private = comp;
881 comp->select = xmlGetNsProp(inst, (const xmlChar *)"select",
884 /* TODO: handle and skip the xsl:sort */
888 /************************************************************************
890 * Generic interface *
892 ************************************************************************/
895 * xsltFreeStylePreComps:
896 * @ctxt: an XSLT transformation context
898 * Free up the memory allocated by all precomputed blocks
901 xsltFreeStylePreComps(xsltTransformContextPtr ctxt) {
902 xsltStylePreCompPtr cur, next;
906 cur = ctxt->preComps;
907 while (cur != NULL) {
909 xsltFreeStylePreComp(cur);
915 * xsltDocumentCompute:
916 * @ctxt: an XSLT processing context
917 * @inst: the instruction in the stylesheet
919 * Precompute an XSLT stylesheet element
922 xsltStylePreCompute(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
923 if (inst->_private != NULL)
925 if (IS_XSLT_ELEM(inst)) {
926 xsltStylePreCompPtr cur;
928 if (IS_XSLT_NAME(inst, "apply-templates")) {
929 xsltApplyTemplatesComp(ctxt, inst);
930 } else if (IS_XSLT_NAME(inst, "value-of")) {
931 xsltValueOfComp(ctxt, inst);
932 } else if (IS_XSLT_NAME(inst, "copy")) {
933 xsltCopyComp(ctxt, inst);
934 } else if (IS_XSLT_NAME(inst, "copy-of")) {
935 xsltCopyOfComp(ctxt, inst);
936 } else if (IS_XSLT_NAME(inst, "if")) {
937 xsltIfComp(ctxt, inst);
938 } else if (IS_XSLT_NAME(inst, "choose")) {
939 xsltChooseComp(ctxt, inst);
940 } else if (IS_XSLT_NAME(inst, "for-each")) {
941 xsltForEachComp(ctxt, inst);
942 } else if (IS_XSLT_NAME(inst, "apply-imports")) {
943 xsltApplyImportsComp(ctxt, inst);
944 } else if (IS_XSLT_NAME(inst, "attribute")) {
945 xsltAttributeComp(ctxt, inst);
946 } else if (IS_XSLT_NAME(inst, "element")) {
947 xsltElementComp(ctxt, inst);
948 } else if (IS_XSLT_NAME(inst, "text")) {
949 xsltTextComp(ctxt, inst);
950 } else if (IS_XSLT_NAME(inst, "sort")) {
951 xsltSortComp(ctxt, inst);
952 } else if (IS_XSLT_NAME(inst, "comment")) {
953 xsltCommentComp(ctxt, inst);
954 } else if (IS_XSLT_NAME(inst, "number")) {
955 xsltNumberComp(ctxt, inst);
956 } else if (IS_XSLT_NAME(inst, "processing-instruction")) {
957 xsltProcessingInstructionComp(ctxt, inst);
958 } else if (IS_XSLT_NAME(inst, "call-template")) {
959 xsltCallTemplateComp(ctxt, inst);
960 } else if (IS_XSLT_NAME(inst, "param")) {
961 /* TODO: is there any use optimizing param too ? */
963 } else if (IS_XSLT_NAME(inst, "variable")) {
964 /* TODO: is there any use optimizing variable too ? */
966 } else if (IS_XSLT_NAME(inst, "message")) {
967 /* no optimization needed */
969 } else if (IS_XSLT_NAME(inst, "document")) {
970 xsltDocumentComp(ctxt, inst);
972 xsltGenericError(xsltGenericDebugContext,
973 "xsltStylePreCompute: unknown xslt:%s\n", inst->name);
976 * Add the namespace lookup here, this code can be shared by
977 * all precomputations.
979 cur = inst->_private;
983 cur->nsList = xmlGetNsList(inst->doc, inst);
984 if (cur->nsList != NULL) {
985 while (cur->nsList[i] != NULL)
991 if (IS_XSLT_NAME(inst, "document")) {
992 xsltDocumentComp(ctxt, inst);