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
= (xsltTransformFunction
) xsltCopy
;break;
324 cur
->func
= (xsltTransformFunction
) xsltSort
;break;
326 cur
->func
= (xsltTransformFunction
) xsltText
;break;
327 case XSLT_FUNC_ELEMENT
:
328 cur
->func
= (xsltTransformFunction
) xsltElement
;break;
329 case XSLT_FUNC_ATTRIBUTE
:
330 cur
->func
= (xsltTransformFunction
) xsltAttribute
;break;
331 case XSLT_FUNC_COMMENT
:
332 cur
->func
= (xsltTransformFunction
) xsltComment
;break;
334 cur
->func
= (xsltTransformFunction
) xsltProcessingInstruction
;
336 case XSLT_FUNC_COPYOF
:
337 cur
->func
= (xsltTransformFunction
) xsltCopyOf
;break;
338 case XSLT_FUNC_VALUEOF
:
339 cur
->func
= (xsltTransformFunction
) xsltValueOf
;break;
340 case XSLT_FUNC_NUMBER
:
341 cur
->func
= (xsltTransformFunction
) xsltNumber
;break;
342 case XSLT_FUNC_APPLYIMPORTS
:
343 cur
->func
= (xsltTransformFunction
) xsltApplyImports
;break;
344 case XSLT_FUNC_CALLTEMPLATE
:
345 cur
->func
= (xsltTransformFunction
) xsltCallTemplate
;break;
346 case XSLT_FUNC_APPLYTEMPLATES
:
347 cur
->func
= (xsltTransformFunction
) xsltApplyTemplates
;break;
348 case XSLT_FUNC_CHOOSE
:
349 cur
->func
= (xsltTransformFunction
) xsltChoose
;break;
351 cur
->func
= (xsltTransformFunction
) xsltIf
;break;
352 case XSLT_FUNC_FOREACH
:
353 cur
->func
= (xsltTransformFunction
) xsltForEach
;break;
354 case XSLT_FUNC_DOCUMENT
:
355 cur
->func
= (xsltTransformFunction
) 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 } else if (prefix
!= NULL
) {
954 xsltTransformError(NULL
, style
, inst
,
955 "xsl:element: The prefixed QName '%s' "
956 "has no namespace binding in scope in the "
957 "stylesheet; this is an error, since the namespace was "
958 "not specified by the instruction itself.\n", comp
->name
);
962 if ((prefix
!= NULL
) &&
963 (!xmlStrncasecmp(prefix
, (xmlChar
*)"xml", 3)))
966 * Mark is to be skipped.
973 * Attribute "use-attribute-sets",
975 comp
->use
= xsltEvalStaticAttrValueTemplate(style
, inst
,
976 (const xmlChar
*)"use-attribute-sets",
977 NULL
, &comp
->has_use
);
985 * @style: an XSLT compiled stylesheet
986 * @inst: the xslt attribute node
988 * Process the xslt attribute node on the source node
991 xsltAttributeComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
992 #ifdef XSLT_REFACTORED
993 xsltStyleItemAttributePtr comp
;
995 xsltStylePreCompPtr comp
;
1001 * namespace = { uri-reference }>
1002 * <!-- Content: template -->
1005 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1008 #ifdef XSLT_REFACTORED
1009 comp
= (xsltStyleItemAttributePtr
) xsltNewStylePreComp(style
,
1010 XSLT_FUNC_ATTRIBUTE
);
1012 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_ATTRIBUTE
);
1024 * TODO: Precompile the AVT. See bug #344894.
1026 comp
->name
= xsltEvalStaticAttrValueTemplate(style
, inst
,
1027 (const xmlChar
*)"name",
1028 NULL
, &comp
->has_name
);
1029 if (! comp
->has_name
) {
1030 xsltTransformError(NULL
, style
, inst
,
1031 "XSLT-attribute: The attribute 'name' is missing.\n");
1036 * Attribute "namespace".
1039 * TODO: Precompile the AVT. See bug #344894.
1041 comp
->ns
= xsltEvalStaticAttrValueTemplate(style
, inst
,
1042 (const xmlChar
*)"namespace",
1043 NULL
, &comp
->has_ns
);
1045 if (comp
->name
!= NULL
) {
1046 if (xmlValidateQName(comp
->name
, 0)) {
1047 xsltTransformError(NULL
, style
, inst
,
1048 "xsl:attribute: The value '%s' of the attribute 'name' is "
1049 "not a valid QName.\n", comp
->name
);
1051 } else if (xmlStrEqual(comp
->name
, BAD_CAST
"xmlns")) {
1052 xsltTransformError(NULL
, style
, inst
,
1053 "xsl:attribute: The attribute name 'xmlns' is not allowed.\n");
1056 const xmlChar
*prefix
= NULL
, *name
;
1058 name
= xsltSplitQName(style
->dict
, comp
->name
, &prefix
);
1059 if (prefix
!= NULL
) {
1060 if (comp
->has_ns
== 0) {
1065 * "If the namespace attribute is not present, then the
1066 * QName is expanded into an expanded-name using the
1067 * namespace declarations in effect for the xsl:element
1068 * element, including any default namespace declaration.
1070 ns
= xmlSearchNs(inst
->doc
, inst
, prefix
);
1072 comp
->ns
= xmlDictLookup(style
->dict
, ns
->href
, -1);
1074 #ifdef XSLT_REFACTORED
1075 comp
->nsPrefix
= prefix
;
1079 xsltTransformError(NULL
, style
, inst
,
1080 "xsl:attribute: The prefixed QName '%s' "
1081 "has no namespace binding in scope in the "
1082 "stylesheet; this is an error, since the "
1083 "namespace was not specified by the instruction "
1084 "itself.\n", comp
->name
);
1095 * @style: an XSLT compiled stylesheet
1096 * @inst: the xslt comment node
1098 * Process the xslt comment node on the source node
1101 xsltCommentComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1102 #ifdef XSLT_REFACTORED
1103 xsltStyleItemCommentPtr comp
;
1105 xsltStylePreCompPtr comp
;
1108 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1111 #ifdef XSLT_REFACTORED
1112 comp
= (xsltStyleItemCommentPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_COMMENT
);
1114 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_COMMENT
);
1124 * xsltProcessingInstructionComp:
1125 * @style: an XSLT compiled stylesheet
1126 * @inst: the xslt processing-instruction node
1128 * Process the xslt processing-instruction node on the source node
1131 xsltProcessingInstructionComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1132 #ifdef XSLT_REFACTORED
1133 xsltStyleItemPIPtr comp
;
1135 xsltStylePreCompPtr comp
;
1138 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1141 #ifdef XSLT_REFACTORED
1142 comp
= (xsltStyleItemPIPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_PI
);
1144 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_PI
);
1152 comp
->name
= xsltEvalStaticAttrValueTemplate(style
, inst
,
1153 (const xmlChar
*)"name",
1154 XSLT_NAMESPACE
, &comp
->has_name
);
1159 * @style: an XSLT compiled stylesheet
1160 * @inst: the xslt copy-of node
1162 * Process the xslt copy-of node on the source node
1165 xsltCopyOfComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1166 #ifdef XSLT_REFACTORED
1167 xsltStyleItemCopyOfPtr comp
;
1169 xsltStylePreCompPtr comp
;
1172 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1175 #ifdef XSLT_REFACTORED
1176 comp
= (xsltStyleItemCopyOfPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_COPYOF
);
1178 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_COPYOF
);
1186 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1188 if (comp
->select
== NULL
) {
1189 xsltTransformError(NULL
, style
, inst
,
1190 "xsl:copy-of : select is missing\n");
1191 if (style
!= NULL
) style
->errors
++;
1194 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1195 if (comp
->comp
== NULL
) {
1196 xsltTransformError(NULL
, style
, inst
,
1197 "xsl:copy-of : could not compile select expression '%s'\n",
1199 if (style
!= NULL
) style
->errors
++;
1205 * @style: an XSLT compiled stylesheet
1206 * @inst: the xslt value-of node
1208 * Process the xslt value-of node on the source node
1211 xsltValueOfComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1212 #ifdef XSLT_REFACTORED
1213 xsltStyleItemValueOfPtr comp
;
1215 xsltStylePreCompPtr comp
;
1217 const xmlChar
*prop
;
1219 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1222 #ifdef XSLT_REFACTORED
1223 comp
= (xsltStyleItemValueOfPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_VALUEOF
);
1225 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_VALUEOF
);
1233 prop
= xsltGetCNsProp(style
, inst
,
1234 (const xmlChar
*)"disable-output-escaping",
1237 if (xmlStrEqual(prop
, (const xmlChar
*)"yes")) {
1239 } else if (!xmlStrEqual(prop
,
1240 (const xmlChar
*)"no")){
1241 xsltTransformError(NULL
, style
, inst
,
1242 "xsl:value-of : disable-output-escaping allows only yes or no\n");
1243 if (style
!= NULL
) style
->warnings
++;
1246 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1248 if (comp
->select
== NULL
) {
1249 xsltTransformError(NULL
, style
, inst
,
1250 "xsl:value-of : select is missing\n");
1251 if (style
!= NULL
) style
->errors
++;
1254 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1255 if (comp
->comp
== NULL
) {
1256 xsltTransformError(NULL
, style
, inst
,
1257 "xsl:value-of : could not compile select expression '%s'\n",
1259 if (style
!= NULL
) style
->errors
++;
1264 xsltGetQNameProperty(xsltStylesheetPtr style
, xmlNodePtr inst
,
1265 const xmlChar
*propName
,
1267 int *hasProp
, const xmlChar
**nsName
,
1268 const xmlChar
** localName
)
1270 const xmlChar
*prop
;
1279 prop
= xsltGetCNsProp(style
, inst
, propName
, XSLT_NAMESPACE
);
1282 xsltTransformError(NULL
, style
, inst
,
1283 "The attribute '%s' is missing.\n", propName
);
1290 if (xmlValidateQName(prop
, 0)) {
1291 xsltTransformError(NULL
, style
, inst
,
1292 "The value '%s' of the attribute "
1293 "'%s' is not a valid QName.\n", prop
, propName
);
1298 * @prop will be in the string dict afterwards, @URI not.
1300 URI
= xsltGetQNameURI2(style
, inst
, &prop
);
1309 * Fixes bug #308441: Put the ns-name in the dict
1310 * in order to pointer compare names during XPath's
1314 *nsName
= xmlDictLookup(style
->dict
, URI
, -1);
1315 /* comp->has_ns = 1; */
1324 * xsltWithParamComp:
1325 * @style: an XSLT compiled stylesheet
1326 * @inst: the xslt with-param node
1328 * Process the xslt with-param node on the source node
1329 * Allowed parents: xsl:call-template, xsl:apply-templates.
1332 * select = expression>
1333 * <!-- Content: template -->
1337 xsltWithParamComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1338 #ifdef XSLT_REFACTORED
1339 xsltStyleItemWithParamPtr comp
;
1341 xsltStylePreCompPtr comp
;
1344 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1347 #ifdef XSLT_REFACTORED
1348 comp
= (xsltStyleItemWithParamPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_WITHPARAM
);
1350 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_WITHPARAM
);
1361 xsltGetQNameProperty(style
, inst
, BAD_CAST
"name",
1362 1, &(comp
->has_name
), &(comp
->ns
), &(comp
->name
));
1366 * Attribute "select".
1368 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1370 if (comp
->select
!= NULL
) {
1371 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1372 if (comp
->comp
== NULL
) {
1373 xsltTransformError(NULL
, style
, inst
,
1374 "XSLT-with-param: Failed to compile select "
1375 "expression '%s'\n", comp
->select
);
1378 if (inst
->children
!= NULL
) {
1379 xsltTransformError(NULL
, style
, inst
,
1380 "XSLT-with-param: The content should be empty since "
1381 "the attribute select is present.\n");
1389 * @style: an XSLT compiled stylesheet
1390 * @cur: the xslt number node
1392 * Process the xslt number node on the source node
1395 xsltNumberComp(xsltStylesheetPtr style
, xmlNodePtr cur
) {
1396 #ifdef XSLT_REFACTORED
1397 xsltStyleItemNumberPtr comp
;
1399 xsltStylePreCompPtr comp
;
1401 const xmlChar
*prop
;
1403 if ((style
== NULL
) || (cur
== NULL
) || (cur
->type
!= XML_ELEMENT_NODE
))
1406 #ifdef XSLT_REFACTORED
1407 comp
= (xsltStyleItemNumberPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_NUMBER
);
1409 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_NUMBER
);
1416 if ((style
== NULL
) || (cur
== NULL
))
1419 comp
->numdata
.doc
= cur
->doc
;
1420 comp
->numdata
.node
= cur
;
1421 comp
->numdata
.value
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"value",
1424 prop
= xsltEvalStaticAttrValueTemplate(style
, cur
,
1425 (const xmlChar
*)"format",
1426 XSLT_NAMESPACE
, &comp
->numdata
.has_format
);
1427 if (comp
->numdata
.has_format
== 0) {
1428 comp
->numdata
.format
= xmlDictLookup(style
->dict
, BAD_CAST
"" , 0);
1430 comp
->numdata
.format
= prop
;
1433 comp
->numdata
.count
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"count",
1435 comp
->numdata
.from
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"from",
1438 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"count", XSLT_NAMESPACE
);
1440 comp
->numdata
.countPat
= xsltCompilePattern(prop
, cur
->doc
, cur
, style
,
1444 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"from", XSLT_NAMESPACE
);
1446 comp
->numdata
.fromPat
= xsltCompilePattern(prop
, cur
->doc
, cur
, style
,
1450 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"level", XSLT_NAMESPACE
);
1452 if (xmlStrEqual(prop
, BAD_CAST("single")) ||
1453 xmlStrEqual(prop
, BAD_CAST("multiple")) ||
1454 xmlStrEqual(prop
, BAD_CAST("any"))) {
1455 comp
->numdata
.level
= prop
;
1457 xsltTransformError(NULL
, style
, cur
,
1458 "xsl:number : invalid value %s for level\n", prop
);
1459 if (style
!= NULL
) style
->warnings
++;
1463 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"lang", XSLT_NAMESPACE
);
1465 xsltTransformError(NULL
, style
, cur
,
1466 "xsl:number : lang attribute not implemented\n");
1467 XSLT_TODO
; /* xsl:number lang attribute */
1470 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"letter-value", XSLT_NAMESPACE
);
1472 if (xmlStrEqual(prop
, BAD_CAST("alphabetic"))) {
1473 xsltTransformError(NULL
, style
, cur
,
1474 "xsl:number : letter-value 'alphabetic' not implemented\n");
1475 if (style
!= NULL
) style
->warnings
++;
1476 XSLT_TODO
; /* xsl:number letter-value attribute alphabetic */
1477 } else if (xmlStrEqual(prop
, BAD_CAST("traditional"))) {
1478 xsltTransformError(NULL
, style
, cur
,
1479 "xsl:number : letter-value 'traditional' not implemented\n");
1480 if (style
!= NULL
) style
->warnings
++;
1481 XSLT_TODO
; /* xsl:number letter-value attribute traditional */
1483 xsltTransformError(NULL
, style
, cur
,
1484 "xsl:number : invalid value %s for letter-value\n", prop
);
1485 if (style
!= NULL
) style
->warnings
++;
1489 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"grouping-separator",
1492 comp
->numdata
.groupingCharacterLen
= xmlStrlen(prop
);
1493 comp
->numdata
.groupingCharacter
=
1494 xsltGetUTF8Char(prop
, &(comp
->numdata
.groupingCharacterLen
));
1497 prop
= xsltGetCNsProp(style
, cur
, (const xmlChar
*)"grouping-size", XSLT_NAMESPACE
);
1499 sscanf((char *)prop
, "%d", &comp
->numdata
.digitsPerGroup
);
1501 comp
->numdata
.groupingCharacter
= 0;
1504 /* Set default values */
1505 if (comp
->numdata
.value
== NULL
) {
1506 if (comp
->numdata
.level
== NULL
) {
1507 comp
->numdata
.level
= xmlDictLookup(style
->dict
,
1508 BAD_CAST
"single", 6);
1515 * xsltApplyImportsComp:
1516 * @style: an XSLT compiled stylesheet
1517 * @inst: the xslt apply-imports node
1519 * Process the xslt apply-imports node on the source node
1522 xsltApplyImportsComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1523 #ifdef XSLT_REFACTORED
1524 xsltStyleItemApplyImportsPtr comp
;
1526 xsltStylePreCompPtr comp
;
1529 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1532 #ifdef XSLT_REFACTORED
1533 comp
= (xsltStyleItemApplyImportsPtr
) xsltNewStylePreComp(style
, XSLT_FUNC_APPLYIMPORTS
);
1535 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_APPLYIMPORTS
);
1545 * xsltCallTemplateComp:
1546 * @style: an XSLT compiled stylesheet
1547 * @inst: the xslt call-template node
1549 * Process the xslt call-template node on the source node
1552 xsltCallTemplateComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1553 #ifdef XSLT_REFACTORED
1554 xsltStyleItemCallTemplatePtr comp
;
1556 xsltStylePreCompPtr comp
;
1559 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1562 #ifdef XSLT_REFACTORED
1563 comp
= (xsltStyleItemCallTemplatePtr
)
1564 xsltNewStylePreComp(style
, XSLT_FUNC_CALLTEMPLATE
);
1566 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_CALLTEMPLATE
);
1577 xsltGetQNameProperty(style
, inst
, BAD_CAST
"name",
1578 1, &(comp
->has_name
), &(comp
->ns
), &(comp
->name
));
1584 * xsltApplyTemplatesComp:
1585 * @style: an XSLT compiled stylesheet
1586 * @inst: the apply-templates node
1588 * Process the apply-templates node on the source node
1591 xsltApplyTemplatesComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1592 #ifdef XSLT_REFACTORED
1593 xsltStyleItemApplyTemplatesPtr comp
;
1595 xsltStylePreCompPtr comp
;
1598 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1601 #ifdef XSLT_REFACTORED
1602 comp
= (xsltStyleItemApplyTemplatesPtr
)
1603 xsltNewStylePreComp(style
, XSLT_FUNC_APPLYTEMPLATES
);
1605 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_APPLYTEMPLATES
);
1616 xsltGetQNameProperty(style
, inst
, BAD_CAST
"mode",
1617 0, NULL
, &(comp
->modeURI
), &(comp
->mode
));
1619 * Attribute "select".
1621 comp
->select
= xsltGetCNsProp(style
, inst
, BAD_CAST
"select",
1623 if (comp
->select
!= NULL
) {
1624 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1625 if (comp
->comp
== NULL
) {
1626 xsltTransformError(NULL
, style
, inst
,
1627 "XSLT-apply-templates: could not compile select "
1628 "expression '%s'\n", comp
->select
);
1632 /* TODO: handle (or skip) the xsl:sort and xsl:with-param */
1637 * @style: an XSLT compiled stylesheet
1638 * @inst: the xslt choose node
1640 * Process the xslt choose node on the source node
1643 xsltChooseComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1644 #ifdef XSLT_REFACTORED
1645 xsltStyleItemChoosePtr comp
;
1647 xsltStylePreCompPtr comp
;
1650 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1653 #ifdef XSLT_REFACTORED
1654 comp
= (xsltStyleItemChoosePtr
)
1655 xsltNewStylePreComp(style
, XSLT_FUNC_CHOOSE
);
1657 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_CHOOSE
);
1668 * @style: an XSLT compiled stylesheet
1669 * @inst: the xslt if node
1671 * Process the xslt if node on the source node
1674 xsltIfComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1675 #ifdef XSLT_REFACTORED
1676 xsltStyleItemIfPtr comp
;
1678 xsltStylePreCompPtr comp
;
1681 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1684 #ifdef XSLT_REFACTORED
1685 comp
= (xsltStyleItemIfPtr
)
1686 xsltNewStylePreComp(style
, XSLT_FUNC_IF
);
1688 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_IF
);
1696 comp
->test
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"test", XSLT_NAMESPACE
);
1697 if (comp
->test
== NULL
) {
1698 xsltTransformError(NULL
, style
, inst
,
1699 "xsl:if : test is not defined\n");
1700 if (style
!= NULL
) style
->errors
++;
1703 comp
->comp
= xsltXPathCompile(style
, comp
->test
);
1704 if (comp
->comp
== NULL
) {
1705 xsltTransformError(NULL
, style
, inst
,
1706 "xsl:if : could not compile test expression '%s'\n",
1708 if (style
!= NULL
) style
->errors
++;
1714 * @style: an XSLT compiled stylesheet
1715 * @inst: the xslt if node
1717 * Process the xslt if node on the source node
1720 xsltWhenComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1721 #ifdef XSLT_REFACTORED
1722 xsltStyleItemWhenPtr comp
;
1724 xsltStylePreCompPtr comp
;
1727 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1730 #ifdef XSLT_REFACTORED
1731 comp
= (xsltStyleItemWhenPtr
)
1732 xsltNewStylePreComp(style
, XSLT_FUNC_WHEN
);
1734 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_WHEN
);
1742 comp
->test
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"test", XSLT_NAMESPACE
);
1743 if (comp
->test
== NULL
) {
1744 xsltTransformError(NULL
, style
, inst
,
1745 "xsl:when : test is not defined\n");
1746 if (style
!= NULL
) style
->errors
++;
1749 comp
->comp
= xsltXPathCompile(style
, comp
->test
);
1750 if (comp
->comp
== NULL
) {
1751 xsltTransformError(NULL
, style
, inst
,
1752 "xsl:when : could not compile test expression '%s'\n",
1754 if (style
!= NULL
) style
->errors
++;
1760 * @style: an XSLT compiled stylesheet
1761 * @inst: the xslt for-each node
1763 * Process the xslt for-each node on the source node
1766 xsltForEachComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1767 #ifdef XSLT_REFACTORED
1768 xsltStyleItemForEachPtr comp
;
1770 xsltStylePreCompPtr comp
;
1773 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1776 #ifdef XSLT_REFACTORED
1777 comp
= (xsltStyleItemForEachPtr
)
1778 xsltNewStylePreComp(style
, XSLT_FUNC_FOREACH
);
1780 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_FOREACH
);
1788 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1790 if (comp
->select
== NULL
) {
1791 xsltTransformError(NULL
, style
, inst
,
1792 "xsl:for-each : select is missing\n");
1793 if (style
!= NULL
) style
->errors
++;
1795 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1796 if (comp
->comp
== NULL
) {
1797 xsltTransformError(NULL
, style
, inst
,
1798 "xsl:for-each : could not compile select expression '%s'\n",
1800 if (style
!= NULL
) style
->errors
++;
1803 /* TODO: handle and skip the xsl:sort */
1808 * @style: an XSLT compiled stylesheet
1809 * @inst: the xslt variable node
1811 * Process the xslt variable node on the source node
1814 xsltVariableComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1815 #ifdef XSLT_REFACTORED
1816 xsltStyleItemVariablePtr comp
;
1818 xsltStylePreCompPtr comp
;
1821 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1824 #ifdef XSLT_REFACTORED
1825 comp
= (xsltStyleItemVariablePtr
)
1826 xsltNewStylePreComp(style
, XSLT_FUNC_VARIABLE
);
1828 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_VARIABLE
);
1837 * The full template resolution can be done statically
1843 xsltGetQNameProperty(style
, inst
, BAD_CAST
"name",
1844 1, &(comp
->has_name
), &(comp
->ns
), &(comp
->name
));
1848 * Attribute "select".
1850 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1852 if (comp
->select
!= NULL
) {
1853 #ifndef XSLT_REFACTORED
1856 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1857 if (comp
->comp
== NULL
) {
1858 xsltTransformError(NULL
, style
, inst
,
1859 "XSLT-variable: Failed to compile the XPath expression '%s'.\n",
1863 #ifdef XSLT_REFACTORED
1864 if (inst
->children
!= NULL
) {
1865 xsltTransformError(NULL
, style
, inst
,
1866 "XSLT-variable: There must be no child nodes, since the "
1867 "attribute 'select' was specified.\n");
1871 for (cur
= inst
->children
; cur
!= NULL
; cur
= cur
->next
) {
1872 if (cur
->type
!= XML_COMMENT_NODE
&&
1873 (cur
->type
!= XML_TEXT_NODE
|| !xsltIsBlank(cur
->content
)))
1875 xsltTransformError(NULL
, style
, inst
,
1876 "XSLT-variable: There must be no child nodes, since the "
1877 "attribute 'select' was specified.\n");
1887 * @style: an XSLT compiled stylesheet
1888 * @inst: the xslt param node
1890 * Process the xslt param node on the source node
1893 xsltParamComp(xsltStylesheetPtr style
, xmlNodePtr inst
) {
1894 #ifdef XSLT_REFACTORED
1895 xsltStyleItemParamPtr comp
;
1897 xsltStylePreCompPtr comp
;
1900 if ((style
== NULL
) || (inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
))
1903 #ifdef XSLT_REFACTORED
1904 comp
= (xsltStyleItemParamPtr
)
1905 xsltNewStylePreComp(style
, XSLT_FUNC_PARAM
);
1907 comp
= xsltNewStylePreComp(style
, XSLT_FUNC_PARAM
);
1918 xsltGetQNameProperty(style
, inst
, BAD_CAST
"name",
1919 1, &(comp
->has_name
), &(comp
->ns
), &(comp
->name
));
1923 * Attribute "select".
1925 comp
->select
= xsltGetCNsProp(style
, inst
, (const xmlChar
*)"select",
1927 if (comp
->select
!= NULL
) {
1928 comp
->comp
= xsltXPathCompile(style
, comp
->select
);
1929 if (comp
->comp
== NULL
) {
1930 xsltTransformError(NULL
, style
, inst
,
1931 "XSLT-param: could not compile select expression '%s'.\n",
1935 if (inst
->children
!= NULL
) {
1936 xsltTransformError(NULL
, style
, inst
,
1937 "XSLT-param: The content should be empty since the "
1938 "attribute 'select' is present.\n");
1944 /************************************************************************
1946 * Generic interface *
1948 ************************************************************************/
1951 * xsltFreeStylePreComps:
1952 * @style: an XSLT transformation context
1954 * Free up the memory allocated by all precomputed blocks
1957 xsltFreeStylePreComps(xsltStylesheetPtr style
) {
1958 xsltElemPreCompPtr cur
, next
;
1963 cur
= style
->preComps
;
1964 while (cur
!= NULL
) {
1966 if (cur
->type
== XSLT_FUNC_EXTENSION
)
1969 xsltFreeStylePreComp((xsltStylePreCompPtr
) cur
);
1974 #ifdef XSLT_REFACTORED
1977 * xsltStylePreCompute:
1978 * @style: the XSLT stylesheet
1979 * @node: the element in the XSLT namespace
1981 * Precompute an XSLT element.
1982 * This expects the type of the element to be already
1983 * set in style->compCtxt->inode->type;
1986 xsltStylePreCompute(xsltStylesheetPtr style
, xmlNodePtr node
) {
1988 * The xsltXSLTElemMarker marker was set beforehand by
1989 * the parsing mechanism for all elements in the XSLT namespace.
1991 if (style
== NULL
) {
1992 if ((node
!= NULL
) && (node
->type
== XML_ELEMENT_NODE
))
1998 if (! IS_XSLT_ELEM_FAST(node
))
2002 if (XSLT_CCTXT(style
)->inode
->type
!= 0) {
2003 switch (XSLT_CCTXT(style
)->inode
->type
) {
2004 case XSLT_FUNC_APPLYTEMPLATES
:
2005 xsltApplyTemplatesComp(style
, node
);
2007 case XSLT_FUNC_WITHPARAM
:
2008 xsltWithParamComp(style
, node
);
2010 case XSLT_FUNC_VALUEOF
:
2011 xsltValueOfComp(style
, node
);
2013 case XSLT_FUNC_COPY
:
2014 xsltCopyComp(style
, node
);
2016 case XSLT_FUNC_COPYOF
:
2017 xsltCopyOfComp(style
, node
);
2020 xsltIfComp(style
, node
);
2022 case XSLT_FUNC_CHOOSE
:
2023 xsltChooseComp(style
, node
);
2025 case XSLT_FUNC_WHEN
:
2026 xsltWhenComp(style
, node
);
2028 case XSLT_FUNC_OTHERWISE
:
2031 case XSLT_FUNC_FOREACH
:
2032 xsltForEachComp(style
, node
);
2034 case XSLT_FUNC_APPLYIMPORTS
:
2035 xsltApplyImportsComp(style
, node
);
2037 case XSLT_FUNC_ATTRIBUTE
:
2038 xsltAttributeComp(style
, node
);
2040 case XSLT_FUNC_ELEMENT
:
2041 xsltElementComp(style
, node
);
2043 case XSLT_FUNC_SORT
:
2044 xsltSortComp(style
, node
);
2046 case XSLT_FUNC_COMMENT
:
2047 xsltCommentComp(style
, node
);
2049 case XSLT_FUNC_NUMBER
:
2050 xsltNumberComp(style
, node
);
2053 xsltProcessingInstructionComp(style
, node
);
2055 case XSLT_FUNC_CALLTEMPLATE
:
2056 xsltCallTemplateComp(style
, node
);
2058 case XSLT_FUNC_PARAM
:
2059 xsltParamComp(style
, node
);
2061 case XSLT_FUNC_VARIABLE
:
2062 xsltVariableComp(style
, node
);
2064 case XSLT_FUNC_FALLBACK
:
2067 case XSLT_FUNC_DOCUMENT
:
2069 node
->psvi
= (void *) xsltDocumentComp(style
, node
,
2070 (xsltTransformFunction
) xsltDocumentElem
);
2072 case XSLT_FUNC_MESSAGE
:
2077 * NOTE that xsl:text, xsl:template, xsl:stylesheet,
2078 * xsl:transform, xsl:import, xsl:include are not expected
2079 * to be handed over to this function.
2081 xsltTransformError(NULL
, style
, node
,
2082 "Internal error: (xsltStylePreCompute) cannot handle "
2083 "the XSLT element '%s'.\n", node
->name
);
2089 * Fallback to string comparison.
2091 if (IS_XSLT_NAME(node
, "apply-templates")) {
2092 xsltApplyTemplatesComp(style
, node
);
2093 } else if (IS_XSLT_NAME(node
, "with-param")) {
2094 xsltWithParamComp(style
, node
);
2095 } else if (IS_XSLT_NAME(node
, "value-of")) {
2096 xsltValueOfComp(style
, node
);
2097 } else if (IS_XSLT_NAME(node
, "copy")) {
2098 xsltCopyComp(style
, node
);
2099 } else if (IS_XSLT_NAME(node
, "copy-of")) {
2100 xsltCopyOfComp(style
, node
);
2101 } else if (IS_XSLT_NAME(node
, "if")) {
2102 xsltIfComp(style
, node
);
2103 } else if (IS_XSLT_NAME(node
, "choose")) {
2104 xsltChooseComp(style
, node
);
2105 } else if (IS_XSLT_NAME(node
, "when")) {
2106 xsltWhenComp(style
, node
);
2107 } else if (IS_XSLT_NAME(node
, "otherwise")) {
2110 } else if (IS_XSLT_NAME(node
, "for-each")) {
2111 xsltForEachComp(style
, node
);
2112 } else if (IS_XSLT_NAME(node
, "apply-imports")) {
2113 xsltApplyImportsComp(style
, node
);
2114 } else if (IS_XSLT_NAME(node
, "attribute")) {
2115 xsltAttributeComp(style
, node
);
2116 } else if (IS_XSLT_NAME(node
, "element")) {
2117 xsltElementComp(style
, node
);
2118 } else if (IS_XSLT_NAME(node
, "sort")) {
2119 xsltSortComp(style
, node
);
2120 } else if (IS_XSLT_NAME(node
, "comment")) {
2121 xsltCommentComp(style
, node
);
2122 } else if (IS_XSLT_NAME(node
, "number")) {
2123 xsltNumberComp(style
, node
);
2124 } else if (IS_XSLT_NAME(node
, "processing-instruction")) {
2125 xsltProcessingInstructionComp(style
, node
);
2126 } else if (IS_XSLT_NAME(node
, "call-template")) {
2127 xsltCallTemplateComp(style
, node
);
2128 } else if (IS_XSLT_NAME(node
, "param")) {
2129 xsltParamComp(style
, node
);
2130 } else if (IS_XSLT_NAME(node
, "variable")) {
2131 xsltVariableComp(style
, node
);
2132 } else if (IS_XSLT_NAME(node
, "fallback")) {
2135 } else if (IS_XSLT_NAME(node
, "document")) {
2137 node
->psvi
= (void *) xsltDocumentComp(style
, node
,
2138 (xsltTransformFunction
) xsltDocumentElem
);
2139 } else if (IS_XSLT_NAME(node
, "output")) {
2142 } else if (IS_XSLT_NAME(node
, "preserve-space")) {
2145 } else if (IS_XSLT_NAME(node
, "strip-space")) {
2148 } else if (IS_XSLT_NAME(node
, "key")) {
2151 } else if (IS_XSLT_NAME(node
, "message")) {
2153 } else if (IS_XSLT_NAME(node
, "attribute-set")) {
2156 } else if (IS_XSLT_NAME(node
, "namespace-alias")) {
2159 } else if (IS_XSLT_NAME(node
, "decimal-format")) {
2162 } else if (IS_XSLT_NAME(node
, "include")) {
2166 * NOTE that xsl:text, xsl:template, xsl:stylesheet,
2167 * xsl:transform, xsl:import, xsl:include are not expected
2168 * to be handed over to this function.
2170 xsltTransformError(NULL
, style
, node
,
2171 "Internal error: (xsltStylePreCompute) cannot handle "
2172 "the XSLT element '%s'.\n", node
->name
);
2178 * Assign the current list of in-scope namespaces to the
2179 * item. This is needed for XPath expressions.
2181 if (node
->psvi
!= NULL
) {
2182 ((xsltStylePreCompPtr
) node
->psvi
)->inScopeNs
=
2183 XSLT_CCTXT(style
)->inode
->inScopeNs
;
2190 * xsltStylePreCompute:
2191 * @style: the XSLT stylesheet
2192 * @inst: the instruction in the stylesheet
2194 * Precompute an XSLT stylesheet element
2197 xsltStylePreCompute(xsltStylesheetPtr style
, xmlNodePtr inst
) {
2199 * URGENT TODO: Normally inst->psvi Should never be reserved here,
2200 * BUT: since if we include the same stylesheet from
2201 * multiple imports, then the stylesheet will be parsed
2202 * again. We simply must not try to compute the stylesheet again.
2203 * TODO: Get to the point where we don't need to query the
2204 * namespace- and local-name of the node, but can evaluate this
2205 * using cctxt->style->inode->category;
2207 if ((inst
== NULL
) || (inst
->type
!= XML_ELEMENT_NODE
) ||
2208 (inst
->psvi
!= NULL
))
2211 if (IS_XSLT_ELEM(inst
)) {
2212 xsltStylePreCompPtr cur
;
2214 if (IS_XSLT_NAME(inst
, "apply-templates")) {
2215 xsltCheckInstructionElement(style
, inst
);
2216 xsltApplyTemplatesComp(style
, inst
);
2217 } else if (IS_XSLT_NAME(inst
, "with-param")) {
2218 xsltCheckParentElement(style
, inst
, BAD_CAST
"apply-templates",
2219 BAD_CAST
"call-template");
2220 xsltWithParamComp(style
, inst
);
2221 } else if (IS_XSLT_NAME(inst
, "value-of")) {
2222 xsltCheckInstructionElement(style
, inst
);
2223 xsltValueOfComp(style
, inst
);
2224 } else if (IS_XSLT_NAME(inst
, "copy")) {
2225 xsltCheckInstructionElement(style
, inst
);
2226 xsltCopyComp(style
, inst
);
2227 } else if (IS_XSLT_NAME(inst
, "copy-of")) {
2228 xsltCheckInstructionElement(style
, inst
);
2229 xsltCopyOfComp(style
, inst
);
2230 } else if (IS_XSLT_NAME(inst
, "if")) {
2231 xsltCheckInstructionElement(style
, inst
);
2232 xsltIfComp(style
, inst
);
2233 } else if (IS_XSLT_NAME(inst
, "when")) {
2234 xsltCheckParentElement(style
, inst
, BAD_CAST
"choose", NULL
);
2235 xsltWhenComp(style
, inst
);
2236 } else if (IS_XSLT_NAME(inst
, "choose")) {
2237 xsltCheckInstructionElement(style
, inst
);
2238 xsltChooseComp(style
, inst
);
2239 } else if (IS_XSLT_NAME(inst
, "for-each")) {
2240 xsltCheckInstructionElement(style
, inst
);
2241 xsltForEachComp(style
, inst
);
2242 } else if (IS_XSLT_NAME(inst
, "apply-imports")) {
2243 xsltCheckInstructionElement(style
, inst
);
2244 xsltApplyImportsComp(style
, inst
);
2245 } else if (IS_XSLT_NAME(inst
, "attribute")) {
2246 xmlNodePtr parent
= inst
->parent
;
2248 if ((parent
== NULL
) || (parent
->ns
== NULL
) ||
2249 ((parent
->ns
!= inst
->ns
) &&
2250 (!xmlStrEqual(parent
->ns
->href
, inst
->ns
->href
))) ||
2251 (!xmlStrEqual(parent
->name
, BAD_CAST
"attribute-set"))) {
2252 xsltCheckInstructionElement(style
, inst
);
2254 xsltAttributeComp(style
, inst
);
2255 } else if (IS_XSLT_NAME(inst
, "element")) {
2256 xsltCheckInstructionElement(style
, inst
);
2257 xsltElementComp(style
, inst
);
2258 } else if (IS_XSLT_NAME(inst
, "text")) {
2259 xsltCheckInstructionElement(style
, inst
);
2260 xsltTextComp(style
, inst
);
2261 } else if (IS_XSLT_NAME(inst
, "sort")) {
2262 xsltCheckParentElement(style
, inst
, BAD_CAST
"apply-templates",
2263 BAD_CAST
"for-each");
2264 xsltSortComp(style
, inst
);
2265 } else if (IS_XSLT_NAME(inst
, "comment")) {
2266 xsltCheckInstructionElement(style
, inst
);
2267 xsltCommentComp(style
, inst
);
2268 } else if (IS_XSLT_NAME(inst
, "number")) {
2269 xsltCheckInstructionElement(style
, inst
);
2270 xsltNumberComp(style
, inst
);
2271 } else if (IS_XSLT_NAME(inst
, "processing-instruction")) {
2272 xsltCheckInstructionElement(style
, inst
);
2273 xsltProcessingInstructionComp(style
, inst
);
2274 } else if (IS_XSLT_NAME(inst
, "call-template")) {
2275 xsltCheckInstructionElement(style
, inst
);
2276 xsltCallTemplateComp(style
, inst
);
2277 } else if (IS_XSLT_NAME(inst
, "param")) {
2278 if (xsltCheckTopLevelElement(style
, inst
, 0) == 0)
2279 xsltCheckInstructionElement(style
, inst
);
2280 xsltParamComp(style
, inst
);
2281 } else if (IS_XSLT_NAME(inst
, "variable")) {
2282 if (xsltCheckTopLevelElement(style
, inst
, 0) == 0)
2283 xsltCheckInstructionElement(style
, inst
);
2284 xsltVariableComp(style
, inst
);
2285 } else if (IS_XSLT_NAME(inst
, "otherwise")) {
2286 xsltCheckParentElement(style
, inst
, BAD_CAST
"choose", NULL
);
2287 xsltCheckInstructionElement(style
, inst
);
2289 } else if (IS_XSLT_NAME(inst
, "template")) {
2290 xsltCheckTopLevelElement(style
, inst
, 1);
2292 } else if (IS_XSLT_NAME(inst
, "output")) {
2293 xsltCheckTopLevelElement(style
, inst
, 1);
2295 } else if (IS_XSLT_NAME(inst
, "preserve-space")) {
2296 xsltCheckTopLevelElement(style
, inst
, 1);
2298 } else if (IS_XSLT_NAME(inst
, "strip-space")) {
2299 xsltCheckTopLevelElement(style
, inst
, 1);
2301 } else if ((IS_XSLT_NAME(inst
, "stylesheet")) ||
2302 (IS_XSLT_NAME(inst
, "transform"))) {
2303 xmlNodePtr parent
= inst
->parent
;
2305 if ((parent
== NULL
) || (parent
->type
!= XML_DOCUMENT_NODE
)) {
2306 xsltTransformError(NULL
, style
, inst
,
2307 "element %s only allowed only as root element\n",
2312 } else if (IS_XSLT_NAME(inst
, "key")) {
2313 xsltCheckTopLevelElement(style
, inst
, 1);
2315 } else if (IS_XSLT_NAME(inst
, "message")) {
2316 xsltCheckInstructionElement(style
, inst
);
2318 } else if (IS_XSLT_NAME(inst
, "attribute-set")) {
2319 xsltCheckTopLevelElement(style
, inst
, 1);
2321 } else if (IS_XSLT_NAME(inst
, "namespace-alias")) {
2322 xsltCheckTopLevelElement(style
, inst
, 1);
2324 } else if (IS_XSLT_NAME(inst
, "include")) {
2325 xsltCheckTopLevelElement(style
, inst
, 1);
2327 } else if (IS_XSLT_NAME(inst
, "import")) {
2328 xsltCheckTopLevelElement(style
, inst
, 1);
2330 } else if (IS_XSLT_NAME(inst
, "decimal-format")) {
2331 xsltCheckTopLevelElement(style
, inst
, 1);
2333 } else if (IS_XSLT_NAME(inst
, "fallback")) {
2334 xsltCheckInstructionElement(style
, inst
);
2336 } else if (IS_XSLT_NAME(inst
, "document")) {
2337 xsltCheckInstructionElement(style
, inst
);
2338 inst
->psvi
= (void *) xsltDocumentComp(style
, inst
,
2339 (xsltTransformFunction
) xsltDocumentElem
);
2341 xsltTransformError(NULL
, style
, inst
,
2342 "xsltStylePreCompute: unknown xsl:%s\n", inst
->name
);
2343 if (style
!= NULL
) style
->warnings
++;
2346 cur
= (xsltStylePreCompPtr
) inst
->psvi
;
2348 * A ns-list is build for every XSLT item in the
2349 * node-tree. This is needed for XPath expressions.
2354 cur
->nsList
= xmlGetNsList(inst
->doc
, inst
);
2355 if (cur
->nsList
!= NULL
) {
2356 while (cur
->nsList
[i
] != NULL
)
2363 (void *) xsltPreComputeExtModuleElement(style
, inst
);
2366 * Unknown element, maybe registered at the context
2367 * level. Mark it for later recognition.
2369 if (inst
->psvi
== NULL
)
2370 inst
->psvi
= (void *) xsltExtMarker
;
2373 #endif /* XSLT_REFACTORED */