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.
23 #include <libxml/xmlmemory.h>
24 #include <libxml/parser.h>
25 #include <libxml/tree.h>
26 #include <libxml/valid.h>
27 #include <libxml/hash.h>
28 #include <libxml/uri.h>
29 #include <libxml/encoding.h>
30 #include <libxml/xmlerror.h>
32 #include "xsltutils.h"
33 #include "xsltInternals.h"
34 #include "transform.h"
35 #include "templates.h"
36 #include "variables.h"
37 #include "numbersInternals.h"
41 #include "extensions.h"
44 #ifdef WITH_XSLT_DEBUG
45 #define WITH_XSLT_DEBUG_PREPROC
48 const xmlChar
*xsltExtMarker
= (const xmlChar
*) "Extension Element";
50 /************************************************************************
54 ************************************************************************/
56 #ifdef XSLT_REFACTORED
58 * Grammar checks are now performed in xslt.c.
62 * xsltCheckTopLevelElement:
63 * @style: the XSLT stylesheet
64 * @inst: the XSLT instruction
65 * @err: raise an error or not
67 * Check that the instruction is instanciated as a top level element.
69 * Returns -1 in case of error, 0 if failed and 1 in case of success
72 xsltCheckTopLevelElement(xsltStylesheetPtr style
, xmlNodePtr inst
, int err
) {
74 if ((style
== NULL
) || (inst
== NULL
) || (inst
->ns
== NULL
))
77 parent
= inst
->parent
;
80 xsltTransformError(NULL
, style
, inst
,
81 "internal problem: element has no parent\n");
86 if ((parent
->ns
== NULL
) || (parent
->type
!= XML_ELEMENT_NODE
) ||
87 ((parent
->ns
!= inst
->ns
) &&
88 (!xmlStrEqual(parent
->ns
->href
, inst
->ns
->href
))) ||
89 ((!xmlStrEqual(parent
->name
, BAD_CAST
"stylesheet")) &&
90 (!xmlStrEqual(parent
->name
, BAD_CAST
"transform")))) {
92 xsltTransformError(NULL
, style
, inst
,
93 "element %s only allowed as child of stylesheet\n",
103 * xsltCheckInstructionElement:
104 * @style: the XSLT stylesheet
105 * @inst: the XSLT instruction
107 * Check that the instruction is instanciated as an instruction element.
110 xsltCheckInstructionElement(xsltStylesheetPtr style
, xmlNodePtr inst
) {
114 if ((style
== NULL
) || (inst
== NULL
) || (inst
->ns
== NULL
) ||
115 (style
->literal_result
))
118 has_ext
= (style
->extInfos
!= NULL
);
120 parent
= inst
->parent
;
121 if (parent
== NULL
) {
122 xsltTransformError(NULL
, style
, inst
,
123 "internal problem: element has no parent\n");
127 while ((parent
!= NULL
) && (parent
->type
!= XML_DOCUMENT_NODE
)) {
128 if (((parent
->ns
== inst
->ns
) ||
129 ((parent
->ns
!= NULL
) &&
130 (xmlStrEqual(parent
->ns
->href
, inst
->ns
->href
)))) &&
131 ((xmlStrEqual(parent
->name
, BAD_CAST
"template")) ||
132 (xmlStrEqual(parent
->name
, BAD_CAST
"param")) ||
133 (xmlStrEqual(parent
->name
, BAD_CAST
"attribute")) ||
134 (xmlStrEqual(parent
->name
, BAD_CAST
"variable")))) {
139 * if we are within an extension element all bets are off
140 * about the semantic there e.g. xsl:param within func:function
142 if ((has_ext
) && (parent
->ns
!= NULL
) &&
143 (xmlHashLookup(style
->extInfos
, parent
->ns
->href
) != NULL
))
146 parent
= parent
->parent
;
148 xsltTransformError(NULL
, style
, inst
,
149 "element %s only allowed within a template, variable or param\n",
155 * xsltCheckParentElement:
156 * @style: the XSLT stylesheet
157 * @inst: the XSLT instruction
158 * @allow1: allowed parent1
159 * @allow2: allowed parent2
161 * Check that the instruction is instanciated as the childre of one of the
165 xsltCheckParentElement(xsltStylesheetPtr style
, xmlNodePtr inst
,
166 const xmlChar
*allow1
, const xmlChar
*allow2
) {
169 if ((style
== NULL
) || (inst
== NULL
) || (inst
->ns
== NULL
) ||
170 (style
->literal_result
))
173 parent
= inst
->parent
;
174 if (parent
== NULL
) {
175 xsltTransformError(NULL
, style
, inst
,
176 "internal problem: element has no parent\n");
180 if (((parent
->ns
== inst
->ns
) ||
181 ((parent
->ns
!= NULL
) &&
182 (xmlStrEqual(parent
->ns
->href
, inst
->ns
->href
)))) &&
183 ((xmlStrEqual(parent
->name
, allow1
)) ||
184 (xmlStrEqual(parent
->name
, allow2
)))) {
188 if (style
->extInfos
!= NULL
) {
189 while ((parent
!= NULL
) && (parent
->type
!= XML_DOCUMENT_NODE
)) {
191 * if we are within an extension element all bets are off
192 * about the semantic there e.g. xsl:param within func:function
194 if ((parent
->ns
!= NULL
) &&
195 (xmlHashLookup(style
->extInfos
, parent
->ns
->href
) != NULL
))
198 parent
= parent
->parent
;
201 xsltTransformError(NULL
, style
, inst
,
202 "element %s is not allowed within that context\n",
208 /************************************************************************
210 * handling of precomputed data *
212 ************************************************************************/
215 * xsltNewStylePreComp:
216 * @style: the XSLT stylesheet
217 * @type: the construct type
219 * Create a new XSLT Style precomputed block
221 * Returns the newly allocated specialized structure
222 * or NULL in case of error
224 static xsltStylePreCompPtr
225 xsltNewStylePreComp(xsltStylesheetPtr style
, xsltStyleType type
) {
226 xsltStylePreCompPtr cur
;
227 #ifdef XSLT_REFACTORED
234 #ifdef XSLT_REFACTORED
236 * URGENT TODO: Use specialized factory functions in order
237 * to avoid this ugliness.
241 size
= sizeof(xsltStyleItemCopy
); break;
243 size
= sizeof(xsltStyleItemSort
); break;
245 size
= sizeof(xsltStyleItemText
); break;
246 case XSLT_FUNC_ELEMENT
:
247 size
= sizeof(xsltStyleItemElement
); break;
248 case XSLT_FUNC_ATTRIBUTE
:
249 size
= sizeof(xsltStyleItemAttribute
); break;
250 case XSLT_FUNC_COMMENT
:
251 size
= sizeof(xsltStyleItemComment
); break;
253 size
= sizeof(xsltStyleItemPI
); break;
254 case XSLT_FUNC_COPYOF
:
255 size
= sizeof(xsltStyleItemCopyOf
); break;
256 case XSLT_FUNC_VALUEOF
:
257 size
= sizeof(xsltStyleItemValueOf
); break;;
258 case XSLT_FUNC_NUMBER
:
259 size
= sizeof(xsltStyleItemNumber
); break;
260 case XSLT_FUNC_APPLYIMPORTS
:
261 size
= sizeof(xsltStyleItemApplyImports
); break;
262 case XSLT_FUNC_CALLTEMPLATE
:
263 size
= sizeof(xsltStyleItemCallTemplate
); break;
264 case XSLT_FUNC_APPLYTEMPLATES
:
265 size
= sizeof(xsltStyleItemApplyTemplates
); break;
266 case XSLT_FUNC_CHOOSE
:
267 size
= sizeof(xsltStyleItemChoose
); break;
269 size
= sizeof(xsltStyleItemIf
); break;
270 case XSLT_FUNC_FOREACH
:
271 size
= sizeof(xsltStyleItemForEach
); break;
272 case XSLT_FUNC_DOCUMENT
:
273 size
= sizeof(xsltStyleItemDocument
); break;
274 case XSLT_FUNC_WITHPARAM
:
275 size
= sizeof(xsltStyleItemWithParam
); break;
276 case XSLT_FUNC_PARAM
:
277 size
= sizeof(xsltStyleItemParam
); break;
278 case XSLT_FUNC_VARIABLE
:
279 size
= sizeof(xsltStyleItemVariable
); break;
281 size
= sizeof(xsltStyleItemWhen
); break;
282 case XSLT_FUNC_OTHERWISE
:
283 size
= sizeof(xsltStyleItemOtherwise
); break;
285 xsltTransformError(NULL
, style
, NULL
,
286 "xsltNewStylePreComp : invalid type %d\n", type
);
291 * Create the structure.
293 cur
= (xsltStylePreCompPtr
) xmlMalloc(size
);
295 xsltTransformError(NULL
, style
, NULL
,
296 "xsltNewStylePreComp : malloc failed\n");
300 memset(cur
, 0, size
);
302 #else /* XSLT_REFACTORED */
306 cur
= (xsltStylePreCompPtr
) xmlMalloc(sizeof(xsltStylePreComp
));
308 xsltTransformError(NULL
, style
, NULL
,
309 "xsltNewStylePreComp : malloc failed\n");
313 memset(cur
, 0, sizeof(xsltStylePreComp
));
314 #endif /* XSLT_REFACTORED */
317 * URGENT TODO: Better to move this to spezialized factory functions.
322 cur
->func
= xsltCopy
;break;
324 cur
->func
= xsltSort
;break;
326 cur
->func
= xsltText
;break;
327 case XSLT_FUNC_ELEMENT
:
328 cur
->func
= xsltElement
;break;
329 case XSLT_FUNC_ATTRIBUTE
:
330 cur
->func
= xsltAttribute
;break;
331 case XSLT_FUNC_COMMENT
:
332 cur
->func
= xsltComment
;break;
334 cur
->func
= xsltProcessingInstruction
;
336 case XSLT_FUNC_COPYOF
:
337 cur
->func
= xsltCopyOf
;break;
338 case XSLT_FUNC_VALUEOF
:
339 cur
->func
= xsltValueOf
;break;
340 case XSLT_FUNC_NUMBER
:
341 cur
->func
= xsltNumber
;break;
342 case XSLT_FUNC_APPLYIMPORTS
:
343 cur
->func
= xsltApplyImports
;break;
344 case XSLT_FUNC_CALLTEMPLATE
:
345 cur
->func
= xsltCallTemplate
;break;
346 case XSLT_FUNC_APPLYTEMPLATES
:
347 cur
->func
= xsltApplyTemplates
;break;
348 case XSLT_FUNC_CHOOSE
:
349 cur
->func
= xsltChoose
;break;
351 cur
->func
= xsltIf
;break;
352 case XSLT_FUNC_FOREACH
:
353 cur
->func
= xsltForEach
;break;
354 case XSLT_FUNC_DOCUMENT
:
355 cur
->func
= xsltDocumentElem
;break;
356 case XSLT_FUNC_WITHPARAM
:
357 case XSLT_FUNC_PARAM
:
358 case XSLT_FUNC_VARIABLE
:
362 if (cur
->func
== NULL
) {
363 xsltTransformError(NULL
, style
, NULL
,
364 "xsltNewStylePreComp : no function for type %d\n", type
);
368 cur
->next
= style
->preComps
;
369 style
->preComps
= (xsltElemPreCompPtr
) cur
;
375 * xsltFreeStylePreComp:
376 * @comp: an XSLT Style precomputed block
378 * Free up the memory allocated by @comp
381 xsltFreeStylePreComp(xsltStylePreCompPtr comp
) {
384 #ifdef XSLT_REFACTORED
386 * URGENT TODO: Implement destructors.
388 switch (comp
->type
) {
389 case XSLT_FUNC_LITERAL_RESULT_ELEMENT
:
393 case XSLT_FUNC_SORT
: {
394 xsltStyleItemSortPtr item
= (xsltStyleItemSortPtr
) comp
;
395 if (item
->locale
!= (xsltLocale
)0)
396 xsltFreeLocale(item
->locale
);
397 if (item
->comp
!= NULL
)
398 xmlXPathFreeCompExpr(item
->comp
);
403 case XSLT_FUNC_ELEMENT
:
405 case XSLT_FUNC_ATTRIBUTE
:
407 case XSLT_FUNC_COMMENT
:
411 case XSLT_FUNC_COPYOF
: {
412 xsltStyleItemCopyOfPtr item
= (xsltStyleItemCopyOfPtr
) comp
;
413 if (item
->comp
!= NULL
)
414 xmlXPathFreeCompExpr(item
->comp
);
417 case XSLT_FUNC_VALUEOF
: {
418 xsltStyleItemValueOfPtr item
= (xsltStyleItemValueOfPtr
) comp
;
419 if (item
->comp
!= NULL
)
420 xmlXPathFreeCompExpr(item
->comp
);
423 case XSLT_FUNC_NUMBER
: {
424 xsltStyleItemNumberPtr item
= (xsltStyleItemNumberPtr
) comp
;
425 if (item
->numdata
.countPat
!= NULL
)
426 xsltFreeCompMatchList(item
->numdata
.countPat
);
427 if (item
->numdata
.fromPat
!= NULL
)
428 xsltFreeCompMatchList(item
->numdata
.fromPat
);
431 case XSLT_FUNC_APPLYIMPORTS
:
433 case XSLT_FUNC_CALLTEMPLATE
:
435 case XSLT_FUNC_APPLYTEMPLATES
: {
436 xsltStyleItemApplyTemplatesPtr item
=
437 (xsltStyleItemApplyTemplatesPtr
) comp
;
438 if (item
->comp
!= NULL
)
439 xmlXPathFreeCompExpr(item
->comp
);
442 case XSLT_FUNC_CHOOSE
:
445 xsltStyleItemIfPtr item
= (xsltStyleItemIfPtr
) comp
;
446 if (item
->comp
!= NULL
)
447 xmlXPathFreeCompExpr(item
->comp
);
450 case XSLT_FUNC_FOREACH
: {
451 xsltStyleItemForEachPtr item
=
452 (xsltStyleItemForEachPtr
) comp
;
453 if (item
->comp
!= NULL
)
454 xmlXPathFreeCompExpr(item
->comp
);
457 case XSLT_FUNC_DOCUMENT
:
459 case XSLT_FUNC_WITHPARAM
: {
460 xsltStyleItemWithParamPtr item
=
461 (xsltStyleItemWithParamPtr
) comp
;
462 if (item
->comp
!= NULL
)
463 xmlXPathFreeCompExpr(item
->comp
);
466 case XSLT_FUNC_PARAM
: {
467 xsltStyleItemParamPtr item
=
468 (xsltStyleItemParamPtr
) comp
;
469 if (item
->comp
!= NULL
)
470 xmlXPathFreeCompExpr(item
->comp
);
473 case XSLT_FUNC_VARIABLE
: {
474 xsltStyleItemVariablePtr item
=
475 (xsltStyleItemVariablePtr
) comp
;
476 if (item
->comp
!= NULL
)
477 xmlXPathFreeCompExpr(item
->comp
);
480 case XSLT_FUNC_WHEN
: {
481 xsltStyleItemWhenPtr item
=
482 (xsltStyleItemWhenPtr
) comp
;
483 if (item
->comp
!= NULL
)
484 xmlXPathFreeCompExpr(item
->comp
);
487 case XSLT_FUNC_OTHERWISE
:
488 case XSLT_FUNC_FALLBACK
:
489 case XSLT_FUNC_MESSAGE
:
490 case XSLT_FUNC_INCLUDE
:
491 case XSLT_FUNC_ATTRSET
:
495 /* TODO: Raise error. */
499 if (comp
->locale
!= (xsltLocale
)0)
500 xsltFreeLocale(comp
->locale
);
501 if (comp
->comp
!= NULL
)
502 xmlXPathFreeCompExpr(comp
->comp
);
503 if (comp
->numdata
.countPat
!= NULL
)
504 xsltFreeCompMatchList(comp
->numdata
.countPat
);
505 if (comp
->numdata
.fromPat
!= NULL
)
506 xsltFreeCompMatchList(comp
->numdata
.fromPat
);
507 if (comp
->nsList
!= NULL
)
508 xmlFree(comp
->nsList
);
515 /************************************************************************
517 * XSLT-1.1 extensions *
519 ************************************************************************/
523 * @style: the XSLT stylesheet
524 * @inst: the instruction in the stylesheet
527 * Pre process an XSLT-1.1 document element
529 * Returns a precompiled data structure for the element
532 xsltDocumentComp(xsltStylesheetPtr style
, xmlNodePtr inst
,
533 xsltTransformFunction function ATTRIBUTE_UNUSED
) {
534 #ifdef XSLT_REFACTORED
535 xsltStyleItemDocumentPtr comp
;
537 xsltStylePreCompPtr comp
;
539 const xmlChar
*filename
= NULL
;
542 * As of 2006-03-30, this function is currently defined in Libxslt
544 * (in libxslt/extra.c)
545 * "output" in XSLT_SAXON_NAMESPACE
546 * "write" XSLT_XALAN_NAMESPACE
547 * "document" XSLT_XT_NAMESPACE
548 * "document" XSLT_NAMESPACE (from the abandoned old working
550 * (in libexslt/common.c)
551 * "document" in EXSLT_COMMON_NAMESPACE
553 #ifdef XSLT_REFACTORED
554 comp
= (xsltStyleItemDocumentPtr
)
555 xsltNewStylePreComp(style
, XSLT_FUNC_DOCUMENT
);
557 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_DOCUMENT
);
565 if (xmlStrEqual(inst
->name
, (const xmlChar
*) "output")) {
566 #ifdef WITH_XSLT_DEBUG_EXTRA
567 xsltGenericDebug(xsltGenericDebugContext
,
568 "Found saxon:output extension\n");
571 * The element "output" is in the namespace XSLT_SAXON_NAMESPACE
572 * (http://icl.com/saxon)
573 * The @file is in no namespace; it is an AVT.
574 * (http://www.computerwizards.com/saxon/doc/extensions.html#saxon:output)
576 * TODO: Do we need not to check the namespace here?
578 filename
= xsltEvalStaticAttrValueTemplate(style
, inst
,
579 (const xmlChar
*)"file",
580 NULL
, &comp
->has_filename
);
581 } else if (xmlStrEqual(inst
->name
, (const xmlChar
*) "write")) {
582 #ifdef WITH_XSLT_DEBUG_EXTRA
583 xsltGenericDebug(xsltGenericDebugContext
,
584 "Found xalan:write extension\n");
586 /* the filename need to be interpreted */
588 * TODO: Is "filename need to be interpreted" meant to be a todo?
589 * Where will be the filename of xalan:write be processed?
591 * TODO: Do we need not to check the namespace here?
592 * The extension ns is "http://xml.apache.org/xalan/redirect".
593 * See http://xml.apache.org/xalan-j/extensionslib.html.
595 } else if (xmlStrEqual(inst
->name
, (const xmlChar
*) "document")) {
596 if (inst
->ns
!= NULL
) {
597 if (xmlStrEqual(inst
->ns
->href
, XSLT_NAMESPACE
)) {
599 * Mark the instruction as being of
600 * XSLT version 1.1 (abandoned).
603 #ifdef WITH_XSLT_DEBUG_EXTRA
604 xsltGenericDebug(xsltGenericDebugContext
,
605 "Found xslt11:document construct\n");
608 if (xmlStrEqual(inst
->ns
->href
,
609 (const xmlChar
*)"http://exslt.org/common")) {
611 #ifdef WITH_XSLT_DEBUG_EXTRA
612 xsltGenericDebug(xsltGenericDebugContext
,
613 "Found exslt:document extension\n");
615 } else if (xmlStrEqual(inst
->ns
->href
, XSLT_XT_NAMESPACE
)) {
616 /* James Clark's XT. */
617 #ifdef WITH_XSLT_DEBUG_EXTRA
618 xsltGenericDebug(xsltGenericDebugContext
,
619 "Found xt:document extension\n");
625 * The element "document" is used in conjunction with the
626 * following namespaces:
628 * 1) XSLT_NAMESPACE (http://www.w3.org/1999/XSL/Transform version 1.1)
629 * <!ELEMENT xsl:document %template;>
630 * <!ATTLIST xsl:document
631 * href %avt; #REQUIRED
633 * IMPORTANT: xsl:document was in the abandoned XSLT 1.1 draft,
634 * it was removed and isn't available in XSLT 1.1 anymore.
635 * In XSLT 2.0 it was renamed to xsl:result-document.
637 * All other attributes are identical to the attributes
640 * 2) EXSLT_COMMON_NAMESPACE (http://exslt.org/common)
642 * href = { uri-reference }
643 * TODO: is @href is an AVT?
645 * 3) XSLT_XT_NAMESPACE (http://www.jclark.com/xt)
646 * Example: <xt:document method="xml" href="myFile.xml">
647 * TODO: is @href is an AVT?
649 * In all cases @href is in no namespace.
651 filename
= xsltEvalStaticAttrValueTemplate(style
, inst
,
652 (const xmlChar
*)"href", NULL
, &comp
->has_filename
);
654 if (!comp
->has_filename
) {
657 comp
->filename
= filename
;
660 return ((xsltElemPreCompPtr
) comp
);
663 /************************************************************************
665 * Most of the XSLT-1.0 transformations *
667 ************************************************************************/
671 * @style: the XSLT stylesheet
672 * @inst: the xslt sort node
674 * Process the xslt sort node on the source node
677 xsltSortComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
678 #ifdef XSLT_REFACTORED
679 xsltStyleItemSortPtr comp
;
681 xsltStylePreCompPtr comp
;
683 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
686 #ifdef XSLT_REFACTORED
687 comp
= (xsltStyleItemSortPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_SORT
);
689 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_SORT
);
697 comp
->stype
= xsltEvalStaticAttrValueTemplate(style
, inst
,
698 (const xmlChar
*)"data-type",
699 NULL
, &comp
->has_stype
);
700 if (comp
->stype
!= NULL
) {
701 if (xmlStrEqual(comp
->stype
, (const xmlChar
*) "text"))
703 else if (xmlStrEqual(comp
->stype
, (const xmlChar
*) "number"))
706 xsltTransformError(NULL
, style
, inst
,
707 "xsltSortComp: no support for data-type = %s\n", comp
->stype
);
708 comp
->number
= 0; /* use default */
709 if (style
!= NULL
) style
->warnings
++;
712 comp
->order
= xsltEvalStaticAttrValueTemplate(style
, inst
,
713 (const xmlChar
*)"order",
714 NULL
, &comp
->has_order
);
715 if (comp
->order
!= NULL
) {
716 if (xmlStrEqual(comp
->order
, (const xmlChar
*) "ascending"))
717 comp
->descending
= 0;
718 else if (xmlStrEqual(comp
->order
, (const xmlChar
*) "descending"))
719 comp
->descending
= 1;
721 xsltTransformError(NULL
, style
, inst
,
722 "xsltSortComp: invalid value %s for order\n", comp
->order
);
723 comp
->descending
= 0; /* use default */
724 if (style
!= NULL
) style
->warnings
++;
727 comp
->case_order
= xsltEvalStaticAttrValueTemplate(style
, inst
,
728 (const xmlChar
*)"case-order",
729 NULL
, &comp
->has_use
);
730 if (comp
->case_order
!= NULL
) {
731 if (xmlStrEqual(comp
->case_order
, (const xmlChar
*) "upper-first"))
732 comp
->lower_first
= 0;
733 else if (xmlStrEqual(comp
->case_order
, (const xmlChar
*) "lower-first"))
734 comp
->lower_first
= 1;
736 xsltTransformError(NULL
, style
, inst
,
737 "xsltSortComp: invalid value %s for order\n", comp
->order
);
738 comp
->lower_first
= 0; /* use default */
739 if (style
!= NULL
) style
->warnings
++;
743 comp
->lang
= xsltEvalStaticAttrValueTemplate(style
, inst
,
744 (const xmlChar
*)"lang",
745 NULL
, &comp
->has_lang
);
746 if (comp
->lang
!= NULL
) {
747 comp
->locale
= xsltNewLocale(comp
->lang
);
750 comp
->locale
= (xsltLocale
)0;
753 comp
->select
= xsltGetCNsProp(style
, inst
,(const xmlChar
*)"select", XSLT_NAMESPACE
);
754 if (comp
->select
== NULL
) {
756 * The default value of the select attribute is ., which will
757 * cause the string-value of the current node to be used as
760 comp
->select
= xmlDictLookup(style
->dict
, BAD_CAST
".", 1);
762 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
763 if (comp
->comp
== NULL
) {
764 xsltTransformError(NULL
, style
, inst
,
765 "xsltSortComp: could not compile select expression '%s'\n",
767 if (style
!= NULL
) style
->errors
++;
769 if (inst
->children
!= NULL
) {
770 xsltTransformError(NULL
, style
, inst
,
771 "xsl:sort : is not empty\n");
772 if (style
!= NULL
) style
->errors
++;
778 * @style: the XSLT stylesheet
779 * @inst: the xslt copy node
781 * Process the xslt copy node on the source node
784 xsltCopyComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
785 #ifdef XSLT_REFACTORED
786 xsltStyleItemCopyPtr comp
;
788 xsltStylePreCompPtr comp
;
791 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
793 #ifdef XSLT_REFACTORED
794 comp
= (xsltStyleItemCopyPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_COPY
);
796 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_COPY
);
805 comp
->use
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"use-attribute-sets",
807 if (comp
->use
== NULL
)
813 #ifdef XSLT_REFACTORED
814 /* Enable if ever needed for xsl:text. */
818 * @style: an XSLT compiled stylesheet
819 * @inst: the xslt text node
821 * TODO: This function is obsolete, since xsl:text won't
822 * be compiled, but removed from the tree.
824 * Process the xslt text node on the source node
827 xsltTextComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
828 #ifdef XSLT_REFACTORED
829 xsltStyleItemTextPtr comp
;
831 xsltStylePreCompPtr comp
;
835 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
838 #ifdef XSLT_REFACTORED
839 comp
= (xsltStyleItemTextPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_TEXT
);
841 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_TEXT
);
849 prop
= xsltGetCNsProp(style
, inst
,
850 (const xmlChar
*)"disable-output-escaping",
853 if (xmlStrEqual(prop
, (const xmlChar
*)"yes")) {
855 } else if (!xmlStrEqual(prop
,
856 (const xmlChar
*)"no")){
857 xsltTransformError(NULL
, style
, inst
,
858 "xsl:text: disable-output-escaping allows only yes or no\n");
859 if (style
!= NULL
) style
->warnings
++;
863 #endif /* else of XSLT_REFACTORED */
867 * @style: an XSLT compiled stylesheet
868 * @inst: the xslt element node
870 * Process the xslt element node on the source node
873 xsltElementComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
874 #ifdef XSLT_REFACTORED
875 xsltStyleItemElementPtr comp
;
877 xsltStylePreCompPtr comp
;
883 * namespace = { uri-reference }
884 * use-attribute-sets = qnames>
885 * <!-- Content: template -->
888 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
891 #ifdef XSLT_REFACTORED
892 comp
= (xsltStyleItemElementPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_ELEMENT
);
894 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_ELEMENT
);
906 * TODO: Precompile the AVT. See bug #344894.
908 comp
->name
= xsltEvalStaticAttrValueTemplate(style
, inst
,
909 (const xmlChar
*)"name", NULL
, &comp
->has_name
);
910 if (! comp
->has_name
) {
911 xsltTransformError(NULL
, style
, inst
,
912 "xsl:element: The attribute 'name' is missing.\n");
917 * Attribute "namespace".
920 * TODO: Precompile the AVT. See bug #344894.
922 comp
->ns
= xsltEvalStaticAttrValueTemplate(style
, inst
,
923 (const xmlChar
*)"namespace", NULL
, &comp
->has_ns
);
925 if (comp
->name
!= NULL
) {
926 if (xmlValidateQName(comp
->name
, 0)) {
927 xsltTransformError(NULL
, style
, inst
,
928 "xsl:element: The value '%s' of the attribute 'name' is "
929 "not a valid QName.\n", comp
->name
);
932 const xmlChar
*prefix
= NULL
, *name
;
934 name
= xsltSplitQName(style
->dict
, comp
->name
, &prefix
);
935 if (comp
->has_ns
== 0) {
940 * "If the namespace attribute is not present, then the QName is
941 * expanded into an expanded-name using the namespace declarations
942 * in effect for the xsl:element element, including any default
943 * namespace declaration.
945 ns
= xmlSearchNs(inst
->doc
, inst
, prefix
);
947 comp
->ns
= xmlDictLookup(style
->dict
, ns
->href
, -1);
949 #ifdef XSLT_REFACTORED
950 comp
->nsPrefix
= prefix
;
953 (void)name
; /* Suppress unused variable warning. */
955 } else if (prefix
!= NULL
) {
956 xsltTransformError(NULL
, style
, inst
,
957 "xsl:element: The prefixed QName '%s' "
958 "has no namespace binding in scope in the "
959 "stylesheet; this is an error, since the namespace was "
960 "not specified by the instruction itself.\n", comp
->name
);
964 if ((prefix
!= NULL
) &&
965 (!xmlStrncasecmp(prefix
, (xmlChar
*)"xml", 3)))
968 * Mark is to be skipped.
975 * Attribute "use-attribute-sets",
977 comp
->use
= xsltEvalStaticAttrValueTemplate(style
, inst
,
978 (const xmlChar
*)"use-attribute-sets",
979 NULL
, &comp
->has_use
);
987 * @style: an XSLT compiled stylesheet
988 * @inst: the xslt attribute node
990 * Process the xslt attribute node on the source node
993 xsltAttributeComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
994 #ifdef XSLT_REFACTORED
995 xsltStyleItemAttributePtr comp
;
997 xsltStylePreCompPtr comp
;
1003 * namespace = { uri-reference }>
1004 * <!-- Content: template -->
1007 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1010 #ifdef XSLT_REFACTORED
1011 comp
= (xsltStyleItemAttributePtr
) xsltNewStylePreComp(style
,
1012 XSLT_FUNC_ATTRIBUTE
);
1014 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_ATTRIBUTE
);
1026 * TODO: Precompile the AVT. See bug #344894.
1028 comp
->name
= xsltEvalStaticAttrValueTemplate(style
, inst
,
1029 (const xmlChar
*)"name",
1030 NULL
, &comp
->has_name
);
1031 if (! comp
->has_name
) {
1032 xsltTransformError(NULL
, style
, inst
,
1033 "XSLT-attribute: The attribute 'name' is missing.\n");
1038 * Attribute "namespace".
1041 * TODO: Precompile the AVT. See bug #344894.
1043 comp
->ns
= xsltEvalStaticAttrValueTemplate(style
, inst
,
1044 (const xmlChar
*)"namespace",
1045 NULL
, &comp
->has_ns
);
1047 if (comp
->name
!= NULL
) {
1048 if (xmlValidateQName(comp
->name
, 0)) {
1049 xsltTransformError(NULL
, style
, inst
,
1050 "xsl:attribute: The value '%s' of the attribute 'name' is "
1051 "not a valid QName.\n", comp
->name
);
1053 } else if (xmlStrEqual(comp
->name
, BAD_CAST
"xmlns")) {
1054 xsltTransformError(NULL
, style
, inst
,
1055 "xsl:attribute: The attribute name 'xmlns' is not allowed.\n");
1058 const xmlChar
*prefix
= NULL
, *name
;
1060 name
= xsltSplitQName(style
->dict
, comp
->name
, &prefix
);
1061 if (prefix
!= NULL
) {
1062 if (comp
->has_ns
== 0) {
1067 * "If the namespace attribute is not present, then the
1068 * QName is expanded into an expanded-name using the
1069 * namespace declarations in effect for the xsl:element
1070 * element, including any default namespace declaration.
1072 ns
= xmlSearchNs(inst
->doc
, inst
, prefix
);
1074 comp
->ns
= xmlDictLookup(style
->dict
, ns
->href
, -1);
1076 #ifdef XSLT_REFACTORED
1077 comp
->nsPrefix
= prefix
;
1080 (void)name
; /* Suppress unused variable warning. */
1083 xsltTransformError(NULL
, style
, inst
,
1084 "xsl:attribute: The prefixed QName '%s' "
1085 "has no namespace binding in scope in the "
1086 "stylesheet; this is an error, since the "
1087 "namespace was not specified by the instruction "
1088 "itself.\n", comp
->name
);
1099 * @style: an XSLT compiled stylesheet
1100 * @inst: the xslt comment node
1102 * Process the xslt comment node on the source node
1105 xsltCommentComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1106 #ifdef XSLT_REFACTORED
1107 xsltStyleItemCommentPtr comp
;
1109 xsltStylePreCompPtr comp
;
1112 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1115 #ifdef XSLT_REFACTORED
1116 comp
= (xsltStyleItemCommentPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_COMMENT
);
1118 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_COMMENT
);
1128 * xsltProcessingInstructionComp:
1129 * @style: an XSLT compiled stylesheet
1130 * @inst: the xslt processing-instruction node
1132 * Process the xslt processing-instruction node on the source node
1135 xsltProcessingInstructionComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1136 #ifdef XSLT_REFACTORED
1137 xsltStyleItemPIPtr comp
;
1139 xsltStylePreCompPtr comp
;
1142 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1145 #ifdef XSLT_REFACTORED
1146 comp
= (xsltStyleItemPIPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_PI
);
1148 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_PI
);
1156 comp
->name
= xsltEvalStaticAttrValueTemplate(style
, inst
,
1157 (const xmlChar
*)"name",
1158 XSLT_NAMESPACE
, &comp
->has_name
);
1163 * @style: an XSLT compiled stylesheet
1164 * @inst: the xslt copy-of node
1166 * Process the xslt copy-of node on the source node
1169 xsltCopyOfComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1170 #ifdef XSLT_REFACTORED
1171 xsltStyleItemCopyOfPtr comp
;
1173 xsltStylePreCompPtr comp
;
1176 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1179 #ifdef XSLT_REFACTORED
1180 comp
= (xsltStyleItemCopyOfPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_COPYOF
);
1182 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_COPYOF
);
1190 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1192 if (comp
->select
== NULL
) {
1193 xsltTransformError(NULL
, style
, inst
,
1194 "xsl:copy-of : select is missing\n");
1195 if (style
!= NULL
) style
->errors
++;
1198 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1199 if (comp
->comp
== NULL
) {
1200 xsltTransformError(NULL
, style
, inst
,
1201 "xsl:copy-of : could not compile select expression '%s'\n",
1203 if (style
!= NULL
) style
->errors
++;
1209 * @style: an XSLT compiled stylesheet
1210 * @inst: the xslt value-of node
1212 * Process the xslt value-of node on the source node
1215 xsltValueOfComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1216 #ifdef XSLT_REFACTORED
1217 xsltStyleItemValueOfPtr comp
;
1219 xsltStylePreCompPtr comp
;
1221 const xmlChar
*prop
;
1223 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1226 #ifdef XSLT_REFACTORED
1227 comp
= (xsltStyleItemValueOfPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_VALUEOF
);
1229 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_VALUEOF
);
1237 prop
= xsltGetCNsProp(style
, inst
,
1238 (const xmlChar
*)"disable-output-escaping",
1241 if (xmlStrEqual(prop
, (const xmlChar
*)"yes")) {
1243 } else if (!xmlStrEqual(prop
,
1244 (const xmlChar
*)"no")){
1245 xsltTransformError(NULL
, style
, inst
,
1246 "xsl:value-of : disable-output-escaping allows only yes or no\n");
1247 if (style
!= NULL
) style
->warnings
++;
1250 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1252 if (comp
->select
== NULL
) {
1253 xsltTransformError(NULL
, style
, inst
,
1254 "xsl:value-of : select is missing\n");
1255 if (style
!= NULL
) style
->errors
++;
1258 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1259 if (comp
->comp
== NULL
) {
1260 xsltTransformError(NULL
, style
, inst
,
1261 "xsl:value-of : could not compile select expression '%s'\n",
1263 if (style
!= NULL
) style
->errors
++;
1268 xsltGetQNameProperty(xsltStylesheetPtr style
, xmlNodePtr inst
,
1269 const xmlChar
*propName
,
1271 int *hasProp
, const xmlChar
**nsName
,
1272 const xmlChar
** localName
)
1274 const xmlChar
*prop
;
1283 prop
= xsltGetCNsProp(style
, inst
, propName
, XSLT_NAMESPACE
);
1286 xsltTransformError(NULL
, style
, inst
,
1287 "The attribute '%s' is missing.\n", propName
);
1294 if (xmlValidateQName(prop
, 0)) {
1295 xsltTransformError(NULL
, style
, inst
,
1296 "The value '%s' of the attribute "
1297 "'%s' is not a valid QName.\n", prop
, propName
);
1302 * @prop will be in the string dict afterwards, @URI not.
1304 URI
= xsltGetQNameURI2(style
, inst
, &prop
);
1314 * Fixes bug #308441: Put the ns-name in the dict
1315 * in order to pointer compare names during XPath's
1319 *nsName
= xmlDictLookup(style
->dict
, URI
, -1);
1320 /* comp->has_ns = 1; */
1329 * xsltWithParamComp:
1330 * @style: an XSLT compiled stylesheet
1331 * @inst: the xslt with-param node
1333 * Process the xslt with-param node on the source node
1334 * Allowed parents: xsl:call-template, xsl:apply-templates.
1337 * select = expression>
1338 * <!-- Content: template -->
1342 xsltWithParamComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1343 #ifdef XSLT_REFACTORED
1344 xsltStyleItemWithParamPtr comp
;
1346 xsltStylePreCompPtr comp
;
1349 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1352 #ifdef XSLT_REFACTORED
1353 comp
= (xsltStyleItemWithParamPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_WITHPARAM
);
1355 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_WITHPARAM
);
1366 xsltGetQNameProperty(style
, inst
, BAD_CAST
"name",
1367 1, &(comp
->has_name
), &(comp
->ns
), &(comp
->name
));
1371 * Attribute "select".
1373 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1375 if (comp
->select
!= NULL
) {
1376 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1377 if (comp
->comp
== NULL
) {
1378 xsltTransformError(NULL
, style
, inst
,
1379 "XSLT-with-param: Failed to compile select "
1380 "expression '%s'\n", comp
->select
);
1383 if (inst
->children
!= NULL
) {
1384 xsltTransformError(NULL
, style
, inst
,
1385 "XSLT-with-param: The content should be empty since "
1386 "the attribute select is present.\n");
1394 * @style: an XSLT compiled stylesheet
1395 * @cur: the xslt number node
1397 * Process the xslt number node on the source node
1400 xsltNumberComp(xsltStylesheetPtr style
, xmlNodePtr cur
) {
1401 #ifdef XSLT_REFACTORED
1402 xsltStyleItemNumberPtr comp
;
1404 xsltStylePreCompPtr comp
;
1406 const xmlChar
*prop
;
1408 if ((style
== NULL
) || (cur
== NULL
) || (cur
->type
!= XML_ELEMENT_NODE
))
1411 #ifdef XSLT_REFACTORED
1412 comp
= (xsltStyleItemNumberPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_NUMBER
);
1414 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_NUMBER
);
1421 comp
->numdata
.doc
= cur
->doc
;
1422 comp
->numdata
.node
= cur
;
1423 comp
->numdata
.value
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"value",
1426 prop
= xsltEvalStaticAttrValueTemplate(style
, cur
,
1427 (const xmlChar
*)"format",
1428 XSLT_NAMESPACE
, &comp
->numdata
.has_format
);
1429 if (comp
->numdata
.has_format
== 0) {
1430 comp
->numdata
.format
= xmlDictLookup(style
->dict
, BAD_CAST
"" , 0);
1432 comp
->numdata
.format
= prop
;
1435 comp
->numdata
.count
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"count",
1437 comp
->numdata
.from
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"from",
1440 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"count", XSLT_NAMESPACE
);
1442 comp
->numdata
.countPat
= xsltCompilePattern(prop
, cur
->doc
, cur
, style
,
1446 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"from", XSLT_NAMESPACE
);
1448 comp
->numdata
.fromPat
= xsltCompilePattern(prop
, cur
->doc
, cur
, style
,
1452 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"level", XSLT_NAMESPACE
);
1454 if (xmlStrEqual(prop
, BAD_CAST("single")) ||
1455 xmlStrEqual(prop
, BAD_CAST("multiple")) ||
1456 xmlStrEqual(prop
, BAD_CAST("any"))) {
1457 comp
->numdata
.level
= prop
;
1459 xsltTransformError(NULL
, style
, cur
,
1460 "xsl:number : invalid value %s for level\n", prop
);
1461 if (style
!= NULL
) style
->warnings
++;
1465 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"lang", XSLT_NAMESPACE
);
1467 xsltTransformError(NULL
, style
, cur
,
1468 "xsl:number : lang attribute not implemented\n");
1469 XSLT_TODO
; /* xsl:number lang attribute */
1472 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"letter-value", XSLT_NAMESPACE
);
1474 if (xmlStrEqual(prop
, BAD_CAST("alphabetic"))) {
1475 xsltTransformError(NULL
, style
, cur
,
1476 "xsl:number : letter-value 'alphabetic' not implemented\n");
1477 if (style
!= NULL
) style
->warnings
++;
1478 XSLT_TODO
; /* xsl:number letter-value attribute alphabetic */
1479 } else if (xmlStrEqual(prop
, BAD_CAST("traditional"))) {
1480 xsltTransformError(NULL
, style
, cur
,
1481 "xsl:number : letter-value 'traditional' not implemented\n");
1482 if (style
!= NULL
) style
->warnings
++;
1483 XSLT_TODO
; /* xsl:number letter-value attribute traditional */
1485 xsltTransformError(NULL
, style
, cur
,
1486 "xsl:number : invalid value %s for letter-value\n", prop
);
1487 if (style
!= NULL
) style
->warnings
++;
1491 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"grouping-separator",
1494 comp
->numdata
.groupingCharacterLen
= xmlStrlen(prop
);
1495 comp
->numdata
.groupingCharacter
=
1496 xsltGetUTF8Char(prop
, &(comp
->numdata
.groupingCharacterLen
));
1499 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"grouping-size", XSLT_NAMESPACE
);
1501 sscanf((char *)prop
, "%d", &comp
->numdata
.digitsPerGroup
);
1503 comp
->numdata
.groupingCharacter
= 0;
1506 /* Set default values */
1507 if (comp
->numdata
.value
== NULL
) {
1508 if (comp
->numdata
.level
== NULL
) {
1509 comp
->numdata
.level
= xmlDictLookup(style
->dict
,
1510 BAD_CAST
"single", 6);
1517 * xsltApplyImportsComp:
1518 * @style: an XSLT compiled stylesheet
1519 * @inst: the xslt apply-imports node
1521 * Process the xslt apply-imports node on the source node
1524 xsltApplyImportsComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1525 #ifdef XSLT_REFACTORED
1526 xsltStyleItemApplyImportsPtr comp
;
1528 xsltStylePreCompPtr comp
;
1531 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1534 #ifdef XSLT_REFACTORED
1535 comp
= (xsltStyleItemApplyImportsPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_APPLYIMPORTS
);
1537 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_APPLYIMPORTS
);
1547 * xsltCallTemplateComp:
1548 * @style: an XSLT compiled stylesheet
1549 * @inst: the xslt call-template node
1551 * Process the xslt call-template node on the source node
1554 xsltCallTemplateComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1555 #ifdef XSLT_REFACTORED
1556 xsltStyleItemCallTemplatePtr comp
;
1558 xsltStylePreCompPtr comp
;
1561 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1564 #ifdef XSLT_REFACTORED
1565 comp
= (xsltStyleItemCallTemplatePtr
)
1566 xsltNewStylePreComp(style
, XSLT_FUNC_CALLTEMPLATE
);
1568 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_CALLTEMPLATE
);
1579 xsltGetQNameProperty(style
, inst
, BAD_CAST
"name",
1580 1, &(comp
->has_name
), &(comp
->ns
), &(comp
->name
));
1586 * xsltApplyTemplatesComp:
1587 * @style: an XSLT compiled stylesheet
1588 * @inst: the apply-templates node
1590 * Process the apply-templates node on the source node
1593 xsltApplyTemplatesComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1594 #ifdef XSLT_REFACTORED
1595 xsltStyleItemApplyTemplatesPtr comp
;
1597 xsltStylePreCompPtr comp
;
1600 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1603 #ifdef XSLT_REFACTORED
1604 comp
= (xsltStyleItemApplyTemplatesPtr
)
1605 xsltNewStylePreComp(style
, XSLT_FUNC_APPLYTEMPLATES
);
1607 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_APPLYTEMPLATES
);
1618 xsltGetQNameProperty(style
, inst
, BAD_CAST
"mode",
1619 0, NULL
, &(comp
->modeURI
), &(comp
->mode
));
1621 * Attribute "select".
1623 comp
->select
= xsltGetCNsProp(style
, inst
, BAD_CAST
"select",
1625 if (comp
->select
!= NULL
) {
1626 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1627 if (comp
->comp
== NULL
) {
1628 xsltTransformError(NULL
, style
, inst
,
1629 "XSLT-apply-templates: could not compile select "
1630 "expression '%s'\n", comp
->select
);
1634 /* TODO: handle (or skip) the xsl:sort and xsl:with-param */
1639 * @style: an XSLT compiled stylesheet
1640 * @inst: the xslt choose node
1642 * Process the xslt choose node on the source node
1645 xsltChooseComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1646 #ifdef XSLT_REFACTORED
1647 xsltStyleItemChoosePtr comp
;
1649 xsltStylePreCompPtr comp
;
1652 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1655 #ifdef XSLT_REFACTORED
1656 comp
= (xsltStyleItemChoosePtr
)
1657 xsltNewStylePreComp(style
, XSLT_FUNC_CHOOSE
);
1659 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_CHOOSE
);
1670 * @style: an XSLT compiled stylesheet
1671 * @inst: the xslt if node
1673 * Process the xslt if node on the source node
1676 xsltIfComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1677 #ifdef XSLT_REFACTORED
1678 xsltStyleItemIfPtr comp
;
1680 xsltStylePreCompPtr comp
;
1683 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1686 #ifdef XSLT_REFACTORED
1687 comp
= (xsltStyleItemIfPtr
)
1688 xsltNewStylePreComp(style
, XSLT_FUNC_IF
);
1690 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_IF
);
1698 comp
->test
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"test", XSLT_NAMESPACE
);
1699 if (comp
->test
== NULL
) {
1700 xsltTransformError(NULL
, style
, inst
,
1701 "xsl:if : test is not defined\n");
1702 if (style
!= NULL
) style
->errors
++;
1705 comp
->comp
= xsltXPathCompile(style
, comp
->test
);
1706 if (comp
->comp
== NULL
) {
1707 xsltTransformError(NULL
, style
, inst
,
1708 "xsl:if : could not compile test expression '%s'\n",
1710 if (style
!= NULL
) style
->errors
++;
1716 * @style: an XSLT compiled stylesheet
1717 * @inst: the xslt if node
1719 * Process the xslt if node on the source node
1722 xsltWhenComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1723 #ifdef XSLT_REFACTORED
1724 xsltStyleItemWhenPtr comp
;
1726 xsltStylePreCompPtr comp
;
1729 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1732 #ifdef XSLT_REFACTORED
1733 comp
= (xsltStyleItemWhenPtr
)
1734 xsltNewStylePreComp(style
, XSLT_FUNC_WHEN
);
1736 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_WHEN
);
1744 comp
->test
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"test", XSLT_NAMESPACE
);
1745 if (comp
->test
== NULL
) {
1746 xsltTransformError(NULL
, style
, inst
,
1747 "xsl:when : test is not defined\n");
1748 if (style
!= NULL
) style
->errors
++;
1751 comp
->comp
= xsltXPathCompile(style
, comp
->test
);
1752 if (comp
->comp
== NULL
) {
1753 xsltTransformError(NULL
, style
, inst
,
1754 "xsl:when : could not compile test expression '%s'\n",
1756 if (style
!= NULL
) style
->errors
++;
1762 * @style: an XSLT compiled stylesheet
1763 * @inst: the xslt for-each node
1765 * Process the xslt for-each node on the source node
1768 xsltForEachComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1769 #ifdef XSLT_REFACTORED
1770 xsltStyleItemForEachPtr comp
;
1772 xsltStylePreCompPtr comp
;
1775 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1778 #ifdef XSLT_REFACTORED
1779 comp
= (xsltStyleItemForEachPtr
)
1780 xsltNewStylePreComp(style
, XSLT_FUNC_FOREACH
);
1782 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_FOREACH
);
1790 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1792 if (comp
->select
== NULL
) {
1793 xsltTransformError(NULL
, style
, inst
,
1794 "xsl:for-each : select is missing\n");
1795 if (style
!= NULL
) style
->errors
++;
1797 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1798 if (comp
->comp
== NULL
) {
1799 xsltTransformError(NULL
, style
, inst
,
1800 "xsl:for-each : could not compile select expression '%s'\n",
1802 if (style
!= NULL
) style
->errors
++;
1805 /* TODO: handle and skip the xsl:sort */
1810 * @style: an XSLT compiled stylesheet
1811 * @inst: the xslt variable node
1813 * Process the xslt variable node on the source node
1816 xsltVariableComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1817 #ifdef XSLT_REFACTORED
1818 xsltStyleItemVariablePtr comp
;
1820 xsltStylePreCompPtr comp
;
1823 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1826 #ifdef XSLT_REFACTORED
1827 comp
= (xsltStyleItemVariablePtr
)
1828 xsltNewStylePreComp(style
, XSLT_FUNC_VARIABLE
);
1830 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_VARIABLE
);
1839 * The full template resolution can be done statically
1845 xsltGetQNameProperty(style
, inst
, BAD_CAST
"name",
1846 1, &(comp
->has_name
), &(comp
->ns
), &(comp
->name
));
1850 * Attribute "select".
1852 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1854 if (comp
->select
!= NULL
) {
1855 #ifndef XSLT_REFACTORED
1858 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1859 if (comp
->comp
== NULL
) {
1860 xsltTransformError(NULL
, style
, inst
,
1861 "XSLT-variable: Failed to compile the XPath expression '%s'.\n",
1865 #ifdef XSLT_REFACTORED
1866 if (inst
->children
!= NULL
) {
1867 xsltTransformError(NULL
, style
, inst
,
1868 "XSLT-variable: There must be no child nodes, since the "
1869 "attribute 'select' was specified.\n");
1873 for (cur
= inst
->children
; cur
!= NULL
; cur
= cur
->next
) {
1874 if (cur
->type
!= XML_COMMENT_NODE
&&
1875 (cur
->type
!= XML_TEXT_NODE
|| !xsltIsBlank(cur
->content
)))
1877 xsltTransformError(NULL
, style
, inst
,
1878 "XSLT-variable: There must be no child nodes, since the "
1879 "attribute 'select' was specified.\n");
1889 * @style: an XSLT compiled stylesheet
1890 * @inst: the xslt param node
1892 * Process the xslt param node on the source node
1895 xsltParamComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1896 #ifdef XSLT_REFACTORED
1897 xsltStyleItemParamPtr comp
;
1899 xsltStylePreCompPtr comp
;
1902 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1905 #ifdef XSLT_REFACTORED
1906 comp
= (xsltStyleItemParamPtr
)
1907 xsltNewStylePreComp(style
, XSLT_FUNC_PARAM
);
1909 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_PARAM
);
1920 xsltGetQNameProperty(style
, inst
, BAD_CAST
"name",
1921 1, &(comp
->has_name
), &(comp
->ns
), &(comp
->name
));
1925 * Attribute "select".
1927 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1929 if (comp
->select
!= NULL
) {
1930 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1931 if (comp
->comp
== NULL
) {
1932 xsltTransformError(NULL
, style
, inst
,
1933 "XSLT-param: could not compile select expression '%s'.\n",
1937 if (inst
->children
!= NULL
) {
1938 xsltTransformError(NULL
, style
, inst
,
1939 "XSLT-param: The content should be empty since the "
1940 "attribute 'select' is present.\n");
1946 /************************************************************************
1948 * Generic interface *
1950 ************************************************************************/
1953 * xsltFreeStylePreComps:
1954 * @style: an XSLT transformation context
1956 * Free up the memory allocated by all precomputed blocks
1959 xsltFreeStylePreComps(xsltStylesheetPtr style
) {
1960 xsltElemPreCompPtr cur
, next
;
1965 cur
= style
->preComps
;
1966 while (cur
!= NULL
) {
1968 if (cur
->type
== XSLT_FUNC_EXTENSION
)
1971 xsltFreeStylePreComp((xsltStylePreCompPtr
) cur
);
1976 #ifdef XSLT_REFACTORED
1979 * xsltStylePreCompute:
1980 * @style: the XSLT stylesheet
1981 * @node: the element in the XSLT namespace
1983 * Precompute an XSLT element.
1984 * This expects the type of the element to be already
1985 * set in style->compCtxt->inode->type;
1988 xsltStylePreCompute(xsltStylesheetPtr style
, xmlNodePtr node
) {
1990 * The xsltXSLTElemMarker marker was set beforehand by
1991 * the parsing mechanism for all elements in the XSLT namespace.
1993 if (style
== NULL
) {
1994 if ((node
!= NULL
) && (node
->type
== XML_ELEMENT_NODE
))
2000 if (! IS_XSLT_ELEM_FAST(node
))
2004 if (XSLT_CCTXT(style
)->inode
->type
!= 0) {
2005 switch (XSLT_CCTXT(style
)->inode
->type
) {
2006 case XSLT_FUNC_APPLYTEMPLATES
:
2007 xsltApplyTemplatesComp(style
, node
);
2009 case XSLT_FUNC_WITHPARAM
:
2010 xsltWithParamComp(style
, node
);
2012 case XSLT_FUNC_VALUEOF
:
2013 xsltValueOfComp(style
, node
);
2015 case XSLT_FUNC_COPY
:
2016 xsltCopyComp(style
, node
);
2018 case XSLT_FUNC_COPYOF
:
2019 xsltCopyOfComp(style
, node
);
2022 xsltIfComp(style
, node
);
2024 case XSLT_FUNC_CHOOSE
:
2025 xsltChooseComp(style
, node
);
2027 case XSLT_FUNC_WHEN
:
2028 xsltWhenComp(style
, node
);
2030 case XSLT_FUNC_OTHERWISE
:
2033 case XSLT_FUNC_FOREACH
:
2034 xsltForEachComp(style
, node
);
2036 case XSLT_FUNC_APPLYIMPORTS
:
2037 xsltApplyImportsComp(style
, node
);
2039 case XSLT_FUNC_ATTRIBUTE
:
2040 xsltAttributeComp(style
, node
);
2042 case XSLT_FUNC_ELEMENT
:
2043 xsltElementComp(style
, node
);
2045 case XSLT_FUNC_SORT
:
2046 xsltSortComp(style
, node
);
2048 case XSLT_FUNC_COMMENT
:
2049 xsltCommentComp(style
, node
);
2051 case XSLT_FUNC_NUMBER
:
2052 xsltNumberComp(style
, node
);
2055 xsltProcessingInstructionComp(style
, node
);
2057 case XSLT_FUNC_CALLTEMPLATE
:
2058 xsltCallTemplateComp(style
, node
);
2060 case XSLT_FUNC_PARAM
:
2061 xsltParamComp(style
, node
);
2063 case XSLT_FUNC_VARIABLE
:
2064 xsltVariableComp(style
, node
);
2066 case XSLT_FUNC_FALLBACK
:
2069 case XSLT_FUNC_DOCUMENT
:
2071 node
->psvi
= (void *) xsltDocumentComp(style
, node
,
2074 case XSLT_FUNC_MESSAGE
:
2079 * NOTE that xsl:text, xsl:template, xsl:stylesheet,
2080 * xsl:transform, xsl:import, xsl:include are not expected
2081 * to be handed over to this function.
2083 xsltTransformError(NULL
, style
, node
,
2084 "Internal error: (xsltStylePreCompute) cannot handle "
2085 "the XSLT element '%s'.\n", node
->name
);
2091 * Fallback to string comparison.
2093 if (IS_XSLT_NAME(node
, "apply-templates")) {
2094 xsltApplyTemplatesComp(style
, node
);
2095 } else if (IS_XSLT_NAME(node
, "with-param")) {
2096 xsltWithParamComp(style
, node
);
2097 } else if (IS_XSLT_NAME(node
, "value-of")) {
2098 xsltValueOfComp(style
, node
);
2099 } else if (IS_XSLT_NAME(node
, "copy")) {
2100 xsltCopyComp(style
, node
);
2101 } else if (IS_XSLT_NAME(node
, "copy-of")) {
2102 xsltCopyOfComp(style
, node
);
2103 } else if (IS_XSLT_NAME(node
, "if")) {
2104 xsltIfComp(style
, node
);
2105 } else if (IS_XSLT_NAME(node
, "choose")) {
2106 xsltChooseComp(style
, node
);
2107 } else if (IS_XSLT_NAME(node
, "when")) {
2108 xsltWhenComp(style
, node
);
2109 } else if (IS_XSLT_NAME(node
, "otherwise")) {
2112 } else if (IS_XSLT_NAME(node
, "for-each")) {
2113 xsltForEachComp(style
, node
);
2114 } else if (IS_XSLT_NAME(node
, "apply-imports")) {
2115 xsltApplyImportsComp(style
, node
);
2116 } else if (IS_XSLT_NAME(node
, "attribute")) {
2117 xsltAttributeComp(style
, node
);
2118 } else if (IS_XSLT_NAME(node
, "element")) {
2119 xsltElementComp(style
, node
);
2120 } else if (IS_XSLT_NAME(node
, "sort")) {
2121 xsltSortComp(style
, node
);
2122 } else if (IS_XSLT_NAME(node
, "comment")) {
2123 xsltCommentComp(style
, node
);
2124 } else if (IS_XSLT_NAME(node
, "number")) {
2125 xsltNumberComp(style
, node
);
2126 } else if (IS_XSLT_NAME(node
, "processing-instruction")) {
2127 xsltProcessingInstructionComp(style
, node
);
2128 } else if (IS_XSLT_NAME(node
, "call-template")) {
2129 xsltCallTemplateComp(style
, node
);
2130 } else if (IS_XSLT_NAME(node
, "param")) {
2131 xsltParamComp(style
, node
);
2132 } else if (IS_XSLT_NAME(node
, "variable")) {
2133 xsltVariableComp(style
, node
);
2134 } else if (IS_XSLT_NAME(node
, "fallback")) {
2137 } else if (IS_XSLT_NAME(node
, "document")) {
2139 node
->psvi
= (void *) xsltDocumentComp(style
, node
,
2141 } else if (IS_XSLT_NAME(node
, "output")) {
2144 } else if (IS_XSLT_NAME(node
, "preserve-space")) {
2147 } else if (IS_XSLT_NAME(node
, "strip-space")) {
2150 } else if (IS_XSLT_NAME(node
, "key")) {
2153 } else if (IS_XSLT_NAME(node
, "message")) {
2155 } else if (IS_XSLT_NAME(node
, "attribute-set")) {
2158 } else if (IS_XSLT_NAME(node
, "namespace-alias")) {
2161 } else if (IS_XSLT_NAME(node
, "decimal-format")) {
2164 } else if (IS_XSLT_NAME(node
, "include")) {
2168 * NOTE that xsl:text, xsl:template, xsl:stylesheet,
2169 * xsl:transform, xsl:import, xsl:include are not expected
2170 * to be handed over to this function.
2172 xsltTransformError(NULL
, style
, node
,
2173 "Internal error: (xsltStylePreCompute) cannot handle "
2174 "the XSLT element '%s'.\n", node
->name
);
2180 * Assign the current list of in-scope namespaces to the
2181 * item. This is needed for XPath expressions.
2183 if (node
->psvi
!= NULL
) {
2184 ((xsltStylePreCompPtr
) node
->psvi
)->inScopeNs
=
2185 XSLT_CCTXT(style
)->inode
->inScopeNs
;
2192 * xsltStylePreCompute:
2193 * @style: the XSLT stylesheet
2194 * @inst: the instruction in the stylesheet
2196 * Precompute an XSLT stylesheet element
2199 xsltStylePreCompute(xsltStylesheetPtr style
, xmlNodePtr inst
) {
2201 * URGENT TODO: Normally inst->psvi Should never be reserved here,
2202 * BUT: since if we include the same stylesheet from
2203 * multiple imports, then the stylesheet will be parsed
2204 * again. We simply must not try to compute the stylesheet again.
2205 * TODO: Get to the point where we don't need to query the
2206 * namespace- and local-name of the node, but can evaluate this
2207 * using cctxt->style->inode->category;
2209 if ((inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
) ||
2210 (inst
->psvi
!= NULL
))
2213 if (IS_XSLT_ELEM(inst
)) {
2214 xsltStylePreCompPtr cur
;
2216 if (IS_XSLT_NAME(inst
, "apply-templates")) {
2217 xsltCheckInstructionElement(style
, inst
);
2218 xsltApplyTemplatesComp(style
, inst
);
2219 } else if (IS_XSLT_NAME(inst
, "with-param")) {
2220 xsltCheckParentElement(style
, inst
, BAD_CAST
"apply-templates",
2221 BAD_CAST
"call-template");
2222 xsltWithParamComp(style
, inst
);
2223 } else if (IS_XSLT_NAME(inst
, "value-of")) {
2224 xsltCheckInstructionElement(style
, inst
);
2225 xsltValueOfComp(style
, inst
);
2226 } else if (IS_XSLT_NAME(inst
, "copy")) {
2227 xsltCheckInstructionElement(style
, inst
);
2228 xsltCopyComp(style
, inst
);
2229 } else if (IS_XSLT_NAME(inst
, "copy-of")) {
2230 xsltCheckInstructionElement(style
, inst
);
2231 xsltCopyOfComp(style
, inst
);
2232 } else if (IS_XSLT_NAME(inst
, "if")) {
2233 xsltCheckInstructionElement(style
, inst
);
2234 xsltIfComp(style
, inst
);
2235 } else if (IS_XSLT_NAME(inst
, "when")) {
2236 xsltCheckParentElement(style
, inst
, BAD_CAST
"choose", NULL
);
2237 xsltWhenComp(style
, inst
);
2238 } else if (IS_XSLT_NAME(inst
, "choose")) {
2239 xsltCheckInstructionElement(style
, inst
);
2240 xsltChooseComp(style
, inst
);
2241 } else if (IS_XSLT_NAME(inst
, "for-each")) {
2242 xsltCheckInstructionElement(style
, inst
);
2243 xsltForEachComp(style
, inst
);
2244 } else if (IS_XSLT_NAME(inst
, "apply-imports")) {
2245 xsltCheckInstructionElement(style
, inst
);
2246 xsltApplyImportsComp(style
, inst
);
2247 } else if (IS_XSLT_NAME(inst
, "attribute")) {
2248 xmlNodePtr parent
= inst
->parent
;
2250 if ((parent
== NULL
) ||
2251 (parent
->type
!= XML_ELEMENT_NODE
) || (parent
->ns
== NULL
) ||
2252 ((parent
->ns
!= inst
->ns
) &&
2253 (!xmlStrEqual(parent
->ns
->href
, inst
->ns
->href
))) ||
2254 (!xmlStrEqual(parent
->name
, BAD_CAST
"attribute-set"))) {
2255 xsltCheckInstructionElement(style
, inst
);
2257 xsltAttributeComp(style
, inst
);
2258 } else if (IS_XSLT_NAME(inst
, "element")) {
2259 xsltCheckInstructionElement(style
, inst
);
2260 xsltElementComp(style
, inst
);
2261 } else if (IS_XSLT_NAME(inst
, "text")) {
2262 xsltCheckInstructionElement(style
, inst
);
2263 xsltTextComp(style
, inst
);
2264 } else if (IS_XSLT_NAME(inst
, "sort")) {
2265 xsltCheckParentElement(style
, inst
, BAD_CAST
"apply-templates",
2266 BAD_CAST
"for-each");
2267 xsltSortComp(style
, inst
);
2268 } else if (IS_XSLT_NAME(inst
, "comment")) {
2269 xsltCheckInstructionElement(style
, inst
);
2270 xsltCommentComp(style
, inst
);
2271 } else if (IS_XSLT_NAME(inst
, "number")) {
2272 xsltCheckInstructionElement(style
, inst
);
2273 xsltNumberComp(style
, inst
);
2274 } else if (IS_XSLT_NAME(inst
, "processing-instruction")) {
2275 xsltCheckInstructionElement(style
, inst
);
2276 xsltProcessingInstructionComp(style
, inst
);
2277 } else if (IS_XSLT_NAME(inst
, "call-template")) {
2278 xsltCheckInstructionElement(style
, inst
);
2279 xsltCallTemplateComp(style
, inst
);
2280 } else if (IS_XSLT_NAME(inst
, "param")) {
2281 if (xsltCheckTopLevelElement(style
, inst
, 0) == 0)
2282 xsltCheckInstructionElement(style
, inst
);
2283 xsltParamComp(style
, inst
);
2284 } else if (IS_XSLT_NAME(inst
, "variable")) {
2285 if (xsltCheckTopLevelElement(style
, inst
, 0) == 0)
2286 xsltCheckInstructionElement(style
, inst
);
2287 xsltVariableComp(style
, inst
);
2288 } else if (IS_XSLT_NAME(inst
, "otherwise")) {
2289 xsltCheckParentElement(style
, inst
, BAD_CAST
"choose", NULL
);
2290 xsltCheckInstructionElement(style
, inst
);
2292 } else if (IS_XSLT_NAME(inst
, "template")) {
2293 xsltCheckTopLevelElement(style
, inst
, 1);
2295 } else if (IS_XSLT_NAME(inst
, "output")) {
2296 xsltCheckTopLevelElement(style
, inst
, 1);
2298 } else if (IS_XSLT_NAME(inst
, "preserve-space")) {
2299 xsltCheckTopLevelElement(style
, inst
, 1);
2301 } else if (IS_XSLT_NAME(inst
, "strip-space")) {
2302 xsltCheckTopLevelElement(style
, inst
, 1);
2304 } else if ((IS_XSLT_NAME(inst
, "stylesheet")) ||
2305 (IS_XSLT_NAME(inst
, "transform"))) {
2306 xmlNodePtr parent
= inst
->parent
;
2308 if ((parent
== NULL
) || (parent
->type
!= XML_DOCUMENT_NODE
)) {
2309 xsltTransformError(NULL
, style
, inst
,
2310 "element %s only allowed only as root element\n",
2315 } else if (IS_XSLT_NAME(inst
, "key")) {
2316 xsltCheckTopLevelElement(style
, inst
, 1);
2318 } else if (IS_XSLT_NAME(inst
, "message")) {
2319 xsltCheckInstructionElement(style
, inst
);
2321 } else if (IS_XSLT_NAME(inst
, "attribute-set")) {
2322 xsltCheckTopLevelElement(style
, inst
, 1);
2324 } else if (IS_XSLT_NAME(inst
, "namespace-alias")) {
2325 xsltCheckTopLevelElement(style
, inst
, 1);
2327 } else if (IS_XSLT_NAME(inst
, "include")) {
2328 xsltCheckTopLevelElement(style
, inst
, 1);
2330 } else if (IS_XSLT_NAME(inst
, "import")) {
2331 xsltCheckTopLevelElement(style
, inst
, 1);
2333 } else if (IS_XSLT_NAME(inst
, "decimal-format")) {
2334 xsltCheckTopLevelElement(style
, inst
, 1);
2336 } else if (IS_XSLT_NAME(inst
, "fallback")) {
2337 xsltCheckInstructionElement(style
, inst
);
2339 } else if (IS_XSLT_NAME(inst
, "document")) {
2340 xsltCheckInstructionElement(style
, inst
);
2341 inst
->psvi
= (void *) xsltDocumentComp(style
, inst
,
2343 } else if ((style
== NULL
) || (style
->forwards_compatible
== 0)) {
2344 xsltTransformError(NULL
, style
, inst
,
2345 "xsltStylePreCompute: unknown xsl:%s\n", inst
->name
);
2346 if (style
!= NULL
) style
->warnings
++;
2349 cur
= (xsltStylePreCompPtr
) inst
->psvi
;
2351 * A ns-list is build for every XSLT item in the
2352 * node-tree. This is needed for XPath expressions.
2357 cur
->nsList
= xmlGetNsList(inst
->doc
, inst
);
2358 if (cur
->nsList
!= NULL
) {
2359 while (cur
->nsList
[i
] != NULL
)
2366 (void *) xsltPreComputeExtModuleElement(style
, inst
);
2369 * Unknown element, maybe registered at the context
2370 * level. Mark it for later recognition.
2372 if (inst
->psvi
== NULL
)
2373 inst
->psvi
= (void *) xsltExtMarker
;
2376 #endif /* XSLT_REFACTORED */