ReactOS 0.4.15-dev-7842-g558ab78
transform.c File Reference
#include "precomp.h"
#include <libxml/debugXML.h>
Include dependency graph for transform.c:

Go to the source code of this file.

Classes

struct  xsltHTMLVersion
 

Macros

#define XSLT_GENERATE_HTML_DOCTYPE
 
#define FALSE   (0 == 1)
 
#define TRUE   (!FALSE)
 
#define IS_BLANK_NODE(n)    (((n)->type == XML_TEXT_NODE) && (xsltIsBlank((n)->content)))
 

Typedefs

typedef struct xsltHTMLVersion xsltHTMLVersion
 

Functions

static int xsltGetHTMLIDs (const xmlChar *version, const xmlChar **publicID, const xmlChar **systemID)
 
static xmlNsPtr xsltCopyNamespaceListInternal (xmlNodePtr node, xmlNsPtr cur)
 
static xmlNodePtr xsltCopyTree (xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr node, xmlNodePtr insert, int isLRE, int topElemVisited)
 
static void xsltApplySequenceConstructor (xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr list, xsltTemplatePtr templ)
 
static void xsltApplyXSLTTemplate (xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr list, xsltTemplatePtr templ, xsltStackElemPtr withParams)
 
static int templPush (xsltTransformContextPtr ctxt, xsltTemplatePtr value)
 
static xsltTemplatePtr templPop (xsltTransformContextPtr ctxt)
 
void xsltLocalVariablePop (xsltTransformContextPtr ctxt, int limitNr, int level)
 
static void xsltTemplateParamsCleanup (xsltTransformContextPtr ctxt)
 
static xmlXPathObjectPtr xsltPreCompEval (xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStylePreCompPtr comp)
 
static int xsltPreCompEvalToBoolean (xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStylePreCompPtr comp)
 
void xsltSetXIncludeDefault (int xinclude)
 
int xsltGetXIncludeDefault (void)
 
void xsltDebugSetDefaultTrace (xsltDebugTraceCodes val)
 
xsltDebugTraceCodes xsltDebugGetDefaultTrace ()
 
static xsltTransformCachePtr xsltTransformCacheCreate (void)
 
static void xsltTransformCacheFree (xsltTransformCachePtr cache)
 
xsltTransformContextPtr xsltNewTransformContext (xsltStylesheetPtr style, xmlDocPtr doc)
 
void xsltFreeTransformContext (xsltTransformContextPtr ctxt)
 
static xmlNodePtr xsltAddChild (xmlNodePtr parent, xmlNodePtr cur)
 
static xmlNodePtr xsltAddTextString (xsltTransformContextPtr ctxt, xmlNodePtr target, const xmlChar *string, int len)
 
xmlNodePtr xsltCopyTextString (xsltTransformContextPtr ctxt, xmlNodePtr target, const xmlChar *string, int noescape)
 
static xmlNodePtr xsltCopyText (xsltTransformContextPtr ctxt, xmlNodePtr target, xmlNodePtr cur, int interned)
 
static xmlAttrPtr xsltShallowCopyAttr (xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr target, xmlAttrPtr attr)
 
static int xsltCopyAttrListNoOverwrite (xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr target, xmlAttrPtr attr)
 
static xmlNodePtr xsltShallowCopyElem (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr insert, int isLRE)
 
static xmlNodePtr xsltCopyTreeList (xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr list, xmlNodePtr insert, int isLRE, int topElemVisited)
 
static xmlNsPtr xsltShallowCopyNsNode (xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr insert, xmlNsPtr ns)
 
static int xsltApplyFallbacks (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst)
 
static void xsltDefaultProcessOneNode (xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStackElemPtr params)
 
void xsltProcessOneNode (xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xsltStackElemPtr withParams)
 
int xsltLocalVariablePush (xsltTransformContextPtr ctxt, xsltStackElemPtr variable, int level)
 
static void xsltReleaseLocalRVTs (xsltTransformContextPtr ctxt, xmlDocPtr base)
 
void xsltApplyOneTemplate (xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr list, xsltTemplatePtr templ ATTRIBUTE_UNUSED, xsltStackElemPtr params)
 
void xsltDocumentElem (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltSort (xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr inst, xsltElemPreCompPtr comp)
 
void xsltCopy (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltText (xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
 
void xsltElement (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltComment (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
 
void xsltProcessingInstruction (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltCopyOf (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltValueOf (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltNumber (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltApplyImports (xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
 
void xsltCallTemplate (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltApplyTemplates (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltChoose (xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
 
void xsltIf (xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltForEach (xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
 
void xsltApplyStripSpaces (xsltTransformContextPtr ctxt, xmlNodePtr node)
 
static int xsltCountKeys (xsltTransformContextPtr ctxt)
 
static xmlDocPtr xsltApplyStylesheetInternal (xsltStylesheetPtr style, xmlDocPtr doc, const char **params, const char *output, FILE *profile, xsltTransformContextPtr userCtxt)
 
xmlDocPtr xsltApplyStylesheet (xsltStylesheetPtr style, xmlDocPtr doc, const char **params)
 
xmlDocPtr xsltProfileStylesheet (xsltStylesheetPtr style, xmlDocPtr doc, const char **params, FILE *output)
 
xmlDocPtr xsltApplyStylesheetUser (xsltStylesheetPtr style, xmlDocPtr doc, const char **params, const char *output, FILE *profile, xsltTransformContextPtr userCtxt)
 
int xsltRunStylesheetUser (xsltStylesheetPtr style, xmlDocPtr doc, const char **params, const char *output, xmlSAXHandlerPtr SAX, xmlOutputBufferPtr IObuf, FILE *profile, xsltTransformContextPtr userCtxt)
 
int xsltRunStylesheet (xsltStylesheetPtr style, xmlDocPtr doc, const char **params, const char *output, xmlSAXHandlerPtr SAX, xmlOutputBufferPtr IObuf)
 
static void xsltMessageWrapper (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
 
void xsltRegisterAllElement (xsltTransformContextPtr ctxt)
 

Variables

int xsltMaxDepth = 3000
 
int xsltMaxVars = 15000
 
static int xsltDoXIncludeDefault = 0
 
static unsigned long xsltDefaultTrace = (unsigned long) XSLT_TRACE_ALL
 
static xsltHTMLVersion xsltHTMLVersions []
 

Macro Definition Documentation

◆ FALSE

#define FALSE   (0 == 1)

Definition at line 43 of file transform.c.

◆ IS_BLANK_NODE

#define IS_BLANK_NODE (   n)     (((n)->type == XML_TEXT_NODE) && (xsltIsBlank((n)->content)))

Definition at line 47 of file transform.c.

◆ TRUE

#define TRUE   (!FALSE)

Definition at line 44 of file transform.c.

◆ XSLT_GENERATE_HTML_DOCTYPE

#define XSLT_GENERATE_HTML_DOCTYPE

Definition at line 29 of file transform.c.

Typedef Documentation

◆ xsltHTMLVersion

Function Documentation

◆ templPop()

static xsltTemplatePtr templPop ( xsltTransformContextPtr  ctxt)
static

templPop: @ctxt: the transformation context

Pop a template value from the stack

Returns the stored template value

Definition at line 121 of file transform.c.

122{
124
125 if (ctxt->templNr <= 0)
126 return (0);
127 ctxt->templNr--;
128 if (ctxt->templNr > 0)
129 ctxt->templ = ctxt->templTab[ctxt->templNr - 1];
130 else
131 ctxt->templ = (xsltTemplatePtr) 0;
132 ret = ctxt->templTab[ctxt->templNr];
133 ctxt->templTab[ctxt->templNr] = 0;
134 return (ret);
135}
xsltTemplatePtr * templTab
xsltTemplatePtr templ
int ret
xsltTemplate * xsltTemplatePtr

Referenced by xsltApplyXSLTTemplate().

◆ templPush()

static int templPush ( xsltTransformContextPtr  ctxt,
xsltTemplatePtr  value 
)
static

templPush: @ctxt: the transformation context @value: the template to push on the stack

Push a template on the stack

Returns the new index in the stack or 0 in case of error

Definition at line 85 of file transform.c.

86{
87 if (ctxt->templMax == 0) {
88 ctxt->templMax = 4;
89 ctxt->templTab =
91 sizeof(ctxt->templTab[0]));
92 if (ctxt->templTab == NULL) {
93 xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
94 return (0);
95 }
96 }
97 else if (ctxt->templNr >= ctxt->templMax) {
98 ctxt->templMax *= 2;
99 ctxt->templTab =
101 ctxt->templMax *
102 sizeof(ctxt->templTab[0]));
103 if (ctxt->templTab == NULL) {
104 xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
105 return (0);
106 }
107 }
108 ctxt->templTab[ctxt->templNr] = value;
109 ctxt->templ = value;
110 return (ctxt->templNr++);
111}
#define NULL
Definition: types.h:112
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR void * xmlGenericErrorContext
Definition: globals.h:353
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:250
XMLPUBVAR xmlGenericErrorFunc xmlGenericError
Definition: globals.h:337
Definition: pdh_main.c:94

Referenced by xsltApplyXSLTTemplate().

◆ xsltAddChild()

static xmlNodePtr xsltAddChild ( xmlNodePtr  parent,
xmlNodePtr  cur 
)
static

xsltAddChild: @parent: the parent node @cur: the child node

Wrapper version of xmlAddChild with a more consistent behaviour on error. One expect the use to be child = xsltAddChild(parent, child); and the routine will take care of not leaking on errors or node merge

Returns the child is successfully attached or NULL if merged or freed

Definition at line 751 of file transform.c.

751 {
753
754 if (cur == NULL)
755 return(NULL);
756 if (parent == NULL) {
758 return(NULL);
759 }
761
762 return(ret);
763}
r parent
Definition: btrfs.c:3010
FxCollectionEntry * cur
XMLPUBFUN xmlNodePtr XMLCALL xmlAddChild(xmlNodePtr parent, xmlNodePtr cur)
XMLPUBFUN void XMLCALL xmlFreeNode(xmlNodePtr cur)
Definition: tree.h:489

Referenced by xsltApplySequenceConstructor(), xsltComment(), xsltCopy(), xsltCopyText(), xsltCopyTextString(), xsltCopyTree(), xsltElement(), xsltProcessingInstruction(), xsltShallowCopyElem(), and xsltText().

◆ xsltAddTextString()

static xmlNodePtr xsltAddTextString ( xsltTransformContextPtr  ctxt,
xmlNodePtr  target,
const xmlChar string,
int  len 
)
static

xsltAddTextString: @ctxt: a XSLT process context @target: the text node where the text will be attached @string: the text string @len: the string length in byte

Extend the current text node with the new string, it handles coalescing

Returns: the text node

Definition at line 777 of file transform.c.

778 {
779 /*
780 * optimization
781 */
782 if ((len <= 0) || (string == NULL) || (target == NULL))
783 return(target);
784
785 if (ctxt->lasttext == target->content) {
786 int minSize;
787
788 /* Check for integer overflow accounting for NUL terminator. */
789 if (len >= INT_MAX - ctxt->lasttuse) {
791 "xsltCopyText: text allocation failed\n");
792 return(NULL);
793 }
794 minSize = ctxt->lasttuse + len + 1;
795
796 if (ctxt->lasttsize < minSize) {
797 xmlChar *newbuf;
798 int size;
799 int extra;
800
801 /* Double buffer size but increase by at least 100 bytes. */
802 extra = minSize < 100 ? 100 : minSize;
803
804 /* Check for integer overflow. */
805 if (extra > INT_MAX - ctxt->lasttsize) {
806 size = INT_MAX;
807 }
808 else {
809 size = ctxt->lasttsize + extra;
810 }
811
812 newbuf = (xmlChar *) xmlRealloc(target->content,size);
813 if (newbuf == NULL) {
815 "xsltCopyText: text allocation failed\n");
816 return(NULL);
817 }
818 ctxt->lasttsize = size;
819 ctxt->lasttext = newbuf;
820 target->content = newbuf;
821 }
822 memcpy(&(target->content[ctxt->lasttuse]), string, len);
823 ctxt->lasttuse += len;
824 target->content[ctxt->lasttuse] = 0;
825 } else {
826 xmlNodeAddContent(target, string);
827 ctxt->lasttext = target->content;
828 len = xmlStrlen(target->content);
829 ctxt->lasttsize = len;
830 ctxt->lasttuse = len;
831 }
832 return(target);
833}
GLsizeiptr size
Definition: glext.h:5919
GLenum GLsizei len
Definition: glext.h:6722
GLenum target
Definition: glext.h:7315
@ extra
Definition: id3.c:95
#define INT_MAX
Definition: limits.h:40
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
XMLPUBFUN void XMLCALL xmlNodeAddContent(xmlNodePtr cur, const xmlChar *content)
const xmlChar * lasttext
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:426
unsigned char xmlChar
Definition: xmlstring.h:28
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678

Referenced by xsltCopyText(), and xsltCopyTextString().

◆ xsltApplyFallbacks()

static int xsltApplyFallbacks ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst 
)
static

xsltApplyFallbacks: @ctxt: a XSLT process context @node: the node in the source tree. @inst: the node generating the error

Process possible xsl:fallback nodes present under @inst

Returns the number of xsl:fallback element found and processed

Definition at line 1803 of file transform.c.

1804 {
1805
1807 int ret = 0;
1808
1809 if ((ctxt == NULL) || (node == NULL) || (inst == NULL) ||
1810 (inst->children == NULL))
1811 return(0);
1812
1813 child = inst->children;
1814 while (child != NULL) {
1815 if ((IS_XSLT_ELEM(child)) &&
1816 (xmlStrEqual(child->name, BAD_CAST "fallback"))) {
1817#ifdef WITH_XSLT_DEBUG_PARSING
1819 "applying xsl:fallback\n");
1820#endif
1821 ret++;
1822 xsltApplySequenceConstructor(ctxt, node, child->children,
1823 NULL);
1824 }
1825 child = child->next;
1826 }
1827 return(ret);
1828}
static void xsltApplySequenceConstructor(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr list, xsltTemplatePtr templ)
Definition: transform.c:2278
static HWND child
Definition: cursoricon.c:298
struct _xmlNode * children
Definition: tree.h:493
Definition: dlist.c:348
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
void * xsltGenericDebugContext
Definition: xsltutils.c:549
#define IS_XSLT_ELEM(n)
Definition: xsltutils.h:51

Referenced by xsltApplySequenceConstructor().

◆ xsltApplyImports()

void xsltApplyImports ( xsltTransformContextPtr  ctxt,
xmlNodePtr  contextNode,
xmlNodePtr  inst,
xsltElemPreCompPtr comp  ATTRIBUTE_UNUSED 
)

xsltApplyImports: @ctxt: an XSLT transformation context @contextNode: the current node in the source tree. @inst: the element node of the XSLT 'apply-imports' instruction @comp: the compiled instruction

Process the XSLT apply-imports element.

Definition at line 4610 of file transform.c.

4613{
4614 xsltTemplatePtr templ;
4615
4616 if ((ctxt == NULL) || (inst == NULL))
4617 return;
4618
4619 if (comp == NULL) {
4620 xsltTransformError(ctxt, NULL, inst,
4621 "Internal error in xsltApplyImports(): "
4622 "The XSLT 'apply-imports' instruction was not compiled.\n");
4623 return;
4624 }
4625 /*
4626 * NOTE that ctxt->currentTemplateRule and ctxt->templ is not the
4627 * same; the former is the "Current Template Rule" as defined by the
4628 * XSLT spec, the latter is simply the template struct being
4629 * currently processed.
4630 */
4631 if (ctxt->currentTemplateRule == NULL) {
4632 /*
4633 * SPEC XSLT 2.0:
4634 * "[ERR XTDE0560] It is a non-recoverable dynamic error if
4635 * xsl:apply-imports or xsl:next-match is evaluated when the
4636 * current template rule is null."
4637 */
4638 xsltTransformError(ctxt, NULL, inst,
4639 "It is an error to call 'apply-imports' "
4640 "when there's no current template rule.\n");
4641 return;
4642 }
4643 /*
4644 * TODO: Check if this is correct.
4645 */
4646 templ = xsltGetTemplate(ctxt, contextNode,
4647 ctxt->currentTemplateRule->style);
4648
4649 if (templ != NULL) {
4650 xsltTemplatePtr oldCurTemplRule = ctxt->currentTemplateRule;
4651 /*
4652 * Set the current template rule.
4653 */
4654 ctxt->currentTemplateRule = templ;
4655 /*
4656 * URGENT TODO: Need xsl:with-param be handled somehow here?
4657 */
4658 xsltApplyXSLTTemplate(ctxt, contextNode, templ->content,
4659 templ, NULL);
4660
4661 ctxt->currentTemplateRule = oldCurTemplRule;
4662 }
4663 else {
4664 /* Use built-in templates. */
4665 xsltDefaultProcessOneNode(ctxt, contextNode, NULL);
4666 }
4667}
xsltTemplatePtr xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStylesheetPtr style)
Definition: pattern.c:2259
static void xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr list, xsltTemplatePtr templ, xsltStackElemPtr withParams)
Definition: transform.c:3026
static void xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStackElemPtr params)
Definition: transform.c:1859
xmlNodePtr content
struct _xsltStylesheet * style
xsltTemplatePtr currentTemplateRule

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltApplyOneTemplate()

void xsltApplyOneTemplate ( xsltTransformContextPtr  ctxt,
xmlNodePtr  contextNode,
xmlNodePtr  list,
xsltTemplatePtr templ  ATTRIBUTE_UNUSED,
xsltStackElemPtr  params 
)

xsltApplyOneTemplate: @ctxt: a XSLT process context @contextNode: the node in the source tree. @list: the nodes of a sequence constructor @templ: not used @params: a set of parameters (xsl:param) or NULL

Processes a sequence constructor on the current node in the source tree.

@params are the already computed variable stack items; this function pushes them on the variable stack, and pops them before exiting; it's left to the caller to free or reuse @params afterwards. The initial states of the variable stack will always be restored before this function exits. NOTE that this does not initiate a new distinct variable scope; i.e. variables already on the stack are visible to the process. The caller's side needs to start a new variable scope if needed (e.g. in exsl:function).

@templ is obsolete and not used anymore (e.g. <exslt:function> does not provide a @templ); a non-NULL @templ might raise an error in the future.

BIG NOTE: This function is not intended to process the content of an xsl:template; it does not expect xsl:param instructions in @list and will report errors if found.

Called by:

Definition at line 3273 of file transform.c.

3278{
3279 if ((ctxt == NULL) || (list == NULL))
3280 return;
3282
3283 if (params) {
3284 /*
3285 * This code should be obsolete - was previously used
3286 * by libexslt/functions.c, but due to bug 381319 the
3287 * logic there was changed.
3288 */
3289 int oldVarsNr = ctxt->varsNr;
3290
3291 /*
3292 * Push the given xsl:param(s) onto the variable stack.
3293 */
3294 while (params != NULL) {
3295 xsltLocalVariablePush(ctxt, params, -1);
3296 params = params->next;
3297 }
3298 xsltApplySequenceConstructor(ctxt, contextNode, list, templ);
3299 /*
3300 * Pop the given xsl:param(s) from the stack but don't free them.
3301 */
3302 xsltLocalVariablePop(ctxt, oldVarsNr, -2);
3303 } else
3304 xsltApplySequenceConstructor(ctxt, contextNode, list, templ);
3305}
Definition: list.h:37
void xsltLocalVariablePop(xsltTransformContextPtr ctxt, int limitNr, int level)
Definition: transform.c:150
int xsltLocalVariablePush(xsltTransformContextPtr ctxt, xsltStackElemPtr variable, int level)
Definition: transform.c:2188
GLenum const GLfloat * params
Definition: glext.h:5645
#define CHECK_STOPPED

Referenced by xsltEvalGlobalVariable(), xsltEvalTemplateString(), and xsltEvalVariable().

◆ xsltApplySequenceConstructor()

static void xsltApplySequenceConstructor ( xsltTransformContextPtr  ctxt,
xmlNodePtr  contextNode,
xmlNodePtr  list,
xsltTemplatePtr  templ 
)
static

xsltApplySequenceConstructor: @ctxt: a XSLT process context @contextNode: the "current node" in the source tree @list: the nodes of a sequence constructor; (plus leading xsl:param elements) @templ: the compiled xsl:template (optional)

Processes a sequence constructor.

NOTE: ctxt->currentTemplateRule was introduced to reflect the semantics of "current template rule". I.e. the field ctxt->templ is not intended to reflect this, thus always pushed onto the template stack.

Definition at line 2278 of file transform.c.

2281{
2282 xmlNodePtr oldInsert, oldInst, oldCurInst, oldContextNode;
2284 int level = 0, oldVarsNr;
2285 xmlDocPtr oldLocalFragmentTop;
2286
2287#ifdef XSLT_REFACTORED
2289#endif
2290
2291#ifdef WITH_DEBUGGER
2292 int addCallResult = 0;
2293 xmlNodePtr debuggedNode = NULL;
2294#endif
2295
2296 if (ctxt == NULL)
2297 return;
2298
2299#ifdef WITH_DEBUGGER
2300 if (ctxt->debugStatus != XSLT_DEBUG_NONE) {
2301 debuggedNode =
2302 xsltDebuggerStartSequenceConstructor(ctxt, contextNode,
2303 list, templ, &addCallResult);
2304 if (debuggedNode == NULL)
2305 return;
2306 }
2307#endif
2308
2309 if (list == NULL)
2310 return;
2312
2313 /*
2314 * Check for infinite recursion: stop if the maximum of nested templates
2315 * is excceeded. Adjust xsltMaxDepth if you need more.
2316 */
2317 if (ctxt->depth >= ctxt->maxTemplateDepth) {
2319 "xsltApplySequenceConstructor: A potential infinite template "
2320 "recursion was detected.\n"
2321 "You can adjust xsltMaxDepth (--maxdepth) in order to "
2322 "raise the maximum number of nested template calls and "
2323 "variables/params (currently set to %d).\n",
2324 ctxt->maxTemplateDepth);
2325 xsltDebug(ctxt, contextNode, list, NULL);
2326 ctxt->state = XSLT_STATE_STOPPED;
2327 return;
2328 }
2329 ctxt->depth++;
2330
2331 oldLocalFragmentTop = ctxt->localRVT;
2332 oldInsert = insert = ctxt->insert;
2333 oldInst = oldCurInst = ctxt->inst;
2334 oldContextNode = ctxt->node;
2335 /*
2336 * Save current number of variables on the stack; new vars are popped when
2337 * exiting.
2338 */
2339 oldVarsNr = ctxt->varsNr;
2340 /*
2341 * Process the sequence constructor.
2342 */
2343 cur = list;
2344 while (cur != NULL) {
2345 if (ctxt->opLimit != 0) {
2346 if (ctxt->opCount >= ctxt->opLimit) {
2348 "xsltApplySequenceConstructor: "
2349 "Operation limit exceeded\n");
2350 ctxt->state = XSLT_STATE_STOPPED;
2351 goto error;
2352 }
2353 ctxt->opCount += 1;
2354 }
2355
2356 ctxt->inst = cur;
2357
2358#ifdef WITH_DEBUGGER
2359 switch (ctxt->debugStatus) {
2361 case XSLT_DEBUG_QUIT:
2362 break;
2363
2364 }
2365#endif
2366 /*
2367 * Test; we must have a valid insertion point.
2368 */
2369 if (insert == NULL) {
2370
2371#ifdef WITH_XSLT_DEBUG_PROCESS
2373 "xsltApplySequenceConstructor: insert == NULL !\n"));
2374#endif
2375 goto error;
2376 }
2377
2378#ifdef WITH_DEBUGGER
2379 if ((ctxt->debugStatus != XSLT_DEBUG_NONE) && (debuggedNode != cur))
2380 xslHandleDebugger(cur, contextNode, templ, ctxt);
2381#endif
2382
2383#ifdef XSLT_REFACTORED
2384 if (cur->type == XML_ELEMENT_NODE) {
2385 info = (xsltStylePreCompPtr) cur->psvi;
2386 /*
2387 * We expect a compiled representation on:
2388 * 1) XSLT instructions of this XSLT version (1.0)
2389 * (with a few exceptions)
2390 * 2) Literal result elements
2391 * 3) Extension instructions
2392 * 4) XSLT instructions of future XSLT versions
2393 * (forwards-compatible mode).
2394 */
2395 if (info == NULL) {
2396 /*
2397 * Handle the rare cases where we don't expect a compiled
2398 * representation on an XSLT element.
2399 */
2400 if (IS_XSLT_ELEM_FAST(cur) && IS_XSLT_NAME(cur, "message")) {
2401 xsltMessage(ctxt, contextNode, cur);
2402 goto skip_children;
2403 }
2404 /*
2405 * Something really went wrong:
2406 */
2408 "Internal error in xsltApplySequenceConstructor(): "
2409 "The element '%s' in the stylesheet has no compiled "
2410 "representation.\n",
2411 cur->name);
2412 goto skip_children;
2413 }
2414
2415 if (info->type == XSLT_FUNC_LITERAL_RESULT_ELEMENT) {
2416 xsltStyleItemLRElementInfoPtr lrInfo =
2417 (xsltStyleItemLRElementInfoPtr) info;
2418 /*
2419 * Literal result elements
2420 * --------------------------------------------------------
2421 */
2422#ifdef WITH_XSLT_DEBUG_PROCESS
2425 "xsltApplySequenceConstructor: copy literal result "
2426 "element '%s'\n", cur->name));
2427#endif
2428 /*
2429 * Copy the raw element-node.
2430 * OLD: if ((copy = xsltShallowCopyElem(ctxt, cur, insert))
2431 * == NULL)
2432 * goto error;
2433 */
2434 copy = xmlDocCopyNode(cur, insert->doc, 0);
2435 if (copy == NULL) {
2437 "Internal error in xsltApplySequenceConstructor(): "
2438 "Failed to copy literal result element '%s'.\n",
2439 cur->name);
2440 goto error;
2441 } else {
2442 /*
2443 * Add the element-node to the result tree.
2444 */
2445 copy->doc = ctxt->output;
2447 /*
2448 * Create effective namespaces declarations.
2449 * OLD: xsltCopyNamespaceList(ctxt, copy, cur->nsDef);
2450 */
2451 if (lrInfo->effectiveNs != NULL) {
2452 xsltEffectiveNsPtr effNs = lrInfo->effectiveNs;
2453 xmlNsPtr ns, lastns = NULL;
2454
2455 while (effNs != NULL) {
2456 /*
2457 * Avoid generating redundant namespace
2458 * declarations; thus lookup if there is already
2459 * such a ns-decl in the result.
2460 */
2461 ns = xmlSearchNs(copy->doc, copy, effNs->prefix);
2462 if ((ns != NULL) &&
2463 (xmlStrEqual(ns->href, effNs->nsName)))
2464 {
2465 effNs = effNs->next;
2466 continue;
2467 }
2468 ns = xmlNewNs(copy, effNs->nsName, effNs->prefix);
2469 if (ns == NULL) {
2471 "Internal error in "
2472 "xsltApplySequenceConstructor(): "
2473 "Failed to copy a namespace "
2474 "declaration.\n");
2475 goto error;
2476 }
2477
2478 if (lastns == NULL)
2479 copy->nsDef = ns;
2480 else
2481 lastns->next =ns;
2482 lastns = ns;
2483
2484 effNs = effNs->next;
2485 }
2486
2487 }
2488 /*
2489 * NOTE that we don't need to apply ns-alising: this was
2490 * already done at compile-time.
2491 */
2492 if (cur->ns != NULL) {
2493 /*
2494 * If there's no such ns-decl in the result tree,
2495 * then xsltGetSpecialNamespace() will
2496 * create a ns-decl on the copied node.
2497 */
2498 copy->ns = xsltGetSpecialNamespace(ctxt, cur,
2499 cur->ns->href, cur->ns->prefix, copy);
2500 } else {
2501 /*
2502 * Undeclare the default namespace if needed.
2503 * This can be skipped, if the result element has
2504 * no ns-decls, in which case the result element
2505 * obviously does not declare a default namespace;
2506 * AND there's either no parent, or the parent
2507 * element is in no namespace; this means there's no
2508 * default namespace is scope to care about.
2509 *
2510 * REVISIT: This might result in massive
2511 * generation of ns-decls if nodes in a default
2512 * namespaces are mixed with nodes in no namespace.
2513 *
2514 */
2515 if (copy->nsDef ||
2516 ((insert != NULL) &&
2517 (insert->type == XML_ELEMENT_NODE) &&
2518 (insert->ns != NULL)))
2519 {
2521 NULL, NULL, copy);
2522 }
2523 }
2524 }
2525 /*
2526 * SPEC XSLT 2.0 "Each attribute of the literal result
2527 * element, other than an attribute in the XSLT namespace,
2528 * is processed to produce an attribute for the element in
2529 * the result tree."
2530 * NOTE: See bug #341325.
2531 */
2532 if (cur->properties != NULL) {
2533 xsltAttrListTemplateProcess(ctxt, copy, cur->properties);
2534 }
2535 } else if (IS_XSLT_ELEM_FAST(cur)) {
2536 /*
2537 * XSLT instructions
2538 * --------------------------------------------------------
2539 */
2540 if (info->type == XSLT_FUNC_UNKOWN_FORWARDS_COMPAT) {
2541 /*
2542 * We hit an unknown XSLT element.
2543 * Try to apply one of the fallback cases.
2544 */
2545 ctxt->insert = insert;
2546 if (!xsltApplyFallbacks(ctxt, contextNode, cur)) {
2548 "The is no fallback behaviour defined for "
2549 "the unknown XSLT element '%s'.\n",
2550 cur->name);
2551 }
2552 ctxt->insert = oldInsert;
2553 } else if (info->func != NULL) {
2554 /*
2555 * Execute the XSLT instruction.
2556 */
2557 ctxt->insert = insert;
2558
2559 info->func(ctxt, contextNode, cur,
2561
2562 /*
2563 * Cleanup temporary tree fragments.
2564 */
2565 if (oldLocalFragmentTop != ctxt->localRVT)
2566 xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
2567
2568 ctxt->insert = oldInsert;
2569 } else if (info->type == XSLT_FUNC_VARIABLE) {
2570 xsltStackElemPtr tmpvar = ctxt->vars;
2571
2573
2574 if (tmpvar != ctxt->vars) {
2575 /*
2576 * TODO: Using a @tmpvar is an annoying workaround, but
2577 * the current mechanisms do not provide any other way
2578 * of knowing if the var was really pushed onto the
2579 * stack.
2580 */
2581 ctxt->vars->level = level;
2582 }
2583 } else if (info->type == XSLT_FUNC_MESSAGE) {
2584 /*
2585 * TODO: Won't be hit, since we don't compile xsl:message.
2586 */
2587 xsltMessage(ctxt, contextNode, cur);
2588 } else {
2590 "Unexpected XSLT element '%s'.\n", cur->name);
2591 }
2592 goto skip_children;
2593
2594 } else {
2596 /*
2597 * Extension intructions (elements)
2598 * --------------------------------------------------------
2599 */
2600 if (cur->psvi == xsltExtMarker) {
2601 /*
2602 * The xsltExtMarker was set during the compilation
2603 * of extension instructions if there was no registered
2604 * handler for this specific extension function at
2605 * compile-time.
2606 * Libxslt will now lookup if a handler is
2607 * registered in the context of this transformation.
2608 */
2609 func = xsltExtElementLookup(ctxt, cur->name,
2610 cur->ns->href);
2611 } else
2612 func = ((xsltElemPreCompPtr) cur->psvi)->func;
2613
2614 if (func == NULL) {
2615 /*
2616 * No handler available.
2617 * Try to execute fallback behaviour via xsl:fallback.
2618 */
2619#ifdef WITH_XSLT_DEBUG_PROCESS
2622 "xsltApplySequenceConstructor: unknown extension %s\n",
2623 cur->name));
2624#endif
2625 ctxt->insert = insert;
2626 if (!xsltApplyFallbacks(ctxt, contextNode, cur)) {
2628 "Unknown extension instruction '{%s}%s'.\n",
2629 cur->ns->href, cur->name);
2630 }
2631 ctxt->insert = oldInsert;
2632 } else {
2633 /*
2634 * Execute the handler-callback.
2635 */
2636#ifdef WITH_XSLT_DEBUG_PROCESS
2638 "xsltApplySequenceConstructor: extension construct %s\n",
2639 cur->name));
2640#endif
2641 /*
2642 * Disable the xsltCopyTextString optimization for
2643 * extension elements. Extensions could append text using
2644 * xmlAddChild which will free the buffer pointed to by
2645 * 'lasttext'. This buffer could later be reallocated with
2646 * a different size than recorded in 'lasttsize'. See bug
2647 * #777432.
2648 */
2649 if (cur->psvi == xsltExtMarker) {
2650 ctxt->lasttext = NULL;
2651 }
2652
2653 ctxt->insert = insert;
2654
2655 func(ctxt, contextNode, cur, cur->psvi);
2656
2657 /*
2658 * Cleanup temporary tree fragments.
2659 */
2660 if (oldLocalFragmentTop != ctxt->localRVT)
2661 xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
2662
2663 ctxt->insert = oldInsert;
2664 }
2665 goto skip_children;
2666 }
2667
2668 } else if (XSLT_IS_TEXT_NODE(cur)) {
2669 /*
2670 * Text
2671 * ------------------------------------------------------------
2672 */
2673#ifdef WITH_XSLT_DEBUG_PROCESS
2674 if (cur->name == xmlStringTextNoenc) {
2677 "xsltApplySequenceConstructor: copy unescaped text '%s'\n",
2678 cur->content));
2679 } else {
2682 "xsltApplySequenceConstructor: copy text '%s'\n",
2683 cur->content));
2684 }
2685#endif
2686 if (xsltCopyText(ctxt, insert, cur, ctxt->internalized) == NULL)
2687 goto error;
2688 }
2689
2690#else /* XSLT_REFACTORED */
2691
2692 if (IS_XSLT_ELEM(cur)) {
2693 /*
2694 * This is an XSLT node
2695 */
2697
2698 if (info == NULL) {
2699 if (IS_XSLT_NAME(cur, "message")) {
2700 xsltMessage(ctxt, contextNode, cur);
2701 } else {
2702 /*
2703 * That's an error try to apply one of the fallback cases
2704 */
2705 ctxt->insert = insert;
2706 if (!xsltApplyFallbacks(ctxt, contextNode, cur)) {
2708 "xsltApplySequenceConstructor: %s was not compiled\n",
2709 cur->name);
2710 }
2711 ctxt->insert = oldInsert;
2712 }
2713 goto skip_children;
2714 }
2715
2716 if (info->func != NULL) {
2717 oldCurInst = ctxt->inst;
2718 ctxt->inst = cur;
2719 ctxt->insert = insert;
2720
2721 info->func(ctxt, contextNode, cur, (xsltElemPreCompPtr) info);
2722
2723 /*
2724 * Cleanup temporary tree fragments.
2725 */
2726 if (oldLocalFragmentTop != ctxt->localRVT)
2727 xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
2728
2729 ctxt->insert = oldInsert;
2730 ctxt->inst = oldCurInst;
2731 goto skip_children;
2732 }
2733
2734 if (IS_XSLT_NAME(cur, "variable")) {
2735 xsltStackElemPtr tmpvar = ctxt->vars;
2736
2737 oldCurInst = ctxt->inst;
2738 ctxt->inst = cur;
2739
2741
2742 ctxt->inst = oldCurInst;
2743
2744 if (tmpvar != ctxt->vars) {
2745 /*
2746 * TODO: Using a @tmpvar is an annoying workaround, but
2747 * the current mechanisms do not provide any other way
2748 * of knowing if the var was really pushed onto the
2749 * stack.
2750 */
2751 ctxt->vars->level = level;
2752 }
2753 } else if (IS_XSLT_NAME(cur, "message")) {
2754 xsltMessage(ctxt, contextNode, cur);
2755 } else {
2757 "Unexpected XSLT element '%s'.\n", cur->name);
2758 }
2759 goto skip_children;
2760 } else if ((cur->type == XML_TEXT_NODE) ||
2761 (cur->type == XML_CDATA_SECTION_NODE)) {
2762
2763 /*
2764 * This text comes from the stylesheet
2765 * For stylesheets, the set of whitespace-preserving
2766 * element names consists of just xsl:text.
2767 */
2768#ifdef WITH_XSLT_DEBUG_PROCESS
2769 if (cur->type == XML_CDATA_SECTION_NODE) {
2771 "xsltApplySequenceConstructor: copy CDATA text %s\n",
2772 cur->content));
2773 } else if (cur->name == xmlStringTextNoenc) {
2775 "xsltApplySequenceConstructor: copy unescaped text %s\n",
2776 cur->content));
2777 } else {
2779 "xsltApplySequenceConstructor: copy text %s\n",
2780 cur->content));
2781 }
2782#endif
2783 if (xsltCopyText(ctxt, insert, cur, ctxt->internalized) == NULL)
2784 goto error;
2785 } else if ((cur->type == XML_ELEMENT_NODE) &&
2786 (cur->ns != NULL) && (cur->psvi != NULL)) {
2787 xsltTransformFunction function;
2788
2789 oldCurInst = ctxt->inst;
2790 ctxt->inst = cur;
2791 /*
2792 * Flagged as an extension element
2793 */
2794 if (cur->psvi == xsltExtMarker)
2795 function = xsltExtElementLookup(ctxt, cur->name,
2796 cur->ns->href);
2797 else
2798 function = ((xsltElemPreCompPtr) cur->psvi)->func;
2799
2800 if (function == NULL) {
2802 int found = 0;
2803
2804#ifdef WITH_XSLT_DEBUG_PROCESS
2806 "xsltApplySequenceConstructor: unknown extension %s\n",
2807 cur->name));
2808#endif
2809 /*
2810 * Search if there are fallbacks
2811 */
2812 ctxt->insert = insert;
2813 child = cur->children;
2814 while (child != NULL) {
2815 if ((IS_XSLT_ELEM(child)) &&
2816 (IS_XSLT_NAME(child, "fallback")))
2817 {
2818 found = 1;
2819 xsltApplySequenceConstructor(ctxt, contextNode,
2820 child->children, NULL);
2821 }
2822 child = child->next;
2823 }
2824 ctxt->insert = oldInsert;
2825
2826 if (!found) {
2828 "xsltApplySequenceConstructor: failed to find extension %s\n",
2829 cur->name);
2830 }
2831 } else {
2832#ifdef WITH_XSLT_DEBUG_PROCESS
2834 "xsltApplySequenceConstructor: extension construct %s\n",
2835 cur->name));
2836#endif
2837
2838 /*
2839 * Disable the xsltCopyTextString optimization for
2840 * extension elements. Extensions could append text using
2841 * xmlAddChild which will free the buffer pointed to by
2842 * 'lasttext'. This buffer could later be reallocated with
2843 * a different size than recorded in 'lasttsize'. See bug
2844 * #777432.
2845 */
2846 if (cur->psvi == xsltExtMarker) {
2847 ctxt->lasttext = NULL;
2848 }
2849
2850 ctxt->insert = insert;
2851
2852 function(ctxt, contextNode, cur, cur->psvi);
2853 /*
2854 * Cleanup temporary tree fragments.
2855 */
2856 if (oldLocalFragmentTop != ctxt->localRVT)
2857 xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
2858
2859 ctxt->insert = oldInsert;
2860
2861 }
2862 ctxt->inst = oldCurInst;
2863 goto skip_children;
2864 } else if (cur->type == XML_ELEMENT_NODE) {
2865#ifdef WITH_XSLT_DEBUG_PROCESS
2867 "xsltApplySequenceConstructor: copy node %s\n",
2868 cur->name));
2869#endif
2870 oldCurInst = ctxt->inst;
2871 ctxt->inst = cur;
2872
2873 if ((copy = xsltShallowCopyElem(ctxt, cur, insert, 1)) == NULL)
2874 goto error;
2875 /*
2876 * Add extra namespaces inherited from the current template
2877 * if we are in the first level children and this is a
2878 * "real" template.
2879 */
2880 if ((templ != NULL) && (oldInsert == insert) &&
2881 (ctxt->templ != NULL) && (ctxt->templ->inheritedNs != NULL)) {
2882 int i;
2883 xmlNsPtr ns, ret;
2884
2885 for (i = 0; i < ctxt->templ->inheritedNsNr; i++) {
2886 const xmlChar *URI = NULL;
2888 ns = ctxt->templ->inheritedNs[i];
2889
2890 /* Note that the XSLT namespace was already excluded
2891 * in xsltGetInheritedNsList().
2892 */
2893#if 0
2894 if (xmlStrEqual(ns->href, XSLT_NAMESPACE))
2895 continue;
2896#endif
2897 style = ctxt->style;
2898 while (style != NULL) {
2899 if (style->nsAliases != NULL)
2900 URI = (const xmlChar *)
2901 xmlHashLookup(style->nsAliases, ns->href);
2902 if (URI != NULL)
2903 break;
2904
2906 }
2907 if (URI == UNDEFINED_DEFAULT_NS)
2908 continue;
2909 if (URI == NULL)
2910 URI = ns->href;
2911 /*
2912 * TODO: The following will still be buggy for the
2913 * non-refactored code.
2914 */
2915 ret = xmlSearchNs(copy->doc, copy, ns->prefix);
2916 if ((ret == NULL) || (!xmlStrEqual(ret->href, URI)))
2917 {
2918 xmlNewNs(copy, URI, ns->prefix);
2919 }
2920 }
2921 if (copy->ns != NULL) {
2922 /*
2923 * Fix the node namespace if needed
2924 */
2925 copy->ns = xsltGetNamespace(ctxt, cur, copy->ns, copy);
2926 }
2927 }
2928 /*
2929 * all the attributes are directly inherited
2930 */
2931 if (cur->properties != NULL) {
2932 xsltAttrListTemplateProcess(ctxt, copy, cur->properties);
2933 }
2934 ctxt->inst = oldCurInst;
2935 }
2936#endif /* else of XSLT_REFACTORED */
2937
2938 /*
2939 * Descend into content in document order.
2940 */
2941 if (cur->children != NULL) {
2942 if (cur->children->type != XML_ENTITY_DECL) {
2943 cur = cur->children;
2944 level++;
2945 if (copy != NULL)
2946 insert = copy;
2947 continue;
2948 }
2949 }
2950
2951skip_children:
2952 /*
2953 * If xslt:message was just processed, we might have hit a
2954 * terminate='yes'; if so, then break the loop and clean up.
2955 * TODO: Do we need to check this also before trying to descend
2956 * into the content?
2957 */
2958 if (ctxt->state == XSLT_STATE_STOPPED)
2959 break;
2960 if (cur->next != NULL) {
2961 cur = cur->next;
2962 continue;
2963 }
2964
2965 do {
2966 cur = cur->parent;
2967 level--;
2968 /*
2969 * Pop variables/params (xsl:variable and xsl:param).
2970 */
2971 if ((ctxt->varsNr > oldVarsNr) && (ctxt->vars->level > level)) {
2972 xsltLocalVariablePop(ctxt, oldVarsNr, level);
2973 }
2974
2975 insert = insert->parent;
2976 if (cur == NULL)
2977 break;
2978 if (cur == list->parent) {
2979 cur = NULL;
2980 break;
2981 }
2982 if (cur->next != NULL) {
2983 cur = cur->next;
2984 break;
2985 }
2986 } while (cur != NULL);
2987 }
2988
2989error:
2990 /*
2991 * In case of errors: pop remaining variables.
2992 */
2993 if (ctxt->varsNr > oldVarsNr)
2994 xsltLocalVariablePop(ctxt, oldVarsNr, -1);
2995
2996 ctxt->node = oldContextNode;
2997 ctxt->inst = oldInst;
2998 ctxt->insert = oldInsert;
2999
3000 ctxt->depth--;
3001
3002#ifdef WITH_DEBUGGER
3003 if ((ctxt->debugStatus != XSLT_DEBUG_NONE) && (addCallResult)) {
3004 xslDropCall();
3005 }
3006#endif
3007}
xsltTransformFunction xsltExtElementLookup(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *URI)
Definition: extensions.c:1668
void xsltDebug(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr inst ATTRIBUTE_UNUSED, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
Definition: extra.c:35
Arabic default style
Definition: afstyles.h:94
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
const xmlChar * xsltExtMarker
Definition: preproc.c:24
static xmlNodePtr xsltCopyText(xsltTransformContextPtr ctxt, xmlNodePtr target, xmlNodePtr cur, int interned)
Definition: transform.c:945
static xmlNodePtr xsltAddChild(xmlNodePtr parent, xmlNodePtr cur)
Definition: transform.c:751
static xmlNodePtr xsltShallowCopyElem(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr insert, int isLRE)
Definition: transform.c:1296
static void xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base)
Definition: transform.c:2226
static int xsltApplyFallbacks(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst)
Definition: transform.c:1803
GLint level
Definition: gl.h:1546
GLenum func
Definition: glext.h:6028
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
xsltStylesheetPtr xsltNextImport(xsltStylesheetPtr cur)
Definition: imports.c:251
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
xmlNsPtr xsltGetSpecialNamespace(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, const xmlChar *nsName, const xmlChar *nsPrefix, xmlNodePtr target)
Definition: namespaces.c:299
xmlNsPtr xsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns, xmlNodePtr out)
Definition: namespaces.c:596
#define UNDEFINED_DEFAULT_NS
Definition: namespaces.h:30
XMLPUBVAR const xmlChar xmlStringTextNoenc[]
#define list
Definition: rosglue.h:35
XMLPUBFUN void *XMLCALL xmlHashLookup(xmlHashTablePtr table, const xmlChar *name)
Definition: hash.c:461
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
@ XML_ENTITY_DECL
Definition: tree.h:176
@ XML_CDATA_SECTION_NODE
Definition: tree.h:163
@ XML_TEXT_NODE
Definition: tree.h:162
@ XML_ELEMENT_NODE
Definition: tree.h:160
XMLPUBFUN xmlNsPtr XMLCALL xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix)
XMLPUBFUN xmlNodePtr XMLCALL xmlDocCopyNode(xmlNodePtr node, xmlDocPtr doc, int recursive)
Definition: tree.h:551
Definition: tree.h:389
struct _xmlNs * next
Definition: tree.h:390
xmlNsPtr * inheritedNs
xsltTransformState state
xsltStackElemPtr vars
xsltStylesheetPtr style
Definition: mxnamespace.c:45
BSTR prefix
Definition: mxnamespace.c:46
xmlAttrPtr xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt, xmlNodePtr target, xmlAttrPtr attrs)
Definition: templates.c:635
XSLTPUBFUN void XSLTCALL xslHandleDebugger(xmlNodePtr cur, xmlNodePtr node, xsltTemplatePtr templ, xsltTransformContextPtr ctxt)
void xsltParseStylesheetVariable(xsltTransformContextPtr ctxt, xmlNodePtr inst)
Definition: variables.c:2149
static int insert
Definition: xmllint.c:138
@ XSLT_FUNC_VARIABLE
xsltElemPreComp * xsltElemPreCompPtr
@ XSLT_STATE_STOPPED
#define XSLT_IS_TEXT_NODE(n)
Definition: xsltInternals.h:38
xsltStylePreComp * xsltStylePreCompPtr
void(* xsltTransformFunction)(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr comp)
#define XSLT_NAMESPACE
Definition: xslt.h:46
xmlGenericErrorFunc xsltGenericError
Definition: xsltutils.c:502
void * xsltGenericErrorContext
Definition: xsltutils.c:503
void xsltMessage(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst)
Definition: xsltutils.c:408
@ XSLT_DEBUG_QUIT
Definition: xsltutils.h:282
@ XSLT_DEBUG_NONE
Definition: xsltutils.h:273
@ XSLT_DEBUG_RUN_RESTART
Definition: xsltutils.h:281
XSLTPUBFUN void XSLTCALL xslDropCall(void)
#define IS_XSLT_NAME(n, val)
Definition: xsltutils.h:60
@ XSLT_TRACE_APPLY_TEMPLATE
Definition: xsltutils.h:103
#define XSLT_TRACE(ctxt, code, call)
Definition: xsltutils.h:125

Referenced by xsltApplyFallbacks(), xsltApplyOneTemplate(), xsltApplySequenceConstructor(), xsltApplyXSLTTemplate(), xsltChoose(), xsltCopy(), xsltDocumentElem(), xsltElement(), xsltForEach(), and xsltIf().

◆ xsltApplyStripSpaces()

void xsltApplyStripSpaces ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node 
)

xsltApplyStripSpaces: @ctxt: a XSLT process context @node: the root of the XML tree

Strip the unwanted ignorable spaces from the input tree

Definition at line 5609 of file transform.c.

5609 {
5611#ifdef WITH_XSLT_DEBUG_PROCESS
5612 int nb = 0;
5613#endif
5614
5615
5616 current = node;
5617 while (current != NULL) {
5618 /*
5619 * Cleanup children empty nodes if asked for
5620 */
5621 if ((IS_XSLT_REAL_NODE(current)) &&
5622 (current->children != NULL) &&
5624 xmlNodePtr delete = NULL, cur = current->children;
5625
5626 while (cur != NULL) {
5627 if (IS_BLANK_NODE(cur))
5628 delete = cur;
5629
5630 cur = cur->next;
5631 if (delete != NULL) {
5632 xmlUnlinkNode(delete);
5633 xmlFreeNode(delete);
5634 delete = NULL;
5635#ifdef WITH_XSLT_DEBUG_PROCESS
5636 nb++;
5637#endif
5638 }
5639 }
5640 }
5641
5642 /*
5643 * Skip to next node in document order.
5644 */
5645 if (node->type == XML_ENTITY_REF_NODE) {
5646 /* process deep in entities */
5647 xsltApplyStripSpaces(ctxt, node->children);
5648 }
5649 if ((current->children != NULL) &&
5650 (current->type != XML_ENTITY_REF_NODE)) {
5651 current = current->children;
5652 } else if (current->next != NULL) {
5653 current = current->next;
5654 } else {
5655 do {
5656 current = current->parent;
5657 if (current == NULL)
5658 break;
5659 if (current == node)
5660 goto done;
5661 if (current->next != NULL) {
5662 current = current->next;
5663 break;
5664 }
5665 } while (current != NULL);
5666 }
5667 }
5668
5669done:
5670#ifdef WITH_XSLT_DEBUG_PROCESS
5672 "xsltApplyStripSpaces: removed %d ignorable blank node\n", nb));
5673#endif
5674 return;
5675}
#define IS_BLANK_NODE(n)
Definition: transform.c:47
void xsltApplyStripSpaces(xsltTransformContextPtr ctxt, xmlNodePtr node)
Definition: transform.c:5609
int xsltFindElemSpaceHandling(xsltTransformContextPtr ctxt, xmlNodePtr node)
Definition: imports.c:303
struct task_struct * current
Definition: linux.c:32
@ XML_ENTITY_REF_NODE
Definition: tree.h:164
XMLPUBFUN void XMLCALL xmlUnlinkNode(xmlNodePtr cur)
@ XSLT_TRACE_STRIP_SPACES
Definition: xsltutils.h:114
#define IS_XSLT_REAL_NODE(n)
Definition: xsltutils.h:68

Referenced by xsltApplyStripSpaces(), xsltApplyStylesheetInternal(), and xsltLoadDocument().

◆ xsltApplyStylesheet()

xmlDocPtr xsltApplyStylesheet ( xsltStylesheetPtr  style,
xmlDocPtr  doc,
const char **  params 
)

xsltApplyStylesheet: @style: a parsed XSLT stylesheet @doc: a parsed XML document @params: a NULL terminated arry of parameters names/values tuples

Apply the stylesheet to the document NOTE: This may lead to a non-wellformed output XML wise !

Returns the result document or NULL in case of error

Definition at line 6144 of file transform.c.

6146{
6148}
static xmlDocPtr xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc, const char **params, const char *output, FILE *profile, xsltTransformContextPtr userCtxt)
Definition: transform.c:5729

◆ xsltApplyStylesheetInternal()

static xmlDocPtr xsltApplyStylesheetInternal ( xsltStylesheetPtr  style,
xmlDocPtr  doc,
const char **  params,
const char output,
FILE profile,
xsltTransformContextPtr  userCtxt 
)
static

xsltApplyStylesheetInternal: @style: a parsed XSLT stylesheet @doc: a parsed XML document @params: a NULL terminated array of parameters names/values tuples @output: the targetted output @profile: profile FILE * output or NULL @user: user provided parameter

Apply the stylesheet to the document NOTE: This may lead to a non-wellformed output XML wise !

Returns the result document or NULL in case of error

Definition at line 5729 of file transform.c.

5732{
5733 xmlDocPtr res = NULL;
5736 const xmlChar *method;
5737 const xmlChar *doctypePublic;
5738 const xmlChar *doctypeSystem;
5739 const xmlChar *version;
5740 const xmlChar *encoding;
5741 xsltStackElemPtr variables;
5742 xsltStackElemPtr vptr;
5743
5745
5746 if ((style == NULL) || (doc == NULL))
5747 return (NULL);
5748
5749 if (style->internalized == 0) {
5750#ifdef WITH_XSLT_DEBUG
5752 "Stylesheet was not fully internalized !\n");
5753#endif
5754 }
5755 if (doc->intSubset != NULL) {
5756 /*
5757 * Avoid hitting the DTD when scanning nodes
5758 * but keep it linked as doc->intSubset
5759 */
5761 if (cur->next != NULL)
5762 cur->next->prev = cur->prev;
5763 if (cur->prev != NULL)
5764 cur->prev->next = cur->next;
5765 if (doc->children == cur)
5766 doc->children = cur->next;
5767 if (doc->last == cur)
5768 doc->last = cur->prev;
5769 cur->prev = cur->next = NULL;
5770 }
5771
5772 /*
5773 * Check for XPath document order availability
5774 */
5776 if (root != NULL) {
5777 if (((ptrdiff_t) root->content >= 0) &&
5779 xmlXPathOrderDocElems(doc);
5780 }
5781
5782 if (userCtxt != NULL)
5783 ctxt = userCtxt;
5784 else
5785 ctxt = xsltNewTransformContext(style, doc);
5786
5787 if (ctxt == NULL)
5788 return (NULL);
5789
5790 ctxt->initialContextDoc = doc;
5791 ctxt->initialContextNode = (xmlNodePtr) doc;
5792
5793 if (profile != NULL) {
5794#ifdef WITH_PROFILER
5795 ctxt->profile = 1;
5796#else
5797 xsltTransformError(ctxt, NULL, (xmlNodePtr) doc,
5798 "xsltApplyStylesheetInternal: "
5799 "libxslt compiled without profiler\n");
5800 goto error;
5801#endif
5802 }
5803
5804 if (output != NULL)
5805 ctxt->outputFile = output;
5806 else
5807 ctxt->outputFile = NULL;
5808
5809 /*
5810 * internalize the modes if needed
5811 */
5812 if (ctxt->dict != NULL) {
5813 if (ctxt->mode != NULL)
5814 ctxt->mode = xmlDictLookup(ctxt->dict, ctxt->mode, -1);
5815 if (ctxt->modeURI != NULL)
5816 ctxt->modeURI = xmlDictLookup(ctxt->dict, ctxt->modeURI, -1);
5817 }
5818
5820 XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
5821 XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
5824
5825 if ((method != NULL) &&
5826 (!xmlStrEqual(method, (const xmlChar *) "xml")))
5827 {
5828 if (xmlStrEqual(method, (const xmlChar *) "html")) {
5829 ctxt->type = XSLT_OUTPUT_HTML;
5830 if (((doctypePublic != NULL) || (doctypeSystem != NULL))) {
5831 res = htmlNewDoc(doctypeSystem, doctypePublic);
5832 } else {
5833 if (version == NULL) {
5834 xmlDtdPtr dtd;
5835
5836 res = htmlNewDoc(NULL, NULL);
5837 /*
5838 * Make sure no DTD node is generated in this case
5839 */
5840 if (res != NULL) {
5841 dtd = xmlGetIntSubset(res);
5842 if (dtd != NULL) {
5844 xmlFreeDtd(dtd);
5845 }
5846 res->intSubset = NULL;
5847 res->extSubset = NULL;
5848 }
5849 } else {
5850
5851#ifdef XSLT_GENERATE_HTML_DOCTYPE
5852 xsltGetHTMLIDs(version, &doctypePublic, &doctypeSystem);
5853#endif
5854 res = htmlNewDoc(doctypeSystem, doctypePublic);
5855 }
5856 }
5857 if (res == NULL)
5858 goto error;
5859 res->dict = ctxt->dict;
5860 xmlDictReference(res->dict);
5861
5862#ifdef WITH_XSLT_DEBUG
5864 "reusing transformation dict for output\n");
5865#endif
5866 } else if (xmlStrEqual(method, (const xmlChar *) "xhtml")) {
5867 xsltTransformError(ctxt, NULL, (xmlNodePtr) doc,
5868 "xsltApplyStylesheetInternal: unsupported method xhtml, using html\n");
5869 ctxt->type = XSLT_OUTPUT_HTML;
5870 res = htmlNewDoc(doctypeSystem, doctypePublic);
5871 if (res == NULL)
5872 goto error;
5873 res->dict = ctxt->dict;
5874 xmlDictReference(res->dict);
5875
5876#ifdef WITH_XSLT_DEBUG
5878 "reusing transformation dict for output\n");
5879#endif
5880 } else if (xmlStrEqual(method, (const xmlChar *) "text")) {
5881 ctxt->type = XSLT_OUTPUT_TEXT;
5882 res = xmlNewDoc(style->version);
5883 if (res == NULL)
5884 goto error;
5885 res->dict = ctxt->dict;
5886 xmlDictReference(res->dict);
5887
5888#ifdef WITH_XSLT_DEBUG
5890 "reusing transformation dict for output\n");
5891#endif
5892 } else {
5893 xsltTransformError(ctxt, NULL, (xmlNodePtr) doc,
5894 "xsltApplyStylesheetInternal: unsupported method (%s)\n",
5895 method);
5896 goto error;
5897 }
5898 } else {
5899 ctxt->type = XSLT_OUTPUT_XML;
5900 res = xmlNewDoc(style->version);
5901 if (res == NULL)
5902 goto error;
5903 res->dict = ctxt->dict;
5904 xmlDictReference(ctxt->dict);
5905#ifdef WITH_XSLT_DEBUG
5907 "reusing transformation dict for output\n");
5908#endif
5909 }
5910 res->charset = XML_CHAR_ENCODING_UTF8;
5911 if (encoding != NULL)
5912 res->encoding = xmlStrdup(encoding);
5913 variables = style->variables;
5914
5915 ctxt->node = (xmlNodePtr) doc;
5916 ctxt->output = res;
5917
5918 ctxt->xpathCtxt->contextSize = 1;
5919 ctxt->xpathCtxt->proximityPosition = 1;
5920 ctxt->xpathCtxt->node = NULL; /* TODO: Set the context node here? */
5921
5922 /*
5923 * Start the evaluation, evaluate the params, the stylesheets globals
5924 * and start by processing the top node.
5925 */
5926 if (xsltNeedElemSpaceHandling(ctxt))
5928 /*
5929 * Evaluate global params and user-provided params.
5930 */
5931 if (ctxt->globalVars == NULL)
5932 ctxt->globalVars = xmlHashCreate(20);
5933 if (params != NULL) {
5935 }
5936
5937 /* need to be called before evaluating global variables */
5938 xsltCountKeys(ctxt);
5939
5941
5942 /* Clean up any unused RVTs. */
5944
5945 ctxt->insert = (xmlNodePtr) res;
5946 ctxt->varsBase = ctxt->varsNr - 1;
5947
5948 /*
5949 * Start processing the source tree -----------------------------------
5950 */
5951 xsltProcessOneNode(ctxt, ctxt->node, NULL);
5952 /*
5953 * Remove all remaining vars from the stack.
5954 */
5955 xsltLocalVariablePop(ctxt, 0, -2);
5957
5958 xsltCleanupTemplates(style); /* TODO: <- style should be read only */
5959
5960 /*
5961 * Now cleanup our variables so stylesheet can be re-used
5962 *
5963 * TODO: this is not needed anymore global variables are copied
5964 * and not evaluated directly anymore, keep this as a check
5965 */
5966 if (style->variables != variables) {
5967 vptr = style->variables;
5968 while (vptr->next != variables)
5969 vptr = vptr->next;
5970 vptr->next = NULL;
5971 xsltFreeStackElemList(style->variables);
5972 style->variables = variables;
5973 }
5974 vptr = style->variables;
5975 while (vptr != NULL) {
5976 if (vptr->computed) {
5977 if (vptr->value != NULL) {
5978 xmlXPathFreeObject(vptr->value);
5979 vptr->value = NULL;
5980 vptr->computed = 0;
5981 }
5982 }
5983 vptr = vptr->next;
5984 }
5985#if 0
5986 /*
5987 * code disabled by wmb; awaiting kb's review
5988 * problem is that global variable(s) may contain xpath objects
5989 * from doc associated with RVT, so can't be freed at this point.
5990 * xsltFreeTransformContext includes a call to xsltFreeRVTs, so
5991 * I assume this shouldn't be required at this point.
5992 */
5993 /*
5994 * Free all remaining tree fragments.
5995 */
5996 xsltFreeRVTs(ctxt);
5997#endif
5998 /*
5999 * Do some post processing work depending on the generated output
6000 */
6002 if (root != NULL) {
6003 const xmlChar *doctype = NULL;
6004
6005 if ((root->ns != NULL) && (root->ns->prefix != NULL))
6006 doctype = xmlDictQLookup(ctxt->dict, root->ns->prefix, root->name);
6007 if (doctype == NULL)
6008 doctype = root->name;
6009
6010 /*
6011 * Apply the default selection of the method
6012 */
6013 if ((method == NULL) &&
6014 (root->ns == NULL) &&
6015 (!xmlStrcasecmp(root->name, (const xmlChar *) "html"))) {
6016 xmlNodePtr tmp;
6017
6018 tmp = res->children;
6019 while ((tmp != NULL) && (tmp != root)) {
6020 if (tmp->type == XML_ELEMENT_NODE)
6021 break;
6022 if ((tmp->type == XML_TEXT_NODE) && (!xmlIsBlankNode(tmp)))
6023 break;
6024 tmp = tmp->next;
6025 }
6026 if (tmp == root) {
6027 ctxt->type = XSLT_OUTPUT_HTML;
6028 /*
6029 * REVISIT TODO: XML_HTML_DOCUMENT_NODE is set after the
6030 * transformation on the doc, but functions like
6031 */
6033 if (((doctypePublic != NULL) || (doctypeSystem != NULL))) {
6034 res->intSubset = xmlCreateIntSubset(res, doctype,
6035 doctypePublic,
6036 doctypeSystem);
6037#ifdef XSLT_GENERATE_HTML_DOCTYPE
6038 } else if (version != NULL) {
6039 xsltGetHTMLIDs(version, &doctypePublic,
6040 &doctypeSystem);
6041 if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
6042 res->intSubset =
6043 xmlCreateIntSubset(res, doctype,
6044 doctypePublic,
6045 doctypeSystem);
6046#endif
6047 }
6048 }
6049
6050 }
6051 if (ctxt->type == XSLT_OUTPUT_XML) {
6052 XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
6053 XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
6054 if (((doctypePublic != NULL) || (doctypeSystem != NULL))) {
6056 /* Need a small "hack" here to assure DTD comes before
6057 possible comment nodes */
6058 node = res->children;
6059 last = res->last;
6060 res->children = NULL;
6061 res->last = NULL;
6062 res->intSubset = xmlCreateIntSubset(res, doctype,
6063 doctypePublic,
6064 doctypeSystem);
6065 if (res->children != NULL) {
6066 res->children->next = node;
6067 node->prev = res->children;
6068 res->last = last;
6069 } else {
6070 res->children = node;
6071 res->last = last;
6072 }
6073 }
6074 }
6075 }
6076 xmlXPathFreeNodeSet(ctxt->nodeList);
6077
6078#ifdef WITH_PROFILER
6079 if (profile != NULL) {
6081 }
6082#endif
6083
6084 /*
6085 * Be pedantic.
6086 */
6087 if ((ctxt != NULL) && (ctxt->state != XSLT_STATE_OK)) {
6088 xmlFreeDoc(res);
6089 res = NULL;
6090 }
6091 if ((res != NULL) && (ctxt != NULL) && (output != NULL)) {
6092 int ret;
6093
6094 ret = xsltCheckWrite(ctxt->sec, ctxt, (const xmlChar *) output);
6095 if (ret == 0) {
6097 "xsltApplyStylesheet: forbidden to save to %s\n",
6098 output);
6099 } else if (ret < 0) {
6101 "xsltApplyStylesheet: saving to %s may not be possible\n",
6102 output);
6103 }
6104 }
6105
6106#ifdef XSLT_DEBUG_PROFILE_CACHE
6107 printf("# Cache:\n");
6108 printf("# Reused tree fragments: %d\n", ctxt->cache->dbgReusedRVTs);
6109 printf("# Reused variables : %d\n", ctxt->cache->dbgReusedVars);
6110#endif
6111
6112 if ((ctxt != NULL) && (userCtxt == NULL))
6114
6115 return (res);
6116
6117error:
6118 if (res != NULL)
6119 xmlFreeDoc(res);
6120
6121#ifdef XSLT_DEBUG_PROFILE_CACHE
6122 printf("# Cache:\n");
6123 printf("# Reused tree fragments: %d\n", ctxt->cache->dbgReusedRVTs);
6124 printf("# Reused variables : %d\n", ctxt->cache->dbgReusedVars);
6125#endif
6126
6127 if ((ctxt != NULL) && (userCtxt == NULL))
6129 return (NULL);
6130}
void xsltInitGlobals(void)
Definition: extensions.c:2257
void xsltShutdownCtxtExts(xsltTransformContextPtr ctxt)
Definition: extensions.c:1081
struct _root root
void xsltCleanupTemplates(xsltStylesheetPtr style ATTRIBUTE_UNUSED)
Definition: pattern.c:2517
int xsltCheckWrite(xsltSecurityPrefsPtr sec, xsltTransformContextPtr ctxt, const xmlChar *URL)
Definition: security.c:335
xsltTransformContextPtr xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc)
Definition: transform.c:536
void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xsltStackElemPtr withParams)
Definition: transform.c:2064
void xsltFreeTransformContext(xsltTransformContextPtr ctxt)
Definition: transform.c:689
static int xsltCountKeys(xsltTransformContextPtr ctxt)
Definition: transform.c:5678
static int xsltGetHTMLIDs(const xmlChar *version, const xmlChar **publicID, const xmlChar **systemID)
Definition: transform.c:5581
static const WCHAR version[]
Definition: asmname.c:66
method
Definition: dragdrop.c:54
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
@ XML_CHAR_ENCODING_UTF8
Definition: encoding.h:59
#define printf
Definition: freeldr.h:93
GLuint res
Definition: glext.h:9613
int xsltNeedElemSpaceHandling(xsltTransformContextPtr ctxt)
Definition: imports.c:276
#define profile
Definition: kernel32.h:12
static UINT UINT last
Definition: font.c:45
XMLPUBFUN const xmlChar *XMLCALL xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:867
XMLPUBFUN const xmlChar *XMLCALL xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name)
Definition: dict.c:1115
XMLPUBFUN int XMLCALL xmlDictReference(xmlDictPtr dict)
Definition: dict.c:647
XMLPUBFUN xmlHashTablePtr XMLCALL xmlHashCreate(int size)
Definition: hash.c:176
XMLPUBFUN xmlNodePtr XMLCALL xmlDocGetRootElement(const xmlDoc *doc)
XMLPUBFUN xmlDtdPtr XMLCALL xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID)
XMLPUBFUN void XMLCALL xmlFreeDtd(xmlDtdPtr cur)
XMLPUBFUN void XMLCALL xmlFreeDoc(xmlDocPtr cur)
xmlNode * xmlNodePtr
Definition: tree.h:488
XMLPUBFUN xmlDocPtr XMLCALL xmlNewDoc(const xmlChar *version)
XMLPUBFUN xmlDtdPtr XMLCALL xmlGetIntSubset(const xmlDoc *doc)
@ XML_HTML_DOCUMENT_NODE
Definition: tree.h:172
XMLPUBFUN int XMLCALL xmlIsBlankNode(const xmlNode *node)
#define XSLT_GET_IMPORT_PTR(res, style, name)
Definition: imports.h:27
struct _xmlDtd * intSubset
Definition: tree.h:570
struct _xmlNode * last
Definition: tree.h:556
struct _xmlNode * children
Definition: tree.h:555
Definition: tree.h:406
struct _xmlNode * next
Definition: tree.h:496
xmlElementType type
Definition: tree.h:491
struct _xsltStackElem * next
xmlXPathObjectPtr value
const xmlChar * modeURI
xmlHashTablePtr globalVars
xmlNodeSetPtr nodeList
xsltTransformCachePtr cache
xmlNodePtr initialContextNode
xmlXPathContextPtr xpathCtxt
const xmlChar * mode
void xsltFreeRVTs(xsltTransformContextPtr ctxt)
Definition: variables.c:416
int xsltEvalGlobalVariables(xsltTransformContextPtr ctxt)
Definition: variables.c:1260
void xsltFreeStackElemList(xsltStackElemPtr elem)
Definition: variables.c:603
int xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params)
Definition: variables.c:1662
static char * encoding
Definition: xmllint.c:155
XMLPUBFUN int XMLCALL xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:275
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:67
@ XSLT_OUTPUT_XML
@ XSLT_OUTPUT_HTML
@ XSLT_OUTPUT_TEXT
@ XSLT_STATE_OK
int xslDebugStatus
Definition: xsltutils.c:2366
XSLTPUBFUN void XSLTCALL xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output)

Referenced by xsltApplyStylesheet(), xsltApplyStylesheetUser(), xsltProfileStylesheet(), and xsltRunStylesheetUser().

◆ xsltApplyStylesheetUser()

xmlDocPtr xsltApplyStylesheetUser ( xsltStylesheetPtr  style,
xmlDocPtr  doc,
const char **  params,
const char output,
FILE profile,
xsltTransformContextPtr  userCtxt 
)

xsltApplyStylesheetUser: @style: a parsed XSLT stylesheet @doc: a parsed XML document @params: a NULL terminated array of parameters names/values tuples @output: the targetted output @profile: profile FILE * output or NULL @userCtxt: user provided transform context

Apply the stylesheet to the document and allow the user to provide its own transformation context.

Returns the result document or NULL in case of error

Definition at line 6187 of file transform.c.

6190{
6191 xmlDocPtr res;
6192
6194 profile, userCtxt);
6195 return (res);
6196}

◆ xsltApplyTemplates()

void xsltApplyTemplates ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltApplyTemplates: @ctxt: a XSLT transformation context @node: the 'current node' in the source tree @inst: the element node of an XSLT 'apply-templates' instruction @castedComp: the compiled instruction

Processes the XSLT 'apply-templates' instruction on the current node.

Definition at line 4782 of file transform.c.

4784{
4785#ifdef XSLT_REFACTORED
4786 xsltStyleItemApplyTemplatesPtr comp =
4787 (xsltStyleItemApplyTemplatesPtr) castedComp;
4788#else
4789 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
4790#endif
4791 int i;
4792 xmlNodePtr cur, oldContextNode;
4793 xmlNodeSetPtr list = NULL, oldList;
4794 xsltStackElemPtr withParams = NULL;
4795 int oldXPProximityPosition, oldXPContextSize;
4796 const xmlChar *oldMode, *oldModeURI;
4797 xmlDocPtr oldXPDoc;
4798 xsltDocumentPtr oldDocInfo;
4799 xmlXPathContextPtr xpctxt;
4800
4801 if (comp == NULL) {
4802 xsltTransformError(ctxt, NULL, inst,
4803 "xsl:apply-templates : compilation failed\n");
4804 return;
4805 }
4806 if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
4807 return;
4808
4809#ifdef WITH_XSLT_DEBUG_PROCESS
4810 if ((node != NULL) && (node->name != NULL))
4812 "xsltApplyTemplates: node: '%s'\n", node->name));
4813#endif
4814
4815 xpctxt = ctxt->xpathCtxt;
4816 /*
4817 * Save context states.
4818 */
4819 oldContextNode = ctxt->node;
4820 oldMode = ctxt->mode;
4821 oldModeURI = ctxt->modeURI;
4822 oldDocInfo = ctxt->document;
4823 oldList = ctxt->nodeList;
4824
4825 /*
4826 * The xpath context size and proximity position, as
4827 * well as the xpath and context documents, may be changed
4828 * so we save their initial state and will restore on exit
4829 */
4830 oldXPContextSize = xpctxt->contextSize;
4831 oldXPProximityPosition = xpctxt->proximityPosition;
4832 oldXPDoc = xpctxt->doc;
4833
4834 /*
4835 * Set up contexts.
4836 */
4837 ctxt->mode = comp->mode;
4838 ctxt->modeURI = comp->modeURI;
4839
4840 if (comp->select != NULL) {
4841 xmlXPathObjectPtr res = NULL;
4842
4843 if (comp->comp == NULL) {
4844 xsltTransformError(ctxt, NULL, inst,
4845 "xsl:apply-templates : compilation failed\n");
4846 goto error;
4847 }
4848#ifdef WITH_XSLT_DEBUG_PROCESS
4850 "xsltApplyTemplates: select %s\n", comp->select));
4851#endif
4852
4853 res = xsltPreCompEval(ctxt, node, comp);
4854
4855 if (res != NULL) {
4856 if (res->type == XPATH_NODESET) {
4857 list = res->nodesetval; /* consume the node set */
4858 res->nodesetval = NULL;
4859 } else {
4860 xsltTransformError(ctxt, NULL, inst,
4861 "The 'select' expression did not evaluate to a "
4862 "node set.\n");
4863 ctxt->state = XSLT_STATE_STOPPED;
4864 xmlXPathFreeObject(res);
4865 goto error;
4866 }
4867 xmlXPathFreeObject(res);
4868 /*
4869 * Note: An xsl:apply-templates with a 'select' attribute,
4870 * can change the current source doc.
4871 */
4872 } else {
4873 xsltTransformError(ctxt, NULL, inst,
4874 "Failed to evaluate the 'select' expression.\n");
4875 ctxt->state = XSLT_STATE_STOPPED;
4876 goto error;
4877 }
4878 if (list == NULL) {
4879#ifdef WITH_XSLT_DEBUG_PROCESS
4881 "xsltApplyTemplates: select didn't evaluate to a node list\n"));
4882#endif
4883 goto exit;
4884 }
4885 /*
4886 *
4887 * NOTE: Previously a document info (xsltDocument) was
4888 * created and attached to the Result Tree Fragment.
4889 * But such a document info is created on demand in
4890 * xsltKeyFunction() (functions.c), so we need to create
4891 * it here beforehand.
4892 * In order to take care of potential keys we need to
4893 * do some extra work for the case when a Result Tree Fragment
4894 * is converted into a nodeset (e.g. exslt:node-set()) :
4895 * We attach a "pseudo-doc" (xsltDocument) to _private.
4896 * This xsltDocument, together with the keyset, will be freed
4897 * when the Result Tree Fragment is freed.
4898 *
4899 */
4900#if 0
4901 if ((ctxt->nbKeys > 0) &&
4902 (list->nodeNr != 0) &&
4903 (list->nodeTab[0]->doc != NULL) &&
4904 XSLT_IS_RES_TREE_FRAG(list->nodeTab[0]->doc))
4905 {
4906 /*
4907 * NOTE that it's also OK if @effectiveDocInfo will be
4908 * set to NULL.
4909 */
4910 isRTF = 1;
4911 effectiveDocInfo = list->nodeTab[0]->doc->_private;
4912 }
4913#endif
4914 } else {
4915 /*
4916 * Build an XPath node set with the children
4917 */
4918 list = xmlXPathNodeSetCreate(NULL);
4919 if (list == NULL)
4920 goto error;
4921 if (node->type != XML_NAMESPACE_DECL)
4922 cur = node->children;
4923 else
4924 cur = NULL;
4925 while (cur != NULL) {
4927 xmlXPathNodeSetAddUnique(list, cur);
4928 cur = cur->next;
4929 }
4930 }
4931
4932#ifdef WITH_XSLT_DEBUG_PROCESS
4933 if (list != NULL)
4935 "xsltApplyTemplates: list of %d nodes\n", list->nodeNr));
4936#endif
4937
4938 if ((list == NULL) || (list->nodeNr == 0))
4939 goto exit;
4940
4941 /*
4942 * Set the context's node set and size; this is also needed for
4943 * for xsltDoSortFunction().
4944 */
4945 ctxt->nodeList = list;
4946 /*
4947 * Process xsl:with-param and xsl:sort instructions.
4948 * (The code became so verbose just to avoid the
4949 * xmlNodePtr sorts[XSLT_MAX_SORT] if there's no xsl:sort)
4950 * BUG TODO: We are not using namespaced potentially defined on the
4951 * xsl:sort or xsl:with-param elements; XPath expression might fail.
4952 */
4953 if (inst->children) {
4955
4956 cur = inst->children;
4957 while (cur) {
4958
4959#ifdef WITH_DEBUGGER
4960 if (ctxt->debugStatus != XSLT_DEBUG_NONE)
4961 xslHandleDebugger(cur, node, NULL, ctxt);
4962#endif
4963 if (ctxt->state == XSLT_STATE_STOPPED)
4964 break;
4965 if (cur->type == XML_TEXT_NODE) {
4966 cur = cur->next;
4967 continue;
4968 }
4969 if (! IS_XSLT_ELEM(cur))
4970 break;
4971 if (IS_XSLT_NAME(cur, "with-param")) {
4973 if (param != NULL) {
4974 param->next = withParams;
4975 withParams = param;
4976 }
4977 }
4978 if (IS_XSLT_NAME(cur, "sort")) {
4979 xsltTemplatePtr oldCurTempRule =
4980 ctxt->currentTemplateRule;
4981 int nbsorts = 0;
4983
4984 sorts[nbsorts++] = cur;
4985 cur = cur->next;
4986
4987 while (cur) {
4988
4989#ifdef WITH_DEBUGGER
4990 if (ctxt->debugStatus != XSLT_DEBUG_NONE)
4991 xslHandleDebugger(cur, node, NULL, ctxt);
4992#endif
4993 if (ctxt->state == XSLT_STATE_STOPPED)
4994 break;
4995
4996 if (cur->type == XML_TEXT_NODE) {
4997 cur = cur->next;
4998 continue;
4999 }
5000
5001 if (! IS_XSLT_ELEM(cur))
5002 break;
5003 if (IS_XSLT_NAME(cur, "with-param")) {
5005 if (param != NULL) {
5006 param->next = withParams;
5007 withParams = param;
5008 }
5009 }
5010 if (IS_XSLT_NAME(cur, "sort")) {
5011 if (nbsorts >= XSLT_MAX_SORT) {
5013 "The number (%d) of xsl:sort instructions exceeds the "
5014 "maximum allowed by this processor's settings.\n",
5015 nbsorts);
5016 ctxt->state = XSLT_STATE_STOPPED;
5017 break;
5018 } else {
5019 sorts[nbsorts++] = cur;
5020 }
5021 }
5022 cur = cur->next;
5023 }
5024 /*
5025 * The "current template rule" is cleared for xsl:sort.
5026 */
5027 ctxt->currentTemplateRule = NULL;
5028 /*
5029 * Sort.
5030 */
5031 xsltDoSortFunction(ctxt, sorts, nbsorts);
5032 ctxt->currentTemplateRule = oldCurTempRule;
5033 break;
5034 }
5035 cur = cur->next;
5036 }
5037 }
5038 xpctxt->contextSize = list->nodeNr;
5039 /*
5040 * Apply templates for all selected source nodes.
5041 */
5042 for (i = 0; i < list->nodeNr; i++) {
5043 cur = list->nodeTab[i];
5044 /*
5045 * The node becomes the "current node".
5046 */
5047 ctxt->node = cur;
5048 /*
5049 * An xsl:apply-templates can change the current context doc.
5050 * OPTIMIZE TODO: Get rid of the need to set the context doc.
5051 */
5052 if ((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL))
5053 xpctxt->doc = cur->doc;
5054
5055 xpctxt->proximityPosition = i + 1;
5056 /*
5057 * Find and apply a template for this node.
5058 */
5059 xsltProcessOneNode(ctxt, cur, withParams);
5060 }
5061
5062exit:
5063error:
5064 /*
5065 * Free the parameter list.
5066 */
5067 if (withParams != NULL)
5068 xsltFreeStackElemList(withParams);
5069 if (list != NULL)
5070 xmlXPathFreeNodeSet(list);
5071 /*
5072 * Restore context states.
5073 */
5074 xpctxt->doc = oldXPDoc;
5075 xpctxt->contextSize = oldXPContextSize;
5076 xpctxt->proximityPosition = oldXPProximityPosition;
5077
5078 ctxt->document = oldDocInfo;
5079 ctxt->nodeList = oldList;
5080 ctxt->node = oldContextNode;
5081 ctxt->mode = oldMode;
5082 ctxt->modeURI = oldModeURI;
5083}
static xmlXPathObjectPtr xsltPreCompEval(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStylePreCompPtr comp)
Definition: transform.c:321
GLfloat param
Definition: glext.h:5796
@ XML_NAMESPACE_DECL
Definition: tree.h:177
#define exit(n)
Definition: config.h:202
struct _xmlDoc * doc
Definition: tree.h:560
xsltDocumentPtr document
xsltStackElemPtr xsltParseStylesheetCallerParam(xsltTransformContextPtr ctxt, xmlNodePtr inst)
Definition: variables.c:1962
#define XSLT_MAX_SORT
#define XSLT_IS_RES_TREE_FRAG(n)
Definition: xsltInternals.h:56
void xsltDoSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts)
Definition: xsltutils.c:1369
@ XSLT_TRACE_APPLY_TEMPLATES
Definition: xsltutils.h:110

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltApplyXSLTTemplate()

static void xsltApplyXSLTTemplate ( xsltTransformContextPtr  ctxt,
xmlNodePtr  contextNode,
xmlNodePtr  list,
xsltTemplatePtr  templ,
xsltStackElemPtr  withParams 
)
static

Definition at line 3026 of file transform.c.

3031{
3032 int oldVarsBase = 0;
3034 xsltStackElemPtr tmpParam = NULL;
3035 xmlDocPtr oldUserFragmentTop;
3036#ifdef WITH_PROFILER
3037 long start = 0;
3038#endif
3039
3040#ifdef XSLT_REFACTORED
3041 xsltStyleItemParamPtr iparam;
3042#else
3043 xsltStylePreCompPtr iparam;
3044#endif
3045
3046#ifdef WITH_DEBUGGER
3047 int addCallResult = 0;
3048#endif
3049
3050 if (ctxt == NULL)
3051 return;
3052 if (templ == NULL) {
3054 "xsltApplyXSLTTemplate: Bad arguments; @templ is mandatory.\n");
3055 return;
3056 }
3057
3058#ifdef WITH_DEBUGGER
3059 if (ctxt->debugStatus != XSLT_DEBUG_NONE) {
3060 if (xsltDebuggerStartSequenceConstructor(ctxt, contextNode,
3061 list, templ, &addCallResult) == NULL)
3062 return;
3063 }
3064#endif
3065
3066 if (list == NULL)
3067 return;
3069
3070 if (ctxt->varsNr >= ctxt->maxTemplateVars)
3071 {
3073 "xsltApplyXSLTTemplate: A potential infinite template recursion "
3074 "was detected.\n"
3075 "You can adjust maxTemplateVars (--maxvars) in order to "
3076 "raise the maximum number of variables/params (currently set to %d).\n",
3077 ctxt->maxTemplateVars);
3078 xsltDebug(ctxt, contextNode, list, NULL);
3079 ctxt->state = XSLT_STATE_STOPPED;
3080 return;
3081 }
3082
3083 oldUserFragmentTop = ctxt->tmpRVT;
3084 ctxt->tmpRVT = NULL;
3085
3086 /*
3087 * Initiate a distinct scope of local params/variables.
3088 */
3089 oldVarsBase = ctxt->varsBase;
3090 ctxt->varsBase = ctxt->varsNr;
3091
3092 ctxt->node = contextNode;
3093
3094#ifdef WITH_PROFILER
3095 if (ctxt->profile) {
3096 templ->nbCalls++;
3097 start = xsltTimestamp();
3098 profPush(ctxt, 0);
3099 profCallgraphAdd(templ, ctxt->templ);
3100 }
3101#endif
3102
3103 /*
3104 * Push the xsl:template declaration onto the stack.
3105 */
3106 templPush(ctxt, templ);
3107
3108#ifdef WITH_XSLT_DEBUG_PROCESS
3109 if (templ->name != NULL)
3111 "applying xsl:template '%s'\n", templ->name));
3112#endif
3113 /*
3114 * Process xsl:param instructions and skip those elements for
3115 * further processing.
3116 */
3117 cur = list;
3118 do {
3119 if (cur->type == XML_TEXT_NODE) {
3120 cur = cur->next;
3121 continue;
3122 }
3123 if ((cur->type != XML_ELEMENT_NODE) ||
3124 (cur->name[0] != 'p') ||
3125 (cur->psvi == NULL) ||
3126 (! xmlStrEqual(cur->name, BAD_CAST "param")) ||
3127 (! IS_XSLT_ELEM(cur)))
3128 {
3129 break;
3130 }
3131
3132 list = cur->next;
3133
3134#ifdef XSLT_REFACTORED
3135 iparam = (xsltStyleItemParamPtr) cur->psvi;
3136#else
3137 iparam = (xsltStylePreCompPtr) cur->psvi;
3138#endif
3139
3140 /*
3141 * Substitute xsl:param for a given xsl:with-param.
3142 * Since the XPath expression will reference the params/vars
3143 * by index, we need to slot the xsl:with-params in the
3144 * order of encountered xsl:params to keep the sequence of
3145 * params/variables in the stack exactly as it was at
3146 * compile time,
3147 */
3148 tmpParam = NULL;
3149 if (withParams) {
3150 tmpParam = withParams;
3151 do {
3152 if ((tmpParam->name == (iparam->name)) &&
3153 (tmpParam->nameURI == (iparam->ns)))
3154 {
3155 /*
3156 * Push the caller-parameter.
3157 */
3158 xsltLocalVariablePush(ctxt, tmpParam, -1);
3159 break;
3160 }
3161 tmpParam = tmpParam->next;
3162 } while (tmpParam != NULL);
3163 }
3164 /*
3165 * Push the xsl:param.
3166 */
3167 if (tmpParam == NULL) {
3168 /*
3169 * Note that we must assume that the added parameter
3170 * has a @depth of 0.
3171 */
3173 }
3174 cur = cur->next;
3175 } while (cur != NULL);
3176 /*
3177 * Process the sequence constructor.
3178 */
3179 xsltApplySequenceConstructor(ctxt, contextNode, list, templ);
3180
3181 /*
3182 * Remove remaining xsl:param and xsl:with-param items from
3183 * the stack. Don't free xsl:with-param items.
3184 */
3185 if (ctxt->varsNr > ctxt->varsBase)
3187 ctxt->varsBase = oldVarsBase;
3188
3189 /*
3190 * Release user-created fragments stored in the scope
3191 * of xsl:template. Note that this mechanism is deprecated:
3192 * user code should now use xsltRegisterLocalRVT() instead
3193 * of the obsolete xsltRegisterTmpRVT().
3194 */
3195 if (ctxt->tmpRVT) {
3196 xmlDocPtr curdoc = ctxt->tmpRVT, tmp;
3197
3198 while (curdoc != NULL) {
3199 tmp = curdoc;
3200 curdoc = (xmlDocPtr) curdoc->next;
3201 xsltReleaseRVT(ctxt, tmp);
3202 }
3203 }
3204 ctxt->tmpRVT = oldUserFragmentTop;
3205
3206 /*
3207 * Pop the xsl:template declaration from the stack.
3208 */
3209 templPop(ctxt);
3210
3211#ifdef WITH_PROFILER
3212 if (ctxt->profile) {
3213 long spent, child, total, end;
3214
3215 end = xsltTimestamp();
3216 child = profPop(ctxt);
3217 total = end - start;
3218 spent = total - child;
3219 if (spent <= 0) {
3220 /*
3221 * Not possible unless the original calibration failed
3222 * we can try to correct it on the fly.
3223 */
3224 xsltCalibrateAdjust(spent);
3225 spent = 0;
3226 }
3227
3228 templ->time += spent;
3229 if (ctxt->profNr > 0)
3230 ctxt->profTab[ctxt->profNr - 1] += total;
3231 }
3232#endif
3233
3234#ifdef WITH_DEBUGGER
3235 if ((ctxt->debugStatus != XSLT_DEBUG_NONE) && (addCallResult)) {
3236 xslDropCall();
3237 }
3238#endif
3239}
static xsltTemplatePtr templPop(xsltTransformContextPtr ctxt)
Definition: transform.c:121
static void xsltTemplateParamsCleanup(xsltTransformContextPtr ctxt)
Definition: transform.c:180
static int templPush(xsltTransformContextPtr ctxt, xsltTemplatePtr value)
Definition: transform.c:85
size_t total
GLuint start
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
xmlDoc * xmlDocPtr
Definition: tree.h:550
struct _xmlNode * next
Definition: tree.h:558
const xmlChar * nameURI
const xmlChar * name
const xmlChar * name
unsigned long time
void xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur)
Definition: variables.c:2191
void xsltReleaseRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
Definition: variables.c:328
XSLTPUBFUN void XSLTCALL xsltCalibrateAdjust(long delta)
XSLTPUBFUN long XSLTCALL xsltTimestamp(void)

Referenced by xsltApplyImports(), xsltCallTemplate(), xsltDefaultProcessOneNode(), and xsltProcessOneNode().

◆ xsltCallTemplate()

void xsltCallTemplate ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltCallTemplate: @ctxt: a XSLT transformation context @node: the "current node" in the source tree @inst: the XSLT 'call-template' instruction @castedComp: the compiled information of the instruction

Processes the XSLT call-template instruction on the source node.

Definition at line 4679 of file transform.c.

4681{
4682#ifdef XSLT_REFACTORED
4683 xsltStyleItemCallTemplatePtr comp =
4684 (xsltStyleItemCallTemplatePtr) castedComp;
4685#else
4686 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
4687#endif
4688 xsltStackElemPtr withParams = NULL;
4689
4690 if (ctxt->insert == NULL)
4691 return;
4692 if (comp == NULL) {
4693 xsltTransformError(ctxt, NULL, inst,
4694 "The XSLT 'call-template' instruction was not compiled.\n");
4695 return;
4696 }
4697
4698 /*
4699 * The template must have been precomputed
4700 */
4701 if (comp->templ == NULL) {
4702 comp->templ = xsltFindTemplate(ctxt, comp->name, comp->ns);
4703 if (comp->templ == NULL) {
4704 if (comp->ns != NULL) {
4705 xsltTransformError(ctxt, NULL, inst,
4706 "The called template '{%s}%s' was not found.\n",
4707 comp->ns, comp->name);
4708 } else {
4709 xsltTransformError(ctxt, NULL, inst,
4710 "The called template '%s' was not found.\n",
4711 comp->name);
4712 }
4713 return;
4714 }
4715 }
4716
4717#ifdef WITH_XSLT_DEBUG_PROCESS
4718 if ((comp != NULL) && (comp->name != NULL))
4720 "call-template: name %s\n", comp->name));
4721#endif
4722
4723 if (inst->children) {
4726
4727 cur = inst->children;
4728 while (cur != NULL) {
4729#ifdef WITH_DEBUGGER
4730 if (ctxt->debugStatus != XSLT_DEBUG_NONE)
4731 xslHandleDebugger(cur, node, comp->templ, ctxt);
4732#endif
4733 if (ctxt->state == XSLT_STATE_STOPPED) break;
4734 /*
4735 * TODO: The "with-param"s could be part of the "call-template"
4736 * structure. Avoid to "search" for params dynamically
4737 * in the XML tree every time.
4738 */
4739 if (IS_XSLT_ELEM(cur)) {
4740 if (IS_XSLT_NAME(cur, "with-param")) {
4742 if (param != NULL) {
4743 param->next = withParams;
4744 withParams = param;
4745 }
4746 } else {
4748 "xsl:call-template: misplaced xsl:%s\n", cur->name);
4749 }
4750 } else {
4752 "xsl:call-template: misplaced %s element\n", cur->name);
4753 }
4754 cur = cur->next;
4755 }
4756 }
4757 /*
4758 * Create a new frame using the params first
4759 */
4760 xsltApplyXSLTTemplate(ctxt, node, comp->templ->content, comp->templ,
4761 withParams);
4762 if (withParams != NULL)
4763 xsltFreeStackElemList(withParams);
4764
4765#ifdef WITH_XSLT_DEBUG_PROCESS
4766 if ((comp != NULL) && (comp->name != NULL))
4768 "call-template returned: name %s\n", comp->name));
4769#endif
4770}
xsltTemplatePtr xsltFindTemplate(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI)
Definition: imports.c:357
char * name
Definition: compiler.c:66
@ XSLT_TRACE_CALL_TEMPLATE
Definition: xsltutils.h:109

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltChoose()

void xsltChoose ( xsltTransformContextPtr  ctxt,
xmlNodePtr  contextNode,
xmlNodePtr  inst,
xsltElemPreCompPtr comp  ATTRIBUTE_UNUSED 
)

xsltChoose: @ctxt: a XSLT process context @contextNode: the current node in the source tree @inst: the xsl:choose instruction @comp: compiled information of the instruction

Processes the xsl:choose instruction on the source node.

Definition at line 5096 of file transform.c.

5098{
5100
5101 if ((ctxt == NULL) || (contextNode == NULL) || (inst == NULL))
5102 return;
5103
5104 /*
5105 * TODO: Content model checks should be done only at compilation
5106 * time.
5107 */
5108 cur = inst->children;
5109 if (cur == NULL) {
5110 xsltTransformError(ctxt, NULL, inst,
5111 "xsl:choose: The instruction has no content.\n");
5112 return;
5113 }
5114
5115#ifdef XSLT_REFACTORED
5116 /*
5117 * We don't check the content model during transformation.
5118 */
5119#else
5120 if ((! IS_XSLT_ELEM(cur)) || (! IS_XSLT_NAME(cur, "when"))) {
5121 xsltTransformError(ctxt, NULL, inst,
5122 "xsl:choose: xsl:when expected first\n");
5123 return;
5124 }
5125#endif
5126
5127 {
5128 int testRes = 0, res = 0;
5129
5130#ifdef XSLT_REFACTORED
5131 xsltStyleItemWhenPtr wcomp = NULL;
5132#else
5133 xsltStylePreCompPtr wcomp = NULL;
5134#endif
5135
5136 /*
5137 * Process xsl:when ---------------------------------------------------
5138 */
5139 while (IS_XSLT_ELEM(cur) && IS_XSLT_NAME(cur, "when")) {
5140 wcomp = cur->psvi;
5141
5142 if ((wcomp == NULL) || (wcomp->test == NULL) ||
5143 (wcomp->comp == NULL))
5144 {
5146 "Internal error in xsltChoose(): "
5147 "The XSLT 'when' instruction was not compiled.\n");
5148 goto error;
5149 }
5150
5151
5152#ifdef WITH_DEBUGGER
5154 /*
5155 * TODO: Isn't comp->templ always NULL for xsl:choose?
5156 */
5157 xslHandleDebugger(cur, contextNode, NULL, ctxt);
5158 }
5159#endif
5160#ifdef WITH_XSLT_DEBUG_PROCESS
5162 "xsltChoose: test %s\n", wcomp->test));
5163#endif
5164
5165#ifdef XSLT_FAST_IF
5166 res = xsltPreCompEvalToBoolean(ctxt, contextNode, wcomp);
5167
5168 if (res == -1) {
5169 ctxt->state = XSLT_STATE_STOPPED;
5170 goto error;
5171 }
5172 testRes = (res == 1) ? 1 : 0;
5173
5174#else /* XSLT_FAST_IF */
5175
5176 res = xsltPreCompEval(ctxt, cotextNode, wcomp);
5177
5178 if (res != NULL) {
5179 if (res->type != XPATH_BOOLEAN)
5180 res = xmlXPathConvertBoolean(res);
5181 if (res->type == XPATH_BOOLEAN)
5182 testRes = res->boolval;
5183 else {
5184#ifdef WITH_XSLT_DEBUG_PROCESS
5186 "xsltChoose: test didn't evaluate to a boolean\n"));
5187#endif
5188 goto error;
5189 }
5190 xmlXPathFreeObject(res);
5191 res = NULL;
5192 } else {
5193 ctxt->state = XSLT_STATE_STOPPED;
5194 goto error;
5195 }
5196
5197#endif /* else of XSLT_FAST_IF */
5198
5199#ifdef WITH_XSLT_DEBUG_PROCESS
5201 "xsltChoose: test evaluate to %d\n", testRes));
5202#endif
5203 if (testRes)
5204 goto test_is_true;
5205
5206 cur = cur->next;
5207 }
5208
5209 /*
5210 * Process xsl:otherwise ----------------------------------------------
5211 */
5212 if (IS_XSLT_ELEM(cur) && IS_XSLT_NAME(cur, "otherwise")) {
5213
5214#ifdef WITH_DEBUGGER
5216 xslHandleDebugger(cur, contextNode, NULL, ctxt);
5217#endif
5218
5219#ifdef WITH_XSLT_DEBUG_PROCESS
5221 "evaluating xsl:otherwise\n"));
5222#endif
5223 goto test_is_true;
5224 }
5225 goto exit;
5226
5227test_is_true:
5228
5229 goto process_sequence;
5230 }
5231
5232process_sequence:
5233
5234 /*
5235 * Instantiate the sequence constructor.
5236 */
5237 xsltApplySequenceConstructor(ctxt, ctxt->node, cur->children,
5238 NULL);
5239
5240exit:
5241error:
5242 return;
5243}
static int xsltPreCompEvalToBoolean(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStylePreCompPtr comp)
Definition: transform.c:370
@ XSLT_TRACE_CHOOSE
Definition: xsltutils.h:111

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltComment()

void xsltComment ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr comp  ATTRIBUTE_UNUSED 
)

xsltComment: @ctxt: a XSLT process context @node: the node in the source tree. @inst: the xslt comment node @comp: precomputed information

Process the xslt comment node on the source node

Definition at line 4225 of file transform.c.

4226 {
4227 xmlChar *value = NULL;
4228 xmlNodePtr commentNode;
4229 int len;
4230
4231 value = xsltEvalTemplateString(ctxt, node, inst);
4232 /* TODO: use or generate the compiled form */
4233 len = xmlStrlen(value);
4234 if (len > 0) {
4235 if ((value[len-1] == '-') ||
4236 (xmlStrstr(value, BAD_CAST "--"))) {
4237 xsltTransformError(ctxt, NULL, inst,
4238 "xsl:comment : '--' or ending '-' not allowed in comment\n");
4239 /* fall through to try to catch further errors */
4240 }
4241 }
4242#ifdef WITH_XSLT_DEBUG_PROCESS
4243 if (value == NULL) {
4245 "xsltComment: empty\n"));
4246 } else {
4248 "xsltComment: content %s\n", value));
4249 }
4250#endif
4251
4252 commentNode = xmlNewComment(value);
4253 commentNode = xsltAddChild(ctxt->insert, commentNode);
4254
4255 if (value != NULL)
4256 xmlFree(value);
4257}
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBFUN xmlNodePtr XMLCALL xmlNewComment(const xmlChar *content)
xmlChar * xsltEvalTemplateString(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst)
Definition: templates.c:189
XMLPUBFUN const xmlChar *XMLCALL xmlStrstr(const xmlChar *str, const xmlChar *val)
Definition: xmlstring.c:345
@ XSLT_TRACE_COMMENT
Definition: xsltutils.h:105

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltCopy()

void xsltCopy ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltCopy: @ctxt: an XSLT process context @node: the node in the source tree @inst: the element node of the XSLT-copy instruction @castedComp: computed information of the XSLT-copy instruction

Execute the XSLT-copy instruction on the source node.

Definition at line 3861 of file transform.c.

3863{
3864#ifdef XSLT_REFACTORED
3865 xsltStyleItemCopyPtr comp = (xsltStyleItemCopyPtr) castedComp;
3866#else
3867 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
3868#endif
3869 xmlNodePtr copy, oldInsert;
3870
3871 oldInsert = ctxt->insert;
3872 if (ctxt->insert != NULL) {
3873 switch (node->type) {
3874 case XML_TEXT_NODE:
3876 /*
3877 * This text comes from the stylesheet
3878 * For stylesheets, the set of whitespace-preserving
3879 * element names consists of just xsl:text.
3880 */
3881#ifdef WITH_XSLT_DEBUG_PROCESS
3882 if (node->type == XML_CDATA_SECTION_NODE) {
3884 "xsltCopy: CDATA text %s\n", node->content));
3885 } else {
3887 "xsltCopy: text %s\n", node->content));
3888 }
3889#endif
3890 xsltCopyText(ctxt, ctxt->insert, node, 0);
3891 break;
3892 case XML_DOCUMENT_NODE:
3894 break;
3895 case XML_ELEMENT_NODE:
3896 /*
3897 * REVISIT NOTE: The "fake" is a doc-node, not an element node.
3898 * REMOVED:
3899 * if (xmlStrEqual(node->name, BAD_CAST " fake node libxslt"))
3900 * return;
3901 */
3902
3903#ifdef WITH_XSLT_DEBUG_PROCESS
3905 "xsltCopy: node %s\n", node->name));
3906#endif
3907 copy = xsltShallowCopyElem(ctxt, node, ctxt->insert, 0);
3908 ctxt->insert = copy;
3909 if (comp->use != NULL) {
3910 xsltApplyAttributeSet(ctxt, node, inst, comp->use);
3911 }
3912 break;
3913 case XML_ATTRIBUTE_NODE: {
3914#ifdef WITH_XSLT_DEBUG_PROCESS
3916 "xsltCopy: attribute %s\n", node->name));
3917#endif
3918 /*
3919 * REVISIT: We could also raise an error if the parent is not
3920 * an element node.
3921 * OPTIMIZE TODO: Can we set the value/children of the
3922 * attribute without an intermediate copy of the string value?
3923 */
3924 xsltShallowCopyAttr(ctxt, inst, ctxt->insert, (xmlAttrPtr) node);
3925 break;
3926 }
3927 case XML_PI_NODE:
3928#ifdef WITH_XSLT_DEBUG_PROCESS
3930 "xsltCopy: PI %s\n", node->name));
3931#endif
3932 copy = xmlNewDocPI(ctxt->insert->doc, node->name,
3933 node->content);
3934 copy = xsltAddChild(ctxt->insert, copy);
3935 break;
3936 case XML_COMMENT_NODE:
3937#ifdef WITH_XSLT_DEBUG_PROCESS
3939 "xsltCopy: comment\n"));
3940#endif
3941 copy = xmlNewComment(node->content);
3942 copy = xsltAddChild(ctxt->insert, copy);
3943 break;
3944 case XML_NAMESPACE_DECL:
3945#ifdef WITH_XSLT_DEBUG_PROCESS
3947 "xsltCopy: namespace declaration\n"));
3948#endif
3949 xsltShallowCopyNsNode(ctxt, inst, ctxt->insert, (xmlNsPtr)node);
3950 break;
3951 default:
3952 break;
3953
3954 }
3955 }
3956
3957 switch (node->type) {
3958 case XML_DOCUMENT_NODE:
3960 case XML_ELEMENT_NODE:
3961 xsltApplySequenceConstructor(ctxt, ctxt->node, inst->children,
3962 NULL);
3963 break;
3964 default:
3965 break;
3966 }
3967 ctxt->insert = oldInsert;
3968}
void xsltApplyAttributeSet(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, const xmlChar *attrSets)
Definition: attributes.c:1086
static xmlAttrPtr xsltShallowCopyAttr(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr target, xmlAttrPtr attr)
Definition: transform.c:1121
static xmlNsPtr xsltShallowCopyNsNode(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr insert, xmlNsPtr ns)
Definition: transform.c:1481
@ XML_ATTRIBUTE_NODE
Definition: tree.h:161
@ XML_DOCUMENT_NODE
Definition: tree.h:168
@ XML_PI_NODE
Definition: tree.h:166
@ XML_COMMENT_NODE
Definition: tree.h:167
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocPI(xmlDocPtr doc, const xmlChar *name, const xmlChar *content)
Definition: tree.h:434
struct _xmlDoc * doc
Definition: tree.h:498
@ XSLT_TRACE_COPY
Definition: xsltutils.h:104

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltCopyAttrListNoOverwrite()

static int xsltCopyAttrListNoOverwrite ( xsltTransformContextPtr  ctxt,
xmlNodePtr  invocNode,
xmlNodePtr  target,
xmlAttrPtr  attr 
)
static

xsltCopyAttrListNoOverwrite: @ctxt: a XSLT process context @invocNode: responsible node in the stylesheet; used for error reports @target: the element where the new attributes will be grafted @attr: the first attribute in the list to be copied

Copies a list of attribute nodes, starting with @attr, over to the @target element node.

Called by:

Returns 0 on success and -1 on errors and internal errors.

Definition at line 1220 of file transform.c.

1223{
1225 xmlNsPtr origNs = NULL, copyNs = NULL;
1226 xmlChar *value;
1227
1228 /*
1229 * Don't use xmlCopyProp() here, since it will try to
1230 * reconciliate namespaces.
1231 */
1232 while (attr != NULL) {
1233 /*
1234 * Find a namespace node in the tree of @target.
1235 * Avoid searching for the same ns.
1236 */
1237 if (attr->ns != origNs) {
1238 origNs = attr->ns;
1239 if (attr->ns != NULL) {
1240 copyNs = xsltGetSpecialNamespace(ctxt, invocNode,
1241 attr->ns->href, attr->ns->prefix, target);
1242 if (copyNs == NULL)
1243 return(-1);
1244 } else
1245 copyNs = NULL;
1246 }
1247 /*
1248 * If attribute has a value, we need to copy it (watching out
1249 * for possible entities)
1250 */
1251 if ((attr->children) && (attr->children->type == XML_TEXT_NODE) &&
1252 (attr->children->next == NULL)) {
1253 copy = xmlNewNsProp(target, copyNs, attr->name,
1254 attr->children->content);
1255 } else if (attr->children != NULL) {
1256 value = xmlNodeListGetString(attr->doc, attr->children, 1);
1258 xmlFree(value);
1259 } else {
1260 copy = xmlNewNsProp(target, copyNs, attr->name, NULL);
1261 }
1262
1263 if (copy == NULL)
1264 return(-1);
1265
1266 attr = attr->next;
1267 }
1268 return(0);
1269}
XMLPUBFUN xmlAttrPtr XMLCALL xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, const xmlChar *value)
XMLPUBFUN xmlChar *XMLCALL xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
Definition: cookie.c:202
WCHAR * name
Definition: cookie.c:203

Referenced by xsltCopyTree().

◆ xsltCopyNamespaceListInternal()

static xmlNsPtr xsltCopyNamespaceListInternal ( xmlNodePtr  elem,
xmlNsPtr  ns 
)
static

xsltCopyNamespaceListInternal: @node: the target node @cur: the first namespace

Do a copy of a namespace list. If @node is non-NULL the new namespaces are added automatically. Called by: xsltCopyTree()

QUESTION: What is the exact difference between this function and xsltCopyNamespaceList() in "namespaces.c"? ANSWER: xsltCopyNamespaceList() tries to apply ns-aliases.

Returns: a new xmlNsPtr, or NULL in case of error.

Definition at line 1424 of file transform.c.

1424 {
1425 xmlNsPtr ret = NULL;
1426 xmlNsPtr p = NULL, q, luNs;
1427
1428 if (ns == NULL)
1429 return(NULL);
1430 /*
1431 * One can add namespaces only on element nodes
1432 */
1433 if ((elem != NULL) && (elem->type != XML_ELEMENT_NODE))
1434 elem = NULL;
1435
1436 do {
1437 if (ns->type != XML_NAMESPACE_DECL)
1438 break;
1439 /*
1440 * Avoid duplicating namespace declarations on the tree.
1441 */
1442 if (elem != NULL) {
1443 if ((elem->ns != NULL) &&
1444 xmlStrEqual(elem->ns->prefix, ns->prefix) &&
1445 xmlStrEqual(elem->ns->href, ns->href))
1446 {
1447 ns = ns->next;
1448 continue;
1449 }
1450 luNs = xmlSearchNs(elem->doc, elem, ns->prefix);
1451 if ((luNs != NULL) && (xmlStrEqual(luNs->href, ns->href)))
1452 {
1453 ns = ns->next;
1454 continue;
1455 }
1456 }
1457 q = xmlNewNs(elem, ns->href, ns->prefix);
1458 if (p == NULL) {
1459 ret = p = q;
1460 } else if (q != NULL) {
1461 p->next = q;
1462 p = q;
1463 }
1464 ns = ns->next;
1465 } while (ns != NULL);
1466 return(ret);
1467}
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLfloat GLfloat p
Definition: glext.h:8902
static size_t elem
Definition: string.c:68

Referenced by xsltCopyTree(), and xsltShallowCopyElem().

◆ xsltCopyOf()

void xsltCopyOf ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltCopyOf: @ctxt: an XSLT transformation context @node: the current node in the source tree @inst: the element node of the XSLT copy-of instruction @castedComp: precomputed information of the XSLT copy-of instruction

Process the XSLT copy-of instruction.

Definition at line 4335 of file transform.c.

4336 {
4337#ifdef XSLT_REFACTORED
4338 xsltStyleItemCopyOfPtr comp = (xsltStyleItemCopyOfPtr) castedComp;
4339#else
4340 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
4341#endif
4342 xmlXPathObjectPtr res = NULL;
4343 xmlNodeSetPtr list = NULL;
4344 int i;
4345
4346 if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
4347 return;
4348 if ((comp == NULL) || (comp->select == NULL) || (comp->comp == NULL)) {
4349 xsltTransformError(ctxt, NULL, inst,
4350 "xsl:copy-of : compilation failed\n");
4351 return;
4352 }
4353
4354 /*
4355 * SPEC XSLT 1.0:
4356 * "The xsl:copy-of element can be used to insert a result tree
4357 * fragment into the result tree, without first converting it to
4358 * a string as xsl:value-of does (see [7.6.1 Generating Text with
4359 * xsl:value-of]). The required select attribute contains an
4360 * expression. When the result of evaluating the expression is a
4361 * result tree fragment, the complete fragment is copied into the
4362 * result tree. When the result is a node-set, all the nodes in the
4363 * set are copied in document order into the result tree; copying
4364 * an element node copies the attribute nodes, namespace nodes and
4365 * children of the element node as well as the element node itself;
4366 * a root node is copied by copying its children. When the result
4367 * is neither a node-set nor a result tree fragment, the result is
4368 * converted to a string and then inserted into the result tree,
4369 * as with xsl:value-of.
4370 */
4371
4372#ifdef WITH_XSLT_DEBUG_PROCESS
4374 "xsltCopyOf: select %s\n", comp->select));
4375#endif
4376
4377 /*
4378 * Evaluate the "select" expression.
4379 */
4380 res = xsltPreCompEval(ctxt, node, comp);
4381
4382 if (res != NULL) {
4383 if (res->type == XPATH_NODESET) {
4384 /*
4385 * Node-set
4386 * --------
4387 */
4388#ifdef WITH_XSLT_DEBUG_PROCESS
4390 "xsltCopyOf: result is a node set\n"));
4391#endif
4392 list = res->nodesetval;
4393 if (list != NULL) {
4395 /*
4396 * The list is already sorted in document order by XPath.
4397 * Append everything in this order under ctxt->insert.
4398 */
4399 for (i = 0;i < list->nodeNr;i++) {
4400 cur = list->nodeTab[i];
4401 if (cur == NULL)
4402 continue;
4403 if ((cur->type == XML_DOCUMENT_NODE) ||
4404 (cur->type == XML_HTML_DOCUMENT_NODE))
4405 {
4406 xsltCopyTreeList(ctxt, inst,
4407 cur->children, ctxt->insert, 0, 0);
4408 } else if (cur->type == XML_ATTRIBUTE_NODE) {
4409 xsltShallowCopyAttr(ctxt, inst,
4410 ctxt->insert, (xmlAttrPtr) cur);
4411 } else {
4412 xsltCopyTree(ctxt, inst, cur, ctxt->insert, 0, 0);
4413 }
4414 }
4415 }
4416 } else if (res->type == XPATH_XSLT_TREE) {
4417 /*
4418 * Result tree fragment
4419 * --------------------
4420 * E.g. via <xsl:variable ...><foo/></xsl:variable>
4421 * Note that the root node of such trees is an xmlDocPtr in Libxslt.
4422 */
4423#ifdef WITH_XSLT_DEBUG_PROCESS
4425 "xsltCopyOf: result is a result tree fragment\n"));
4426#endif
4427 list = res->nodesetval;
4428 if ((list != NULL) && (list->nodeTab != NULL) &&
4429 (list->nodeTab[0] != NULL) &&
4430 (IS_XSLT_REAL_NODE(list->nodeTab[0])))
4431 {
4432 xsltCopyTreeList(ctxt, inst,
4433 list->nodeTab[0]->children, ctxt->insert, 0, 0);
4434 }
4435 } else {
4436 xmlChar *value = NULL;
4437 /*
4438 * Convert to a string.
4439 */
4440 value = xmlXPathCastToString(res);
4441 if (value == NULL) {
4442 xsltTransformError(ctxt, NULL, inst,
4443 "Internal error in xsltCopyOf(): "
4444 "failed to cast an XPath object to string.\n");
4445 ctxt->state = XSLT_STATE_STOPPED;
4446 } else {
4447 if (value[0] != 0) {
4448 /*
4449 * Append content as text node.
4450 */
4451 xsltCopyTextString(ctxt, ctxt->insert, value, 0);
4452 }
4453 xmlFree(value);
4454
4455#ifdef WITH_XSLT_DEBUG_PROCESS
4457 "xsltCopyOf: result %s\n", res->stringval));
4458#endif
4459 }
4460 }
4461 } else {
4462 ctxt->state = XSLT_STATE_STOPPED;
4463 }
4464
4465 if (res != NULL)
4466 xmlXPathFreeObject(res);
4467}
xmlNodePtr xsltCopyTextString(xsltTransformContextPtr ctxt, xmlNodePtr target, const xmlChar *string, int noescape)
Definition: transform.c:849
static xmlNodePtr xsltCopyTreeList(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr list, xmlNodePtr insert, int isLRE, int topElemVisited)
Definition: transform.c:1388
static xmlNodePtr xsltCopyTree(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr node, xmlNodePtr insert, int isLRE, int topElemVisited)
Definition: transform.c:1592
@ XSLT_TRACE_COPY_OF
Definition: xsltutils.h:107

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltCopyText()

static xmlNodePtr xsltCopyText ( xsltTransformContextPtr  ctxt,
xmlNodePtr  target,
xmlNodePtr  cur,
int  interned 
)
static

xsltCopyText: @ctxt: a XSLT process context @target: the element where the text will be attached @cur: the text or CDATA node @interned: the string is in the target doc dictionary

Copy the text content of @cur and append it to @target's children.

Returns: the text node, where the text content of @cur is copied to. NULL in case of API or internal errors.

Definition at line 945 of file transform.c.

947{
949
950 if ((cur->type != XML_TEXT_NODE) &&
951 (cur->type != XML_CDATA_SECTION_NODE))
952 return(NULL);
953 if (cur->content == NULL)
954 return(NULL);
955
956#ifdef WITH_XSLT_DEBUG_PROCESS
957 if (cur->type == XML_CDATA_SECTION_NODE) {
959 "xsltCopyText: copy CDATA text %s\n",
960 cur->content));
961 } else if (cur->name == xmlStringTextNoenc) {
963 "xsltCopyText: copy unescaped text %s\n",
964 cur->content));
965 } else {
967 "xsltCopyText: copy text %s\n",
968 cur->content));
969 }
970#endif
971
972 /*
973 * Play save and reset the merging mechanism for every new
974 * target node.
975 */
976 if ((target == NULL) || (target->children == NULL)) {
977 ctxt->lasttext = NULL;
978 }
979
980 if ((ctxt->style->cdataSection != NULL) &&
981 (ctxt->type == XSLT_OUTPUT_XML) &&
982 (target != NULL) &&
983 (target->type == XML_ELEMENT_NODE) &&
984 (((target->ns == NULL) &&
986 target->name, NULL) != NULL)) ||
987 ((target->ns != NULL) &&
989 target->name, target->ns->href) != NULL))))
990 {
991 /*
992 * Process "cdata-section-elements".
993 */
994 /*
995 * OPTIMIZE TODO: xsltCopyText() is also used for attribute content.
996 */
997 /*
998 * TODO: Since this doesn't merge adjacent CDATA-section nodes,
999 * we'll get: <![CDATA[x]]><!CDATA[y]]>.
1000 * TODO: Reported in #321505.
1001 */
1002 if ((target->last != NULL) &&
1003 (target->last->type == XML_CDATA_SECTION_NODE))
1004 {
1005 /*
1006 * Append to existing CDATA-section node.
1007 */
1008 copy = xsltAddTextString(ctxt, target->last, cur->content,
1009 xmlStrlen(cur->content));
1010 goto exit;
1011 } else {
1012 unsigned int len;
1013
1014 len = xmlStrlen(cur->content);
1015 copy = xmlNewCDataBlock(ctxt->output, cur->content, len);
1016 if (copy == NULL)
1017 goto exit;
1018 ctxt->lasttext = copy->content;
1019 ctxt->lasttsize = len;
1020 ctxt->lasttuse = len;
1021 }
1022 } else if ((target != NULL) &&
1023 (target->last != NULL) &&
1024 /* both escaped or both non-escaped text-nodes */
1025 (((target->last->type == XML_TEXT_NODE) &&
1026 (target->last->name == cur->name)) ||
1027 /* non-escaped text nodes and CDATA-section nodes */
1028 (((target->last->type == XML_CDATA_SECTION_NODE) &&
1029 (cur->name == xmlStringTextNoenc)))))
1030 {
1031 /*
1032 * we are appending to an existing text node
1033 */
1034 copy = xsltAddTextString(ctxt, target->last, cur->content,
1035 xmlStrlen(cur->content));
1036 goto exit;
1037 } else if ((interned) && (target != NULL) &&
1038 (target->doc != NULL) &&
1039 (target->doc->dict == ctxt->dict))
1040 {
1041 /*
1042 * TODO: DO we want to use this also for "text" output?
1043 */
1044 copy = xmlNewTextLen(NULL, 0);
1045 if (copy == NULL)
1046 goto exit;
1047 if (cur->name == xmlStringTextNoenc)
1048 copy->name = xmlStringTextNoenc;
1049
1050 /*
1051 * Must confirm that content is in dict (bug 302821)
1052 * TODO: This check should be not needed for text coming
1053 * from the stylesheets
1054 */
1055 if (xmlDictOwns(ctxt->dict, cur->content))
1056 copy->content = cur->content;
1057 else {
1058 if ((copy->content = xmlStrdup(cur->content)) == NULL)
1059 return NULL;
1060 }
1061
1062 ctxt->lasttext = NULL;
1063 } else {
1064 /*
1065 * normal processing. keep counters to extend the text node
1066 * in xsltAddTextString if needed.
1067 */
1068 unsigned int len;
1069
1070 len = xmlStrlen(cur->content);
1071 copy = xmlNewTextLen(cur->content, len);
1072 if (copy == NULL)
1073 goto exit;
1074 if (cur->name == xmlStringTextNoenc)
1075 copy->name = xmlStringTextNoenc;
1076 ctxt->lasttext = copy->content;
1077 ctxt->lasttsize = len;
1078 ctxt->lasttuse = len;
1079 }
1080 if (copy != NULL) {
1081 if (target != NULL) {
1082 copy->doc = target->doc;
1083 /*
1084 * MAYBE TODO: Maybe we should reset the ctxt->lasttext here
1085 * to ensure that the optimized text-merging mechanism
1086 * won't interfere with normal node-merging in any case.
1087 */
1089 }
1090 } else {
1092 "xsltCopyText: text copy failed\n");
1093 }
1094
1095exit:
1096 if ((copy == NULL) || (copy->content == NULL)) {
1098 "Internal error in xsltCopyText(): "
1099 "Failed to copy the string.\n");
1100 ctxt->state = XSLT_STATE_STOPPED;
1101 }
1102 return(copy);
1103}
static xmlNodePtr xsltAddTextString(xsltTransformContextPtr ctxt, xmlNodePtr target, const xmlChar *string, int len)
Definition: transform.c:777
XMLPUBFUN int XMLCALL xmlDictOwns(xmlDictPtr dict, const xmlChar *str)
Definition: dict.c:1220
XMLPUBFUN void *XMLCALL xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2)
Definition: hash.c:476
XMLPUBFUN xmlNodePtr XMLCALL xmlNewTextLen(const xmlChar *content, int len)
XMLPUBFUN xmlNodePtr XMLCALL xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len)
xmlHashTablePtr cdataSection
@ XSLT_TRACE_COPY_TEXT
Definition: xsltutils.h:101

Referenced by xsltApplySequenceConstructor(), xsltCopy(), xsltDefaultProcessOneNode(), and xsltShallowCopyElem().

◆ xsltCopyTextString()

xmlNodePtr xsltCopyTextString ( xsltTransformContextPtr  ctxt,
xmlNodePtr  target,
const xmlChar string,
int  noescape 
)

xsltCopyTextString: @ctxt: a XSLT process context @target: the element where the text will be attached @string: the text string @noescape: should disable-escaping be activated for this text node.

Adds @string to a newly created or an existent text node child of @target.

Returns: the text node, where the text content of @cur is copied to. NULL in case of API or internal errors.

Definition at line 849 of file transform.c.

851{
853 int len;
854
855 if (string == NULL)
856 return(NULL);
857
858#ifdef WITH_XSLT_DEBUG_PROCESS
860 "xsltCopyTextString: copy text %s\n",
861 string));
862#endif
863
864 /*
865 * Play safe and reset the merging mechanism for every new
866 * target node.
867 */
868 if ((target == NULL) || (target->children == NULL)) {
869 ctxt->lasttext = NULL;
870 }
871
872 /* handle coalescing of text nodes here */
873 len = xmlStrlen(string);
874 if ((ctxt->type == XSLT_OUTPUT_XML) &&
875 (ctxt->style->cdataSection != NULL) &&
876 (target != NULL) &&
877 (target->type == XML_ELEMENT_NODE) &&
878 (((target->ns == NULL) &&
880 target->name, NULL) != NULL)) ||
881 ((target->ns != NULL) &&
883 target->name, target->ns->href) != NULL))))
884 {
885 /*
886 * Process "cdata-section-elements".
887 */
888 if ((target->last != NULL) &&
889 (target->last->type == XML_CDATA_SECTION_NODE))
890 {
891 return(xsltAddTextString(ctxt, target->last, string, len));
892 }
893 copy = xmlNewCDataBlock(ctxt->output, string, len);
894 } else if (noescape) {
895 /*
896 * Process "disable-output-escaping".
897 */
898 if ((target != NULL) && (target->last != NULL) &&
899 (target->last->type == XML_TEXT_NODE) &&
900 (target->last->name == xmlStringTextNoenc))
901 {
902 return(xsltAddTextString(ctxt, target->last, string, len));
903 }
904 copy = xmlNewTextLen(string, len);
905 if (copy != NULL)
906 copy->name = xmlStringTextNoenc;
907 } else {
908 /*
909 * Default processing.
910 */
911 if ((target != NULL) && (target->last != NULL) &&
912 (target->last->type == XML_TEXT_NODE) &&
913 (target->last->name == xmlStringText)) {
914 return(xsltAddTextString(ctxt, target->last, string, len));
915 }
916 copy = xmlNewTextLen(string, len);
917 }
918 if (copy != NULL && target != NULL)
920 if (copy != NULL) {
921 ctxt->lasttext = copy->content;
922 ctxt->lasttsize = len;
923 ctxt->lasttuse = len;
924 } else {
926 "xsltCopyTextString: text copy failed\n");
927 ctxt->lasttext = NULL;
928 }
929 return(copy);
930}
XMLPUBVAR const xmlChar xmlStringText[]

Referenced by xsltCopyOf(), xsltCopyTree(), xsltNumberFormat(), and xsltValueOf().

◆ xsltCopyTree()

static xmlNodePtr xsltCopyTree ( xsltTransformContextPtr  ctxt,
xmlNodePtr  invocNode,
xmlNodePtr  node,
xmlNodePtr  insert,
int  isLRE,
int  topElemVisited 
)
static

xsltCopyTree: @ctxt: the XSLT transformation context @invocNode: responsible node in the stylesheet; used for error reports @node: the element node in the source tree @insert: the parent in the result tree @isLRE: indicates if @node is a Literal Result Element @topElemVisited: indicates if a top-most element was already processed

Make a copy of the full tree under the element node @node and insert it as last child of @insert

NOTE: Not to be used for Literal Result Elements.

Used by:

Returns a pointer to the new tree, or NULL in case of error

Definition at line 1592 of file transform.c.

1595{
1597
1598 if (node == NULL)
1599 return(NULL);
1600 switch (node->type) {
1601 case XML_ELEMENT_NODE:
1603 case XML_ENTITY_NODE:
1604 case XML_PI_NODE:
1605 case XML_COMMENT_NODE:
1606 case XML_DOCUMENT_NODE:
1608#ifdef LIBXML_DOCB_ENABLED
1610#endif
1611 break;
1612 case XML_TEXT_NODE: {
1613 int noenc = (node->name == xmlStringTextNoenc);
1614 return(xsltCopyTextString(ctxt, insert, node->content, noenc));
1615 }
1617 return(xsltCopyTextString(ctxt, insert, node->content, 0));
1618 case XML_ATTRIBUTE_NODE:
1619 return((xmlNodePtr)
1620 xsltShallowCopyAttr(ctxt, invocNode, insert, (xmlAttrPtr) node));
1621 case XML_NAMESPACE_DECL:
1622 return((xmlNodePtr) xsltShallowCopyNsNode(ctxt, invocNode,
1623 insert, (xmlNsPtr) node));
1624
1627 case XML_NOTATION_NODE:
1628 case XML_DTD_NODE:
1629 case XML_ELEMENT_DECL:
1630 case XML_ATTRIBUTE_DECL:
1631 case XML_ENTITY_DECL:
1632 case XML_XINCLUDE_START:
1633 case XML_XINCLUDE_END:
1634 return(NULL);
1635 }
1637 if (node->children != NULL)
1638 copy = xsltCopyTreeList(ctxt, invocNode,
1639 node->children, insert, 0, 0);
1640 else
1641 copy = NULL;
1642 return(copy);
1643 }
1644 copy = xmlDocCopyNode(node, insert->doc, 0);
1645 if (copy != NULL) {
1646 copy->doc = ctxt->output;
1648 if (copy == NULL) {
1649 xsltTransformError(ctxt, NULL, invocNode,
1650 "xsltCopyTree: Copying of '%s' failed.\n", node->name);
1651 return (copy);
1652 }
1653 /*
1654 * The node may have been coalesced into another text node.
1655 */
1656 if (insert->last != copy)
1657 return(insert->last);
1658 copy->next = NULL;
1659
1660 if (node->type == XML_ELEMENT_NODE) {
1661 /*
1662 * Copy in-scope namespace nodes.
1663 *
1664 * REVISIT: Since we try to reuse existing in-scope ns-decls by
1665 * using xmlSearchNsByHref(), this will eventually change
1666 * the prefix of an original ns-binding; thus it might
1667 * break QNames in element/attribute content.
1668 * OPTIMIZE TODO: If we had a xmlNsPtr * on the transformation
1669 * context, plus a ns-lookup function, which writes directly
1670 * to a given list, then we wouldn't need to create/free the
1671 * nsList every time.
1672 */
1673 if ((topElemVisited == 0) &&
1674 (node->parent != NULL) &&
1675 (node->parent->type != XML_DOCUMENT_NODE) &&
1676 (node->parent->type != XML_HTML_DOCUMENT_NODE))
1677 {
1678 xmlNsPtr *nsList, *curns, ns;
1679
1680 /*
1681 * If this is a top-most element in a tree to be
1682 * copied, then we need to ensure that all in-scope
1683 * namespaces are copied over. For nodes deeper in the
1684 * tree, it is sufficient to reconcile only the ns-decls
1685 * (node->nsDef entries).
1686 */
1687
1688 nsList = xmlGetNsList(node->doc, node);
1689 if (nsList != NULL) {
1690 curns = nsList;
1691 do {
1692 /*
1693 * Search by prefix first in order to break as less
1694 * QNames in element/attribute content as possible.
1695 */
1696 ns = xmlSearchNs(insert->doc, insert,
1697 (*curns)->prefix);
1698
1699 if ((ns == NULL) ||
1700 (! xmlStrEqual(ns->href, (*curns)->href)))
1701 {
1702 ns = NULL;
1703 /*
1704 * Search by namespace name.
1705 * REVISIT TODO: Currently disabled.
1706 */
1707#if 0
1709 insert, (*curns)->href);
1710#endif
1711 }
1712 if (ns == NULL) {
1713 /*
1714 * Declare a new namespace on the copied element.
1715 */
1716 ns = xmlNewNs(copy, (*curns)->href,
1717 (*curns)->prefix);
1718 /* TODO: Handle errors */
1719 }
1720 if (node->ns == *curns) {
1721 /*
1722 * If this was the original's namespace then set
1723 * the generated counterpart on the copy.
1724 */
1725 copy->ns = ns;
1726 }
1727 curns++;
1728 } while (*curns != NULL);
1729 xmlFree(nsList);
1730 }
1731 } else if (node->nsDef != NULL) {
1732 /*
1733 * Copy over all namespace declaration attributes.
1734 */
1735 if (node->nsDef != NULL) {
1736 if (isLRE)
1737 xsltCopyNamespaceList(ctxt, copy, node->nsDef);
1738 else
1740 }
1741 }
1742 /*
1743 * Set the namespace.
1744 */
1745 if (node->ns != NULL) {
1746 if (copy->ns == NULL) {
1747 /*
1748 * This will map copy->ns to one of the newly created
1749 * in-scope ns-decls, OR create a new ns-decl on @copy.
1750 */
1751 copy->ns = xsltGetSpecialNamespace(ctxt, invocNode,
1752 node->ns->href, node->ns->prefix, copy);
1753 }
1754 } else if ((insert->type == XML_ELEMENT_NODE) &&
1755 (insert->ns != NULL))
1756 {
1757 /*
1758 * "Undeclare" the default namespace on @copy with xmlns="".
1759 */
1760 xsltGetSpecialNamespace(ctxt, invocNode, NULL, NULL, copy);
1761 }
1762 /*
1763 * Copy attribute nodes.
1764 */
1765 if (node->properties != NULL) {
1766 xsltCopyAttrListNoOverwrite(ctxt, invocNode,
1767 copy, node->properties);
1768 }
1769 if (topElemVisited == 0)
1770 topElemVisited = 1;
1771 }
1772 /*
1773 * Copy the subtree.
1774 */
1775 if (node->children != NULL) {
1776 xsltCopyTreeList(ctxt, invocNode,
1777 node->children, copy, isLRE, topElemVisited);
1778 }
1779 } else {
1780 xsltTransformError(ctxt, NULL, invocNode,
1781 "xsltCopyTree: Copying of '%s' failed.\n", node->name);
1782 }
1783 return(copy);
1784}
static xmlNsPtr xsltCopyNamespaceListInternal(xmlNodePtr node, xmlNsPtr cur)
Definition: transform.c:1424
static int xsltCopyAttrListNoOverwrite(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr target, xmlAttrPtr attr)
Definition: transform.c:1220
xmlNsPtr xsltCopyNamespaceList(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNsPtr cur)
Definition: namespaces.c:697
#define XML_DOCB_DOCUMENT_NODE
Definition: tree.h:184
@ XML_DOCUMENT_TYPE_NODE
Definition: tree.h:169
@ XML_XINCLUDE_START
Definition: tree.h:178
@ XML_ENTITY_NODE
Definition: tree.h:165
@ XML_XINCLUDE_END
Definition: tree.h:179
@ XML_DOCUMENT_FRAG_NODE
Definition: tree.h:170
@ XML_DTD_NODE
Definition: tree.h:173
@ XML_ELEMENT_DECL
Definition: tree.h:174
@ XML_NOTATION_NODE
Definition: tree.h:171
@ XML_ATTRIBUTE_DECL
Definition: tree.h:175
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar *href)
static int noenc
Definition: xmllint.c:111

Referenced by xsltCopyOf(), and xsltCopyTreeList().

◆ xsltCopyTreeList()

static xmlNodePtr xsltCopyTreeList ( xsltTransformContextPtr  ctxt,
xmlNodePtr  invocNode,
xmlNodePtr  list,
xmlNodePtr  insert,
int  isLRE,
int  topElemVisited 
)
static

xsltCopyTreeList: @ctxt: a XSLT process context @invocNode: responsible node in the stylesheet; used for error reports @list: the list of element nodes in the source tree. @insert: the parent in the result tree. @isLRE: is this a literal result element list @topElemVisited: indicates if a top-most element was already processed

Make a copy of the full list of tree @list and insert it as last children of @insert

NOTE: Not to be used for Literal Result Elements.

Used by:

Returns a pointer to the new list, or NULL in case of error

Definition at line 1388 of file transform.c.

1391{
1393
1394 while (list != NULL) {
1395 copy = xsltCopyTree(ctxt, invocNode,
1396 list, insert, isLRE, topElemVisited);
1397 if (copy != NULL) {
1398 if (ret == NULL) {
1399 ret = copy;
1400 }
1401 }
1402 list = list->next;
1403 }
1404 return(ret);
1405}
struct list * next
Definition: list.h:38

Referenced by xsltCopyOf(), and xsltCopyTree().

◆ xsltCountKeys()

static int xsltCountKeys ( xsltTransformContextPtr  ctxt)
static

Definition at line 5678 of file transform.c.

5679{
5681 xsltKeyDefPtr keyd;
5682
5683 if (ctxt == NULL)
5684 return(-1);
5685
5686 /*
5687 * Do we have those nastly templates with a key() in the match pattern?
5688 */
5689 ctxt->hasTemplKeyPatterns = 0;
5690 style = ctxt->style;
5691 while (style != NULL) {
5692 if (style->keyMatch != NULL) {
5693 ctxt->hasTemplKeyPatterns = 1;
5694 break;
5695 }
5697 }
5698 /*
5699 * Count number of key declarations.
5700 */
5701 ctxt->nbKeys = 0;
5702 style = ctxt->style;
5703 while (style != NULL) {
5704 keyd = style->keys;
5705 while (keyd) {
5706 ctxt->nbKeys++;
5707 keyd = keyd->next;
5708 }
5710 }
5711 return(ctxt->nbKeys);
5712}
struct _xsltKeyDef * next

Referenced by xsltApplyStylesheetInternal().

◆ xsltDebugGetDefaultTrace()

xsltDebugTraceCodes xsltDebugGetDefaultTrace ( void  )

xsltDebugGetDefaultTrace:

Get the current default debug tracing level mask

Returns the current default debug tracing level mask

Definition at line 460 of file transform.c.

460 {
461 return xsltDefaultTrace;
462}
static unsigned long xsltDefaultTrace
Definition: transform.c:441

◆ xsltDebugSetDefaultTrace()

void xsltDebugSetDefaultTrace ( xsltDebugTraceCodes  val)

xsltDebugSetDefaultTrace: @val: tracing level mask

Set the default debug tracing level mask

Definition at line 449 of file transform.c.

449 {
451}
GLuint GLfloat * val
Definition: glext.h:7180

◆ xsltDefaultProcessOneNode()

static void xsltDefaultProcessOneNode ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xsltStackElemPtr  params 
)
static

xsltDefaultProcessOneNode: @ctxt: a XSLT process context @node: the node in the source tree. @params: extra parameters passed to the template if any

Process the source node with the default built-in template rule: <xsl:template match="*|/"> <xsl:apply-templates/> </xsl:template>

and

<xsl:template match="text()|@*"> <xsl:value-of select="."/> </xsl:template>

Note also that namespace declarations are copied directly:

the built-in template rule is the only template rule that is applied for namespace nodes.

Definition at line 1859 of file transform.c.

1860 {
1863 int nbchild = 0, oldSize;
1864 int childno = 0, oldPos;
1865 xsltTemplatePtr template;
1866
1868 /*
1869 * Handling of leaves
1870 */
1871 switch (node->type) {
1872 case XML_DOCUMENT_NODE:
1874 case XML_ELEMENT_NODE:
1875 break;
1877#ifdef WITH_XSLT_DEBUG_PROCESS
1879 "xsltDefaultProcessOneNode: copy CDATA %s\n",
1880 node->content));
1881#endif
1882 copy = xsltCopyText(ctxt, ctxt->insert, node, 0);
1883 if (copy == NULL) {
1885 "xsltDefaultProcessOneNode: cdata copy failed\n");
1886 }
1887 return;
1888 case XML_TEXT_NODE:
1889#ifdef WITH_XSLT_DEBUG_PROCESS
1890 if (node->content == NULL) {
1892 "xsltDefaultProcessOneNode: copy empty text\n"));
1893 return;
1894 } else {
1896 "xsltDefaultProcessOneNode: copy text %s\n",
1897 node->content));
1898 }
1899#endif
1900 copy = xsltCopyText(ctxt, ctxt->insert, node, 0);
1901 if (copy == NULL) {
1903 "xsltDefaultProcessOneNode: text copy failed\n");
1904 }
1905 return;
1906 case XML_ATTRIBUTE_NODE:
1907 cur = node->children;
1908 while ((cur != NULL) && (cur->type != XML_TEXT_NODE))
1909 cur = cur->next;
1910 if (cur == NULL) {
1912 "xsltDefaultProcessOneNode: no text for attribute\n");
1913 } else {
1914#ifdef WITH_XSLT_DEBUG_PROCESS
1915 if (cur->content == NULL) {
1917 "xsltDefaultProcessOneNode: copy empty text\n"));
1918 } else {
1920 "xsltDefaultProcessOneNode: copy text %s\n",
1921 cur->content));
1922 }
1923#endif
1924 copy = xsltCopyText(ctxt, ctxt->insert, cur, 0);
1925 if (copy == NULL) {
1927 "xsltDefaultProcessOneNode: text copy failed\n");
1928 }
1929 }
1930 return;
1931 default:
1932 return;
1933 }
1934 /*
1935 * Handling of Elements: first pass, counting
1936 */
1937 cur = node->children;
1938 while (cur != NULL) {
1940 nbchild++;
1941 cur = cur->next;
1942 }
1943
1944 /*
1945 * Handling of Elements: second pass, actual processing
1946 *
1947 * Note that params are passed to the next template. This matches
1948 * XSLT 2.0 behavior but doesn't conform to XSLT 1.0.
1949 */
1950 oldSize = ctxt->xpathCtxt->contextSize;
1951 oldPos = ctxt->xpathCtxt->proximityPosition;
1952 cur = node->children;
1953 while (cur != NULL) {
1954 childno++;
1955 switch (cur->type) {
1956 case XML_DOCUMENT_NODE:
1958 case XML_ELEMENT_NODE:
1959 ctxt->xpathCtxt->contextSize = nbchild;
1960 ctxt->xpathCtxt->proximityPosition = childno;
1962 break;
1964 template = xsltGetTemplate(ctxt, cur, NULL);
1965 if (template) {
1966#ifdef WITH_XSLT_DEBUG_PROCESS
1968 "xsltDefaultProcessOneNode: applying template for CDATA %s\n",
1969 cur->content));
1970#endif
1971 /*
1972 * Instantiate the xsl:template.
1973 */
1974 xsltApplyXSLTTemplate(ctxt, cur, template->content,
1975 template, params);
1976 } else /* if (ctxt->mode == NULL) */ {
1977#ifdef WITH_XSLT_DEBUG_PROCESS
1979 "xsltDefaultProcessOneNode: copy CDATA %s\n",
1980 cur->content));
1981#endif
1982 copy = xsltCopyText(ctxt, ctxt->insert, cur, 0);
1983 if (copy == NULL) {
1985 "xsltDefaultProcessOneNode: cdata copy failed\n");
1986 }
1987 }
1988 break;
1989 case XML_TEXT_NODE:
1990 template = xsltGetTemplate(ctxt, cur, NULL);
1991 if (template) {
1992#ifdef WITH_XSLT_DEBUG_PROCESS
1994 "xsltDefaultProcessOneNode: applying template for text %s\n",
1995 cur->content));
1996#endif
1997 ctxt->xpathCtxt->contextSize = nbchild;
1998 ctxt->xpathCtxt->proximityPosition = childno;
1999 /*
2000 * Instantiate the xsl:template.
2001 */
2002 xsltApplyXSLTTemplate(ctxt, cur, template->content,
2003 template, params);
2004 } else /* if (ctxt->mode == NULL) */ {
2005#ifdef WITH_XSLT_DEBUG_PROCESS
2006 if (cur->content == NULL) {
2008 "xsltDefaultProcessOneNode: copy empty text\n"));
2009 } else {
2011 "xsltDefaultProcessOneNode: copy text %s\n",
2012 cur->content));
2013 }
2014#endif
2015 copy = xsltCopyText(ctxt, ctxt->insert, cur, 0);
2016 if (copy == NULL) {
2018 "xsltDefaultProcessOneNode: text copy failed\n");
2019 }
2020 }
2021 break;
2022 case XML_PI_NODE:
2023 case XML_COMMENT_NODE:
2024 template = xsltGetTemplate(ctxt, cur, NULL);
2025 if (template) {
2026#ifdef WITH_XSLT_DEBUG_PROCESS
2027 if (cur->type == XML_PI_NODE) {
2029 "xsltDefaultProcessOneNode: template found for PI %s\n",
2030 cur->name));
2031 } else if (cur->type == XML_COMMENT_NODE) {
2033 "xsltDefaultProcessOneNode: template found for comment\n"));
2034 }
2035#endif
2036 ctxt->xpathCtxt->contextSize = nbchild;
2037 ctxt->xpathCtxt->proximityPosition = childno;
2038 /*
2039 * Instantiate the xsl:template.
2040 */
2041 xsltApplyXSLTTemplate(ctxt, cur, template->content,
2042 template, params);
2043 }
2044 break;
2045 default:
2046 break;
2047 }
2048 cur = cur->next;
2049 }
2050 ctxt->xpathCtxt->contextSize = oldSize;
2051 ctxt->xpathCtxt->proximityPosition = oldPos;
2052}
const UINT template
Definition: action.c:7481
@ XSLT_TRACE_PROCESS_NODE
Definition: xsltutils.h:102

Referenced by xsltApplyImports(), and xsltProcessOneNode().

◆ xsltDocumentElem()

void xsltDocumentElem ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltDocumentElem: @ctxt: an XSLT processing context @node: The current node @inst: the instruction in the stylesheet @castedComp: precomputed information

Process an EXSLT/XSLT-1.1 document element

Definition at line 3323 of file transform.c.

3325{
3326#ifdef XSLT_REFACTORED
3327 xsltStyleItemDocumentPtr comp = (xsltStyleItemDocumentPtr) castedComp;
3328#else
3329 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
3330#endif
3332 int ret;
3333 xmlChar *filename = NULL, *prop, *elements;
3334 xmlChar *element, *end;
3335 xmlDocPtr res = NULL;
3336 xmlDocPtr oldOutput;
3337 xmlNodePtr oldInsert, root;
3338 const char *oldOutputFile;
3339 xsltOutputType oldType;
3340 xmlChar *URL = NULL;
3341 const xmlChar *method;
3342 const xmlChar *doctypePublic;
3343 const xmlChar *doctypeSystem;
3344 const xmlChar *version;
3345 const xmlChar *encoding;
3346 int redirect_write_append = 0;
3347
3348 if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
3349 return;
3350
3351 if (comp->filename == NULL) {
3352
3353 if (xmlStrEqual(inst->name, (const xmlChar *) "output")) {
3354 /*
3355 * The element "output" is in the namespace XSLT_SAXON_NAMESPACE
3356 * (http://icl.com/saxon)
3357 * The @file is in no namespace.
3358 */
3359#ifdef WITH_XSLT_DEBUG_EXTRA
3361 "Found saxon:output extension\n");
3362#endif
3363 URL = xsltEvalAttrValueTemplate(ctxt, inst,
3364 (const xmlChar *) "file",
3366
3367 if (URL == NULL)
3368 URL = xsltEvalAttrValueTemplate(ctxt, inst,
3369 (const xmlChar *) "href",
3371 } else if (xmlStrEqual(inst->name, (const xmlChar *) "write")) {
3372#ifdef WITH_XSLT_DEBUG_EXTRA
3374 "Found xalan:write extension\n");
3375#endif
3376 URL = xsltEvalAttrValueTemplate(ctxt, inst,
3377 (const xmlChar *)
3378 "select",
3380 if (URL != NULL) {
3381 xmlXPathCompExprPtr cmp;
3382 xmlChar *val;
3383
3384 /*
3385 * Trying to handle bug #59212
3386 * The value of the "select" attribute is an
3387 * XPath expression.
3388 * (see http://xml.apache.org/xalan-j/extensionslib.html#redirect)
3389 */
3390 cmp = xmlXPathCtxtCompile(ctxt->xpathCtxt, URL);
3391 val = xsltEvalXPathString(ctxt, cmp);
3392 xmlXPathFreeCompExpr(cmp);
3393 xmlFree(URL);
3394 URL = val;
3395 }
3396 if (URL == NULL)
3397 URL = xsltEvalAttrValueTemplate(ctxt, inst,
3398 (const xmlChar *)
3399 "file",
3401 if (URL == NULL)
3402 URL = xsltEvalAttrValueTemplate(ctxt, inst,
3403 (const xmlChar *)
3404 "href",
3406 } else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) {
3407 URL = xsltEvalAttrValueTemplate(ctxt, inst,
3408 (const xmlChar *) "href",
3409 NULL);
3410 }
3411
3412 } else {
3413 URL = xmlStrdup(comp->filename);
3414 }
3415
3416 if (URL == NULL) {
3417 xsltTransformError(ctxt, NULL, inst,
3418 "xsltDocumentElem: href/URI-Reference not found\n");
3419 return;
3420 }
3421
3422 /*
3423 * If the computation failed, it's likely that the URL wasn't escaped
3424 */
3425 filename = xmlBuildURI(URL, (const xmlChar *) ctxt->outputFile);
3426 if (filename == NULL) {
3427 xmlChar *escURL;
3428
3429 escURL=xmlURIEscapeStr(URL, BAD_CAST ":/.?,");
3430 if (escURL != NULL) {
3431 filename = xmlBuildURI(escURL, (const xmlChar *) ctxt->outputFile);
3432 xmlFree(escURL);
3433 }
3434 }
3435
3436 if (filename == NULL) {
3437 xsltTransformError(ctxt, NULL, inst,
3438 "xsltDocumentElem: URL computation failed for %s\n",
3439 URL);
3440 xmlFree(URL);
3441 return;
3442 }
3443
3444 /*
3445 * Security checking: can we write to this resource
3446 */
3447 if (ctxt->sec != NULL) {
3448 ret = xsltCheckWrite(ctxt->sec, ctxt, filename);
3449 if (ret <= 0) {
3450 if (ret == 0)
3451 xsltTransformError(ctxt, NULL, inst,
3452 "xsltDocumentElem: write rights for %s denied\n",
3453 filename);
3454 xmlFree(URL);
3456 return;
3457 }
3458 }
3459
3460 oldOutputFile = ctxt->outputFile;
3461 oldOutput = ctxt->output;
3462 oldInsert = ctxt->insert;
3463 oldType = ctxt->type;
3464 ctxt->outputFile = (const char *) filename;
3465
3467 if (style == NULL) {
3468 xsltTransformError(ctxt, NULL, inst,
3469 "xsltDocumentElem: out of memory\n");
3470 goto error;
3471 }
3472
3473 /*
3474 * Version described in 1.1 draft allows full parameterization
3475 * of the output.
3476 */
3477 prop = xsltEvalAttrValueTemplate(ctxt, inst,
3478 (const xmlChar *) "version",
3479 NULL);
3480 if (prop != NULL) {
3481 if (style->version != NULL)
3482 xmlFree(style->version);
3483 style->version = prop;
3484 }
3485 prop = xsltEvalAttrValueTemplate(ctxt, inst,
3486 (const xmlChar *) "encoding",
3487 NULL);
3488 if (prop != NULL) {
3489 if (style->encoding != NULL)
3490 xmlFree(style->encoding);
3491 style->encoding = prop;
3492 }
3493 prop = xsltEvalAttrValueTemplate(ctxt, inst,
3494 (const xmlChar *) "method",
3495 NULL);
3496 if (prop != NULL) {
3497 const xmlChar *URI;
3498
3499 if (style->method != NULL)
3500 xmlFree(style->method);
3501 style->method = NULL;
3502 if (style->methodURI != NULL)
3503 xmlFree(style->methodURI);
3504 style->methodURI = NULL;
3505
3506 URI = xsltGetQNameURI(inst, &prop);
3507 if (prop == NULL) {
3508 if (style != NULL) style->errors++;
3509 } else if (URI == NULL) {
3510 if ((xmlStrEqual(prop, (const xmlChar *) "xml")) ||
3511 (xmlStrEqual(prop, (const xmlChar *) "html")) ||
3512 (xmlStrEqual(prop, (const xmlChar *) "text"))) {
3513 style->method = prop;
3514 } else {
3515 xsltTransformError(ctxt, NULL, inst,
3516 "invalid value for method: %s\n", prop);
3517 if (style != NULL) style->warnings++;
3518 }
3519 } else {
3520 style->method = prop;
3521 style->methodURI = xmlStrdup(URI);
3522 }
3523 }
3524 prop = xsltEvalAttrValueTemplate(ctxt, inst,
3525 (const xmlChar *)
3526 "doctype-system", NULL);
3527 if (prop != NULL) {
3528 if (style->doctypeSystem != NULL)
3529 xmlFree(style->doctypeSystem);
3530 style->doctypeSystem = prop;
3531 }
3532 prop = xsltEvalAttrValueTemplate(ctxt, inst,
3533 (const xmlChar *)
3534 "doctype-public", NULL);
3535 if (prop != NULL) {
3536 if (style->doctypePublic != NULL)
3537 xmlFree(style->doctypePublic);
3538 style->doctypePublic = prop;
3539 }
3540 prop = xsltEvalAttrValueTemplate(ctxt, inst,
3541 (const xmlChar *) "standalone",
3542 NULL);
3543 if (prop != NULL) {
3544 if (xmlStrEqual(prop, (const xmlChar *) "yes")) {
3545 style->standalone = 1;
3546 } else if (xmlStrEqual(prop, (const xmlChar *) "no")) {
3547 style->standalone = 0;
3548 } else {
3549 xsltTransformError(ctxt, NULL, inst,
3550 "invalid value for standalone: %s\n",
3551 prop);
3552 if (style != NULL) style->warnings++;
3553 }
3554 xmlFree(prop);
3555 }
3556
3557 prop = xsltEvalAttrValueTemplate(ctxt, inst,
3558 (const xmlChar *) "indent",
3559 NULL);
3560 if (prop != NULL) {
3561 if (xmlStrEqual(prop, (const xmlChar *) "yes")) {
3562 style->indent = 1;
3563 } else if (xmlStrEqual(prop, (const xmlChar *) "no")) {
3564 style->indent = 0;
3565 } else {
3566 xsltTransformError(ctxt, NULL, inst,
3567 "invalid value for indent: %s\n", prop);
3568 if (style != NULL) style->warnings++;
3569 }
3570 xmlFree(prop);
3571 }
3572
3573 prop = xsltEvalAttrValueTemplate(ctxt, inst,
3574 (const xmlChar *)
3575 "omit-xml-declaration",
3576 NULL);
3577 if (prop != NULL) {
3578 if (xmlStrEqual(prop, (const xmlChar *) "yes")) {
3579 style->omitXmlDeclaration = 1;
3580 } else if (xmlStrEqual(prop, (const xmlChar *) "no")) {
3581 style->omitXmlDeclaration = 0;
3582 } else {
3583 xsltTransformError(ctxt, NULL, inst,
3584 "invalid value for omit-xml-declaration: %s\n",
3585 prop);
3586 if (style != NULL) style->warnings++;
3587 }
3588 xmlFree(prop);
3589 }
3590
3591 elements = xsltEvalAttrValueTemplate(ctxt, inst,
3592 (const xmlChar *)
3593 "cdata-section-elements",
3594 NULL);
3595 if (elements != NULL) {
3596 if (style->stripSpaces == NULL)
3597 style->stripSpaces = xmlHashCreate(10);
3598 if (style->stripSpaces == NULL) {
3599 xmlFree(elements);
3600 return;
3601 }
3602
3603 element = elements;
3604 while (*element != 0) {
3605 while (xmlIsBlank_ch(*element))
3606 element++;
3607 if (*element == 0)
3608 break;
3609 end = element;
3610 while ((*end != 0) && (!xmlIsBlank_ch(*end)))
3611 end++;
3613 if (element) {
3614 const xmlChar *URI;
3615
3616#ifdef WITH_XSLT_DEBUG_PARSING
3618 "add cdata section output element %s\n",
3619 element);
3620#endif
3621 URI = xsltGetQNameURI(inst, &element);
3622
3623 xmlHashAddEntry2(style->stripSpaces, element, URI,
3624 (xmlChar *) "cdata");
3626 }
3627 element = end;
3628 }
3629 xmlFree(elements);
3630 }
3631
3632 /*
3633 * Create a new document tree and process the element template
3634 */
3636 XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
3637 XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
3640
3641 if ((method != NULL) &&
3642 (!xmlStrEqual(method, (const xmlChar *) "xml"))) {
3643 if (xmlStrEqual(method, (const xmlChar *) "html")) {
3644 ctxt->type = XSLT_OUTPUT_HTML;
3645 if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
3646 res = htmlNewDoc(doctypeSystem, doctypePublic);
3647 else {
3648 if (version != NULL) {
3649#ifdef XSLT_GENERATE_HTML_DOCTYPE
3650 xsltGetHTMLIDs(version, &doctypePublic, &doctypeSystem);
3651#endif
3652 }
3653 res = htmlNewDocNoDtD(doctypeSystem, doctypePublic);
3654 }
3655 if (res == NULL)
3656 goto error;
3657 res->dict = ctxt->dict;
3658 xmlDictReference(res->dict);
3659 } else if (xmlStrEqual(method, (const xmlChar *) "xhtml")) {
3660 xsltTransformError(ctxt, NULL, inst,
3661 "xsltDocumentElem: unsupported method xhtml\n");
3662 ctxt->type = XSLT_OUTPUT_HTML;
3663 res = htmlNewDocNoDtD(doctypeSystem, doctypePublic);
3664 if (res == NULL)
3665 goto error;
3666 res->dict = ctxt->dict;
3667 xmlDictReference(res->dict);
3668 } else if (xmlStrEqual(method, (const xmlChar *) "text")) {
3669 ctxt->type = XSLT_OUTPUT_TEXT;
3670 res = xmlNewDoc(style->version);
3671 if (res == NULL)
3672 goto error;
3673 res->dict = ctxt->dict;
3674 xmlDictReference(res->dict);
3675#ifdef WITH_XSLT_DEBUG
3677 "reusing transformation dict for output\n");
3678#endif
3679 } else {
3680 xsltTransformError(ctxt, NULL, inst,
3681 "xsltDocumentElem: unsupported method (%s)\n",
3682 method);
3683 goto error;
3684 }
3685 } else {
3686 ctxt->type = XSLT_OUTPUT_XML;
3687 res = xmlNewDoc(style->version);
3688 if (res == NULL)
3689 goto error;
3690 res->dict = ctxt->dict;
3691 xmlDictReference(res->dict);
3692#ifdef WITH_XSLT_DEBUG
3694 "reusing transformation dict for output\n");
3695#endif
3696 }
3697 res->charset = XML_CHAR_ENCODING_UTF8;
3698 if (encoding != NULL)
3699 res->encoding = xmlStrdup(encoding);
3700 ctxt->output = res;
3701 ctxt->insert = (xmlNodePtr) res;
3703
3704 /*
3705 * Do some post processing work depending on the generated output
3706 */
3708 if (root != NULL) {
3709 const xmlChar *doctype = NULL;
3710
3711 if ((root->ns != NULL) && (root->ns->prefix != NULL))
3712 doctype = xmlDictQLookup(ctxt->dict, root->ns->prefix, root->name);
3713 if (doctype == NULL)
3714 doctype = root->name;
3715
3716 /*
3717 * Apply the default selection of the method
3718 */
3719 if ((method == NULL) &&
3720 (root->ns == NULL) &&
3721 (!xmlStrcasecmp(root->name, (const xmlChar *) "html"))) {
3722 xmlNodePtr tmp;
3723
3724 tmp = res->children;
3725 while ((tmp != NULL) && (tmp != root)) {
3726 if (tmp->type == XML_ELEMENT_NODE)
3727 break;
3728 if ((tmp->type == XML_TEXT_NODE) && (!xmlIsBlankNode(tmp)))
3729 break;
3730 tmp = tmp->next;
3731 }
3732 if (tmp == root) {
3733 ctxt->type = XSLT_OUTPUT_HTML;
3735 if (((doctypePublic != NULL) || (doctypeSystem != NULL))) {
3736 res->intSubset = xmlCreateIntSubset(res, doctype,
3737 doctypePublic,
3738 doctypeSystem);
3739#ifdef XSLT_GENERATE_HTML_DOCTYPE
3740 } else if (version != NULL) {
3741 xsltGetHTMLIDs(version, &doctypePublic,
3742 &doctypeSystem);
3743 if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
3744 res->intSubset =
3745 xmlCreateIntSubset(res, doctype,
3746 doctypePublic,
3747 doctypeSystem);
3748#endif
3749 }
3750 }
3751
3752 }
3753 if (ctxt->type == XSLT_OUTPUT_XML) {
3754 XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
3755 XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
3756 if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
3757 res->intSubset = xmlCreateIntSubset(res, doctype,
3758 doctypePublic,
3759 doctypeSystem);
3760 }
3761 }
3762
3763 /*
3764 * Calls to redirect:write also take an optional attribute append.
3765 * Attribute append="true|yes" which will attempt to simply append
3766 * to an existing file instead of always opening a new file. The
3767 * default behavior of always overwriting the file still happens
3768 * if we do not specify append.
3769 * Note that append use will forbid use of remote URI target.
3770 */
3771 prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"append",
3772 NULL);
3773 if (prop != NULL) {
3774 if (xmlStrEqual(prop, (const xmlChar *) "true") ||
3775 xmlStrEqual(prop, (const xmlChar *) "yes")) {
3776 style->omitXmlDeclaration = 1;
3777 redirect_write_append = 1;
3778 } else
3779 style->omitXmlDeclaration = 0;
3780 xmlFree(prop);
3781 }
3782
3783 if (redirect_write_append) {
3784 FILE *f;
3785
3786 f = fopen((const char *) filename, "ab");
3787 if (f == NULL) {
3788 ret = -1;
3789 } else {
3791 fclose(f);
3792 }
3793 } else {
3794 ret = xsltSaveResultToFilename((const char *) filename, res, style, 0);
3795 }
3796 if (ret < 0) {
3797 xsltTransformError(ctxt, NULL, inst,
3798 "xsltDocumentElem: unable to save to %s\n",
3799 filename);
3800#ifdef WITH_XSLT_DEBUG_EXTRA
3801 } else {
3803 "Wrote %d bytes to %s\n", ret, filename);
3804#endif
3805 }
3806
3807 error:
3808 ctxt->output = oldOutput;
3809 ctxt->insert = oldInsert;
3810 ctxt->type = oldType;
3811 ctxt->outputFile = oldOutputFile;
3812 if (URL != NULL)
3813 xmlFree(URL);
3814 if (filename != NULL)
3816 if (style != NULL)
3818 if (res != NULL)
3819 xmlFreeDoc(res);
3820}
#define xmlIsBlank_ch(c)
Definition: chvalid.h:88
#define XSLT_XALAN_NAMESPACE
Definition: extra.h:48
#define XSLT_SAXON_NAMESPACE
Definition: extra.h:34
GLfloat f
Definition: glext.h:7540
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
const char * filename
Definition: ioapi.h:137
#define f
Definition: ke_i.h:83
#define cmp(status, error)
Definition: error.c:114
XMLPUBFUN int XMLCALL xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, void *userdata)
Definition: hash.c:406
const xmlChar * name
Definition: tree.h:492
xmlChar * xsltEvalXPathString(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp)
Definition: templates.c:171
xmlChar * xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr inst, const xmlChar *name, const xmlChar *ns)
Definition: templates.c:392
XMLPUBFUN xmlChar *XMLCALL xmlURIEscapeStr(const xmlChar *str, const xmlChar *list)
Definition: uri.c:1679
XMLPUBFUN xmlChar *XMLCALL xmlBuildURI(const xmlChar *URI, const xmlChar *base)
Definition: uri.c:1892
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:42
xsltOutputType
xsltStylesheetPtr xsltNewStylesheet(void)
Definition: xslt.c:795
void xsltFreeStylesheet(xsltStylesheetPtr style)
Definition: xslt.c:950
const xmlChar * xsltGetQNameURI(xmlNodePtr node, xmlChar **name)
Definition: xsltutils.c:753
int xsltSaveResultToFilename(const char *URL, xmlDocPtr result, xsltStylesheetPtr style, int compression)
Definition: xsltutils.c:1636
int xsltSaveResultToFile(FILE *file, xmlDocPtr result, xsltStylesheetPtr style)
Definition: xsltutils.c:1680

Referenced by xsltNewStylePreComp(), xsltRegisterAllExtras(), and xsltStylePreCompute().

◆ xsltElement()

void xsltElement ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltElement: @ctxt: a XSLT process context @node: the node in the source tree. @inst: the xslt element node @castedComp: precomputed information

Process the xslt element node on the source node

Definition at line 4017 of file transform.c.

4018 {
4019#ifdef XSLT_REFACTORED
4020 xsltStyleItemElementPtr comp = (xsltStyleItemElementPtr) castedComp;
4021#else
4022 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
4023#endif
4024 xmlChar *prop = NULL;
4025 const xmlChar *name, *prefix = NULL, *nsName = NULL;
4027 xmlNodePtr oldInsert;
4028
4029 if (ctxt->insert == NULL)
4030 return;
4031
4032 /*
4033 * A comp->has_name == 0 indicates that we need to skip this instruction,
4034 * since it was evaluated to be invalid already during compilation.
4035 */
4036 if (!comp->has_name)
4037 return;
4038
4039 /*
4040 * stack and saves
4041 */
4042 oldInsert = ctxt->insert;
4043
4044 if (comp->name == NULL) {
4045 /* TODO: fix attr acquisition wrt to the XSLT namespace */
4046 prop = xsltEvalAttrValueTemplate(ctxt, inst,
4047 (const xmlChar *) "name", XSLT_NAMESPACE);
4048 if (prop == NULL) {
4049 xsltTransformError(ctxt, NULL, inst,
4050 "xsl:element: The attribute 'name' is missing.\n");
4051 goto error;
4052 }
4053 if (xmlValidateQName(prop, 0)) {
4054 xsltTransformError(ctxt, NULL, inst,
4055 "xsl:element: The effective name '%s' is not a "
4056 "valid QName.\n", prop);
4057 /* we fall through to catch any further errors, if possible */
4058 }
4059 name = xsltSplitQName(ctxt->dict, prop, &prefix);
4060 xmlFree(prop);
4061 } else {
4062 /*
4063 * The "name" value was static.
4064 */
4065#ifdef XSLT_REFACTORED
4066 prefix = comp->nsPrefix;
4067 name = comp->name;
4068#else
4069 name = xsltSplitQName(ctxt->dict, comp->name, &prefix);
4070#endif
4071 }
4072
4073 /*
4074 * Create the new element
4075 */
4076 if (ctxt->output->dict == ctxt->dict) {
4078 } else {
4079 copy = xmlNewDocNode(ctxt->output, NULL, (xmlChar *)name, NULL);
4080 }
4081 if (copy == NULL) {
4082 xsltTransformError(ctxt, NULL, inst,
4083 "xsl:element : creation of %s failed\n", name);
4084 return;
4085 }
4086 copy = xsltAddChild(ctxt->insert, copy);
4087 if (copy == NULL) {
4088 xsltTransformError(ctxt, NULL, inst,
4089 "xsl:element : xsltAddChild failed\n");
4090 return;
4091 }
4092
4093 /*
4094 * Namespace
4095 * ---------
4096 */
4097 if (comp->has_ns) {
4098 if (comp->ns != NULL) {
4099 /*
4100 * No AVT; just plain text for the namespace name.
4101 */
4102 if (comp->ns[0] != 0)
4103 nsName = comp->ns;
4104 } else {
4105 xmlChar *tmpNsName;
4106 /*
4107 * Eval the AVT.
4108 */
4109 /* TODO: check attr acquisition wrt to the XSLT namespace */
4110 tmpNsName = xsltEvalAttrValueTemplate(ctxt, inst,
4111 (const xmlChar *) "namespace", XSLT_NAMESPACE);
4112 /*
4113 * SPEC XSLT 1.0:
4114 * "If the string is empty, then the expanded-name of the
4115 * attribute has a null namespace URI."
4116 */
4117 if ((tmpNsName != NULL) && (tmpNsName[0] != 0))
4118 nsName = xmlDictLookup(ctxt->dict, BAD_CAST tmpNsName, -1);
4119 xmlFree(tmpNsName);
4120 }
4121
4122 if (xmlStrEqual(nsName, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
4123 xsltTransformError(ctxt, NULL, inst,
4124 "xsl:attribute: Namespace http://www.w3.org/2000/xmlns/ "
4125 "forbidden.\n");
4126 goto error;
4127 }
4128 if (xmlStrEqual(nsName, XML_XML_NAMESPACE)) {
4129 prefix = BAD_CAST "xml";
4130 } else if (xmlStrEqual(prefix, BAD_CAST "xml")) {
4131 prefix = NULL;
4132 }
4133 } else {
4134 xmlNsPtr ns;
4135 /*
4136 * SPEC XSLT 1.0:
4137 * "If the namespace attribute is not present, then the QName is
4138 * expanded into an expanded-name using the namespace declarations
4139 * in effect for the xsl:element element, including any default
4140 * namespace declaration.
4141 */
4142 ns = xmlSearchNs(inst->doc, inst, prefix);
4143 if (ns == NULL) {
4144 /*
4145 * TODO: Check this in the compilation layer in case it's a
4146 * static value.
4147 */
4148 if (prefix != NULL) {
4149 xsltTransformError(ctxt, NULL, inst,
4150 "xsl:element: The QName '%s:%s' has no "
4151 "namespace binding in scope in the stylesheet; "
4152 "this is an error, since the namespace was not "
4153 "specified by the instruction itself.\n", prefix, name);
4154 }
4155 } else
4156 nsName = ns->href;
4157 }
4158 /*
4159 * Find/create a matching ns-decl in the result tree.
4160 */
4161 if (nsName != NULL) {
4162 if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
4163 /* Don't use a prefix of "xmlns" */
4164 xmlChar *pref = xmlStrdup(BAD_CAST "ns_1");
4165
4166 copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, pref, copy);
4167
4168 xmlFree(pref);
4169 } else {
4170 copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, prefix,
4171 copy);
4172 }
4173 } else if ((copy->parent != NULL) &&
4174 (copy->parent->type == XML_ELEMENT_NODE) &&
4175 (copy->parent->ns != NULL))
4176 {
4177 /*
4178 * "Undeclare" the default namespace.
4179 */
4180 xsltGetSpecialNamespace(ctxt, inst, NULL, NULL, copy);
4181 }
4182
4183 ctxt->insert = copy;
4184
4185 if (comp->has_use) {
4186 if (comp->use != NULL) {
4187 xsltApplyAttributeSet(ctxt, node, inst, comp->use);
4188 } else {
4189 xmlChar *attrSets = NULL;
4190 /*
4191 * BUG TODO: use-attribute-sets is not a value template.
4192 * use-attribute-sets = qnames
4193 */
4194 attrSets = xsltEvalAttrValueTemplate(ctxt, inst,
4195 (const xmlChar *)"use-attribute-sets", NULL);
4196 if (attrSets != NULL) {
4197 xsltApplyAttributeSet(ctxt, node, inst, attrSets);
4198 xmlFree(attrSets);
4199 }
4200 }
4201 }
4202 /*
4203 * Instantiate the sequence constructor.
4204 */
4205 if (inst->children != NULL)
4206 xsltApplySequenceConstructor(ctxt, ctxt->node, inst->children,
4207 NULL);
4208
4209error:
4210 ctxt->insert = oldInsert;
4211 return;
4212}
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns, const xmlChar *name, const xmlChar *content)
#define XML_XML_NAMESPACE
Definition: tree.h:140
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocNodeEatName(xmlDocPtr doc, xmlNsPtr ns, xmlChar *name, const xmlChar *content)
struct _xmlDict * dict
Definition: tree.h:580
Definition: name.c:39
WCHAR * name
Definition: name.c:42
const xmlChar * xsltSplitQName(xmlDictPtr dict, const xmlChar *name, const xmlChar **prefix)
Definition: xsltutils.c:720

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltForEach()

void xsltForEach ( xsltTransformContextPtr  ctxt,
xmlNodePtr  contextNode,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltForEach: @ctxt: an XSLT transformation context @contextNode: the "current node" in the source tree @inst: the element node of the xsl:for-each instruction @castedComp: the compiled information of the instruction

Process the xslt for-each node on the source node

Definition at line 5361 of file transform.c.

5363{
5364#ifdef XSLT_REFACTORED
5365 xsltStyleItemForEachPtr comp = (xsltStyleItemForEachPtr) castedComp;
5366#else
5367 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
5368#endif
5369 int i;
5370 xmlXPathObjectPtr res = NULL;
5371 xmlNodePtr cur, curInst;
5372 xmlNodeSetPtr list = NULL;
5373 xmlNodeSetPtr oldList;
5374 int oldXPProximityPosition, oldXPContextSize;
5375 xmlNodePtr oldContextNode;
5376 xsltTemplatePtr oldCurTemplRule;
5377 xmlDocPtr oldXPDoc;
5378 xsltDocumentPtr oldDocInfo;
5379 xmlXPathContextPtr xpctxt;
5380
5381 if ((ctxt == NULL) || (contextNode == NULL) || (inst == NULL)) {
5383 "xsltForEach(): Bad arguments.\n");
5384 return;
5385 }
5386
5387 if (comp == NULL) {
5388 xsltTransformError(ctxt, NULL, inst,
5389 "Internal error in xsltForEach(): "
5390 "The XSLT 'for-each' instruction was not compiled.\n");
5391 return;
5392 }
5393 if ((comp->select == NULL) || (comp->comp == NULL)) {
5394 xsltTransformError(ctxt, NULL, inst,
5395 "Internal error in xsltForEach(): "
5396 "The selecting expression of the XSLT 'for-each' "
5397 "instruction was not compiled correctly.\n");
5398 return;
5399 }
5400 xpctxt = ctxt->xpathCtxt;
5401
5402#ifdef WITH_XSLT_DEBUG_PROCESS
5404 "xsltForEach: select %s\n", comp->select));
5405#endif
5406
5407 /*
5408 * Save context states.
5409 */
5410 oldDocInfo = ctxt->document;
5411 oldList = ctxt->nodeList;
5412 oldContextNode = ctxt->node;
5413 /*
5414 * The "current template rule" is cleared for the instantiation of
5415 * xsl:for-each.
5416 */
5417 oldCurTemplRule = ctxt->currentTemplateRule;
5418 ctxt->currentTemplateRule = NULL;
5419
5420 oldXPDoc = xpctxt->doc;
5421 oldXPProximityPosition = xpctxt->proximityPosition;
5422 oldXPContextSize = xpctxt->contextSize;
5423
5424 /*
5425 * Evaluate the 'select' expression.
5426 */
5427 res = xsltPreCompEval(ctxt, contextNode, comp);
5428
5429 if (res != NULL) {
5430 if (res->type == XPATH_NODESET)
5431 list = res->nodesetval;
5432 else {
5433 xsltTransformError(ctxt, NULL, inst,
5434 "The 'select' expression does not evaluate to a node set.\n");
5435
5436#ifdef WITH_XSLT_DEBUG_PROCESS
5438 "xsltForEach: select didn't evaluate to a node list\n"));
5439#endif
5440 goto error;
5441 }
5442 } else {
5443 xsltTransformError(ctxt, NULL, inst,
5444 "Failed to evaluate the 'select' expression.\n");
5445 ctxt->state = XSLT_STATE_STOPPED;
5446 goto error;
5447 }
5448
5449 if ((list == NULL) || (list->nodeNr <= 0))
5450 goto exit;
5451
5452#ifdef WITH_XSLT_DEBUG_PROCESS
5454 "xsltForEach: select evaluates to %d nodes\n", list->nodeNr));
5455#endif
5456
5457 /*
5458 * Set the list; this has to be done already here for xsltDoSortFunction().
5459 */
5460 ctxt->nodeList = list;
5461 /*
5462 * Handle xsl:sort instructions and skip them for further processing.
5463 * BUG TODO: We are not using namespaced potentially defined on the
5464 * xsl:sort element; XPath expression might fail.
5465 */
5466 curInst = inst->children;
5467 if (IS_XSLT_ELEM(curInst) && IS_XSLT_NAME(curInst, "sort")) {
5468 int nbsorts = 0;
5470
5471 sorts[nbsorts++] = curInst;
5472
5473#ifdef WITH_DEBUGGER
5475 xslHandleDebugger(curInst, contextNode, NULL, ctxt);
5476#endif
5477
5478 curInst = curInst->next;
5479 while (IS_XSLT_ELEM(curInst) && IS_XSLT_NAME(curInst, "sort")) {
5480 if (nbsorts >= XSLT_MAX_SORT) {
5481 xsltTransformError(ctxt, NULL, curInst,
5482 "The number of xsl:sort instructions exceeds the "
5483 "maximum (%d) allowed by this processor.\n",
5485 goto error;
5486 } else {
5487 sorts[nbsorts++] = curInst;
5488 }
5489
5490#ifdef WITH_DEBUGGER
5492 xslHandleDebugger(curInst, contextNode, NULL, ctxt);
5493#endif
5494 curInst = curInst->next;
5495 }
5496 xsltDoSortFunction(ctxt, sorts, nbsorts);
5497 }
5498 xpctxt->contextSize = list->nodeNr;
5499 /*
5500 * Instantiate the sequence constructor for each selected node.
5501 */
5502 for (i = 0; i < list->nodeNr; i++) {
5503 cur = list->nodeTab[i];
5504 /*
5505 * The selected node becomes the "current node".
5506 */
5507 ctxt->node = cur;
5508 /*
5509 * An xsl:for-each can change the current context doc.
5510 * OPTIMIZE TODO: Get rid of the need to set the context doc.
5511 */
5512 if ((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL))
5513 xpctxt->doc = cur->doc;
5514
5515 xpctxt->proximityPosition = i + 1;
5516
5517 xsltApplySequenceConstructor(ctxt, cur, curInst, NULL);
5518 }
5519
5520exit:
5521error:
5522 if (res != NULL)
5523 xmlXPathFreeObject(res);
5524 /*
5525 * Restore old states.
5526 */
5527 ctxt->document = oldDocInfo;
5528 ctxt->nodeList = oldList;
5529 ctxt->node = oldContextNode;
5530 ctxt->currentTemplateRule = oldCurTemplRule;
5531
5532 xpctxt->doc = oldXPDoc;
5533 xpctxt->contextSize = oldXPContextSize;
5534 xpctxt->proximityPosition = oldXPProximityPosition;
5535}
@ XSLT_TRACE_FOR_EACH
Definition: xsltutils.h:113

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltFreeTransformContext()

void xsltFreeTransformContext ( xsltTransformContextPtr  ctxt)

xsltFreeTransformContext: @ctxt: an XSLT parser context

Free up the memory allocated by @ctxt

Definition at line 689 of file transform.c.

689 {
690 if (ctxt == NULL)
691 return;
692
693 /*
694 * Shutdown the extension modules associated to the stylesheet
695 * used if needed.
696 */
698
699 if (ctxt->xpathCtxt != NULL) {
700 ctxt->xpathCtxt->nsHash = NULL;
701 xmlXPathFreeContext(ctxt->xpathCtxt);
702 }
703 if (ctxt->templTab != NULL)
704 xmlFree(ctxt->templTab);
705 if (ctxt->varsTab != NULL)
706 xmlFree(ctxt->varsTab);
707 if (ctxt->profTab != NULL)
708 xmlFree(ctxt->profTab);
709 if ((ctxt->extrasNr > 0) && (ctxt->extras != NULL)) {
710 int i;
711
712 for (i = 0;i < ctxt->extrasNr;i++) {
713 if ((ctxt->extras[i].deallocate != NULL) &&
714 (ctxt->extras[i].info != NULL))
715 ctxt->extras[i].deallocate(ctxt->extras[i].info);
716 }
717 xmlFree(ctxt->extras);
718 }
720 xsltFreeDocuments(ctxt);
721 xsltFreeCtxtExts(ctxt);
722 xsltFreeRVTs(ctxt);
724 xmlDictFree(ctxt->dict);
725#ifdef WITH_XSLT_DEBUG
727 "freeing transformation dictionary\n");
728#endif
729 memset(ctxt, -1, sizeof(xsltTransformContext));
730 xmlFree(ctxt);
731}
void xsltFreeCtxtExts(xsltTransformContextPtr ctxt)
Definition: extensions.c:642
static void xsltTransformCacheFree(xsltTransformCachePtr cache)
Definition: transform.c:486
void xsltFreeDocuments(xsltTransformContextPtr ctxt)
Definition: documents.c:234
XMLPUBFUN void XMLCALL xmlDictFree(xmlDictPtr dict)
Definition: dict.c:802
#define memset(x, y, z)
Definition: compat.h:39
xmlFreeFunc deallocate
xsltRuntimeExtraPtr extras
xsltStackElemPtr * varsTab
void xsltFreeGlobalVariables(xsltTransformContextPtr ctxt)
Definition: variables.c:2227

Referenced by xsltApplyStylesheetInternal(), and xsltNewTransformContext().

◆ xsltGetHTMLIDs()

static int xsltGetHTMLIDs ( const xmlChar version,
const xmlChar **  publicID,
const xmlChar **  systemID 
)
static

xsltGetHTMLIDs:

Version
: the version string @publicID: used to return the public ID @systemID: used to return the system ID

Returns -1 if not found, 0 otherwise and the system and public Identifier for this given verion of HTML

Definition at line 5581 of file transform.c.

5582 {
5583 unsigned int i;
5584 if (version == NULL)
5585 return(-1);
5586 for (i = 0;i < (sizeof(xsltHTMLVersions)/sizeof(xsltHTMLVersions[1]));
5587 i++) {
5589 (const xmlChar *) xsltHTMLVersions[i].version)) {
5590 if (publicID != NULL)
5591 *publicID = (const xmlChar *) xsltHTMLVersions[i].public;
5592 if (systemID != NULL)
5593 *systemID = (const xmlChar *) xsltHTMLVersions[i].system;
5594 return(0);
5595 }
5596 }
5597 return(-1);
5598}
static xsltHTMLVersion xsltHTMLVersions[]
Definition: transform.c:5550
int __cdecl system(_In_opt_z_ const char *_Command)
const char * version
Definition: transform.c:5545

Referenced by xsltApplyStylesheetInternal(), and xsltDocumentElem().

◆ xsltGetXIncludeDefault()

int xsltGetXIncludeDefault ( void  )

xsltGetXIncludeDefault:

Provides the default state for XInclude processing

Returns 0 if there is no processing 1 otherwise

Definition at line 437 of file transform.c.

437 {
438 return(xsltDoXIncludeDefault);
439}
static int xsltDoXIncludeDefault
Definition: transform.c:416

Referenced by xsltNewTransformContext().

◆ xsltIf()

void xsltIf ( xsltTransformContextPtr  ctxt,
xmlNodePtr  contextNode,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltIf: @ctxt: a XSLT process context @contextNode: the current node in the source tree @inst: the xsl:if instruction @castedComp: compiled information of the instruction

Processes the xsl:if instruction on the source node.

Definition at line 5255 of file transform.c.

5257{
5258 int res = 0;
5259
5260#ifdef XSLT_REFACTORED
5261 xsltStyleItemIfPtr comp = (xsltStyleItemIfPtr) castedComp;
5262#else
5263 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
5264#endif
5265
5266 if ((ctxt == NULL) || (contextNode == NULL) || (inst == NULL))
5267 return;
5268 if ((comp == NULL) || (comp->test == NULL) || (comp->comp == NULL)) {
5269 xsltTransformError(ctxt, NULL, inst,
5270 "Internal error in xsltIf(): "
5271 "The XSLT 'if' instruction was not compiled.\n");
5272 return;
5273 }
5274
5275#ifdef WITH_XSLT_DEBUG_PROCESS
5277 "xsltIf: test %s\n", comp->test));
5278#endif
5279
5280#ifdef XSLT_FAST_IF
5281 {
5282 xmlDocPtr oldLocalFragmentTop = ctxt->localRVT;
5283
5284 res = xsltPreCompEvalToBoolean(ctxt, contextNode, comp);
5285
5286 /*
5287 * Cleanup fragments created during evaluation of the
5288 * "select" expression.
5289 */
5290 if (oldLocalFragmentTop != ctxt->localRVT)
5291 xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
5292 }
5293
5294#ifdef WITH_XSLT_DEBUG_PROCESS
5296 "xsltIf: test evaluate to %d\n", res));
5297#endif
5298
5299 if (res == -1) {
5300 ctxt->state = XSLT_STATE_STOPPED;
5301 goto error;
5302 }
5303 if (res == 1) {
5304 /*
5305 * Instantiate the sequence constructor of xsl:if.
5306 */
5308 contextNode, inst->children, NULL);
5309 }
5310
5311#else /* XSLT_FAST_IF */
5312 {
5313 /*
5314 * OLD CODE:
5315 */
5316 xmlXPathObjectPtr xpobj = xsltPreCompEval(ctxt, contextNode, comp);
5317 if (xpobj != NULL) {
5318 if (xpobj->type != XPATH_BOOLEAN)
5319 xpobj = xmlXPathConvertBoolean(xpobj);
5320 if (xpobj->type == XPATH_BOOLEAN) {
5321 res = xpobj->boolval;
5322
5323#ifdef WITH_XSLT_DEBUG_PROCESS
5325 "xsltIf: test evaluate to %d\n", res));
5326#endif
5327 if (res) {
5329 contextNode, inst->children, NULL);
5330 }
5331 } else {
5332
5333#ifdef WITH_XSLT_DEBUG_PROCESS
5336 "xsltIf: test didn't evaluate to a boolean\n"));
5337#endif
5338 ctxt->state = XSLT_STATE_STOPPED;
5339 }
5340 xmlXPathFreeObject(xpobj);
5341 } else {
5342 ctxt->state = XSLT_STATE_STOPPED;
5343 }
5344 }
5345#endif /* else of XSLT_FAST_IF */
5346
5347error:
5348 return;
5349}
@ XSLT_TRACE_IF
Definition: xsltutils.h:112

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltLocalVariablePop()

void xsltLocalVariablePop ( xsltTransformContextPtr  ctxt,
int  limitNr,
int  level 
)

xsltLocalVariablePop: @ctxt: the transformation context @limitNr: number of variables which should remain @level: the depth in the xsl:template's tree

Pops all variable values at the given @depth from the stack.

Returns the stored variable value NOTE: This is an internal routine and should not be called by users!

Definition at line 150 of file transform.c.

151{
153
154 if (ctxt->varsNr <= 0)
155 return;
156
157 do {
158 if (ctxt->varsNr <= limitNr)
159 break;
160 variable = ctxt->varsTab[ctxt->varsNr - 1];
161 if (variable->level <= level)
162 break;
163 if (variable->level >= 0)
165 ctxt->varsNr--;
166 } while (ctxt->varsNr != 0);
167 if (ctxt->varsNr > 0)
168 ctxt->vars = ctxt->varsTab[ctxt->varsNr - 1];
169 else
170 ctxt->vars = NULL;
171}
GLenum GLenum variable
Definition: glext.h:9031

Referenced by xsltApplyOneTemplate(), xsltApplySequenceConstructor(), and xsltApplyStylesheetInternal().

◆ xsltLocalVariablePush()

int xsltLocalVariablePush ( xsltTransformContextPtr  ctxt,
xsltStackElemPtr  variable,
int  level 
)

xsltLocalVariablePush: @ctxt: the transformation context @variable: variable to be pushed to the variable stack @level: new value for variable's level

Places the variable onto the local variable stack

Returns: 0 for success, -1 for any error NOTE: This is an internal routine and should not be called by users!

Definition at line 2188 of file transform.c.

2191{
2192 if (ctxt->varsMax == 0) {
2193 ctxt->varsMax = 10;
2194 ctxt->varsTab =
2196 sizeof(ctxt->varsTab[0]));
2197 if (ctxt->varsTab == NULL) {
2198 xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
2199 return (-1);
2200 }
2201 }
2202 if (ctxt->varsNr >= ctxt->varsMax) {
2203 ctxt->varsMax *= 2;
2204 ctxt->varsTab =
2206 ctxt->varsMax *
2207 sizeof(ctxt->varsTab[0]));
2208 if (ctxt->varsTab == NULL) {
2209 xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
2210 return (-1);
2211 }
2212 }
2213 ctxt->varsTab[ctxt->varsNr++] = variable;
2214 ctxt->vars = variable;
2215 variable->level = level;
2216 return(0);
2217}

Referenced by xsltApplyOneTemplate(), and xsltApplyXSLTTemplate().

◆ xsltMessageWrapper()

static void xsltMessageWrapper ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr comp  ATTRIBUTE_UNUSED 
)
static

Definition at line 6295 of file transform.c.

6296 {
6297 xsltMessage(ctxt, node, inst);
6298}

Referenced by xsltRegisterAllElement().

◆ xsltNewTransformContext()

xsltTransformContextPtr xsltNewTransformContext ( xsltStylesheetPtr  style,
xmlDocPtr  doc 
)

xsltNewTransformContext: @style: a parsed XSLT stylesheet @doc: the input document

Create a new XSLT TransformContext

Returns the newly allocated xsltTransformContextPtr or NULL in case of error

Definition at line 536 of file transform.c.

536 {
538 xsltDocumentPtr docu;
539 int i;
540
542
544 if (cur == NULL) {
546 "xsltNewTransformContext : malloc failed\n");
547 return(NULL);
548 }
549 memset(cur, 0, sizeof(xsltTransformContext));
550
551 cur->cache = xsltTransformCacheCreate();
552 if (cur->cache == NULL)
553 goto internal_err;
554 /*
555 * setup of the dictionary must be done early as some of the
556 * processing later like key handling may need it.
557 */
558 cur->dict = xmlDictCreateSub(style->dict);
559 cur->internalized = ((style->internalized) && (cur->dict != NULL));
560#ifdef WITH_XSLT_DEBUG
562 "Creating sub-dictionary from stylesheet for transformation\n");
563#endif
564
565 /*
566 * initialize the template stack
567 */
568 cur->templTab = (xsltTemplatePtr *)
569 xmlMalloc(10 * sizeof(xsltTemplatePtr));
570 if (cur->templTab == NULL) {
572 "xsltNewTransformContext: out of memory\n");
573 goto internal_err;
574 }
575 cur->templNr = 0;
576 cur->templMax = 5;
577 cur->templ = NULL;
578 cur->maxTemplateDepth = xsltMaxDepth;
579
580 /*
581 * initialize the variables stack
582 */
583 cur->varsTab = (xsltStackElemPtr *)
584 xmlMalloc(10 * sizeof(xsltStackElemPtr));
585 if (cur->varsTab == NULL) {
587 "xsltNewTransformContext: out of memory\n");
588 goto internal_err;
589 }
590 cur->varsNr = 0;
591 cur->varsMax = 10;
592 cur->vars = NULL;
593 cur->varsBase = 0;
594 cur->maxTemplateVars = xsltMaxVars;
595
596 /*
597 * the profiling stack is not initialized by default
598 */
599 cur->profTab = NULL;
600 cur->profNr = 0;
601 cur->profMax = 0;
602 cur->prof = 0;
603
604 cur->style = style;
605 cur->xpathCtxt = xmlXPathNewContext(doc);
606 if (cur->xpathCtxt == NULL) {
608 "xsltNewTransformContext : xmlXPathNewContext failed\n");
609 goto internal_err;
610 }
611 /*
612 * Create an XPath cache.
613 */
614 if (xmlXPathContextSetCache(cur->xpathCtxt, 1, -1, 0) == -1)
615 goto internal_err;
616 /*
617 * Initialize the extras array
618 */
619 if (style->extrasNr != 0) {
620 cur->extrasMax = style->extrasNr + 20;
621 cur->extras = (xsltRuntimeExtraPtr)
622 xmlMalloc(cur->extrasMax * sizeof(xsltRuntimeExtra));
623 if (cur->extras == NULL) {
625 "xsltNewTransformContext: out of memory\n");
626 goto internal_err;
627 }
628 cur->extrasNr = style->extrasNr;
629 for (i = 0;i < cur->extrasMax;i++) {
630 cur->extras[i].info = NULL;
631 cur->extras[i].deallocate = NULL;
632 cur->extras[i].val.ptr = NULL;
633 }
634 } else {
635 cur->extras = NULL;
636 cur->extrasNr = 0;
637 cur->extrasMax = 0;
638 }
639
642 cur->xpathCtxt->nsHash = style->nsHash;
643 /*
644 * Initialize the registered external modules
645 */
647 /*
648 * Setup document element ordering for later efficiencies
649 * (bug 133289)
650 */
652 xmlXPathOrderDocElems(doc);
653 /*
654 * Must set parserOptions before calling xsltNewDocument
655 * (bug 164530)
656 */
657 cur->parserOptions = XSLT_PARSE_OPTIONS;
658 docu = xsltNewDocument(cur, doc);
659 if (docu == NULL) {
661 "xsltNewTransformContext : xsltNewDocument failed\n");
662 goto internal_err;
663 }
664 docu->main = 1;
665 cur->document = docu;
666 cur->inst = NULL;
667 cur->outputFile = NULL;
669 cur->debugStatus = xslDebugStatus;
670 cur->traceCode = (unsigned long*) &xsltDefaultTrace;
671 cur->xinclude = xsltGetXIncludeDefault();
672 cur->keyInitLevel = 0;
673
674 return(cur);
675
676internal_err:
677 if (cur != NULL)
679 return(NULL);
680}
int xsltInitCtxtExts(xsltTransformContextPtr ctxt)
Definition: extensions.c:1016
xsltSecurityPrefsPtr xsltGetDefaultSecurityPrefs(void)
Definition: security.c:163
int xsltMaxDepth
Definition: transform.c:35
static xsltTransformCachePtr xsltTransformCacheCreate(void)
Definition: transform.c:471
int xsltGetXIncludeDefault(void)
Definition: transform.c:437
int xsltMaxVars
Definition: transform.c:36
xsltDocumentPtr xsltNewDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc)
Definition: documents.c:127
#define XSLT_REGISTER_FUNCTION_LOOKUP(ctxt)
Definition: functions.h:27
XMLPUBFUN xmlDictPtr XMLCALL xmlDictCreateSub(xmlDictPtr sub)
Definition: dict.c:624
#define XSLT_REGISTER_VARIABLE_LOOKUP(ctxt)
Definition: variables.h:30
xsltTransformContext * xsltTransformContextPtr
xsltRuntimeExtra * xsltRuntimeExtraPtr
#define XSLT_PARSE_OPTIONS
Definition: xslt.h:54

Referenced by xsltApplyStylesheetInternal().

◆ xsltNumber()

void xsltNumber ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltNumber: @ctxt: a XSLT process context @node: the node in the source tree. @inst: the xslt number node @castedComp: precomputed information

Process the xslt number node on the source node

Definition at line 4553 of file transform.c.

4555{
4556#ifdef XSLT_REFACTORED
4557 xsltStyleItemNumberPtr comp = (xsltStyleItemNumberPtr) castedComp;
4558#else
4559 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
4560#endif
4561 xmlXPathContextPtr xpctxt;
4562 xmlNsPtr *oldXPNamespaces;
4563 int oldXPNsNr;
4564
4565 if (comp == NULL) {
4566 xsltTransformError(ctxt, NULL, inst,
4567 "xsl:number : compilation failed\n");
4568 return;
4569 }
4570
4571 if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
4572 return;
4573
4574 comp->numdata.doc = inst->doc;
4575 comp->numdata.node = inst;
4576
4577 xpctxt = ctxt->xpathCtxt;
4578 oldXPNsNr = xpctxt->nsNr;
4579 oldXPNamespaces = xpctxt->namespaces;
4580
4581#ifdef XSLT_REFACTORED
4582 if (comp->inScopeNs != NULL) {
4583 xpctxt->namespaces = comp->inScopeNs->list;
4584 xpctxt->nsNr = comp->inScopeNs->xpathNumber;
4585 } else {
4586 xpctxt->namespaces = NULL;
4587 xpctxt->nsNr = 0;
4588 }
4589#else
4590 xpctxt->namespaces = comp->nsList;
4591 xpctxt->nsNr = comp->nsNr;
4592#endif
4593
4594 xsltNumberFormat(ctxt, &comp->numdata, node);
4595
4596 xpctxt->nsNr = oldXPNsNr;
4597 xpctxt->namespaces = oldXPNamespaces;
4598}
void xsltNumberFormat(xsltTransformContextPtr ctxt, xsltNumberDataPtr data, xmlNodePtr node)
Definition: numbers.c:728

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltPreCompEval()

static xmlXPathObjectPtr xsltPreCompEval ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xsltStylePreCompPtr  comp 
)
static

xsltPreCompEval: @ctxt: transform context @node: context node @comp: precompiled expression

Evaluate a precompiled XPath expression.

Definition at line 321 of file transform.c.

322 {
323 xmlXPathObjectPtr res;
324 xmlXPathContextPtr xpctxt;
325 xmlNodePtr oldXPContextNode;
326 xmlNsPtr *oldXPNamespaces;
327 int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
328
329 xpctxt = ctxt->xpathCtxt;
330 oldXPContextNode = xpctxt->node;
331 oldXPProximityPosition = xpctxt->proximityPosition;
332 oldXPContextSize = xpctxt->contextSize;
333 oldXPNsNr = xpctxt->nsNr;
334 oldXPNamespaces = xpctxt->namespaces;
335
336 xpctxt->node = node;
337#ifdef XSLT_REFACTORED
338 if (comp->inScopeNs != NULL) {
339 xpctxt->namespaces = comp->inScopeNs->list;
340 xpctxt->nsNr = comp->inScopeNs->xpathNumber;
341 } else {
342 xpctxt->namespaces = NULL;
343 xpctxt->nsNr = 0;
344 }
345#else
346 xpctxt->namespaces = comp->nsList;
347 xpctxt->nsNr = comp->nsNr;
348#endif
349
350 res = xmlXPathCompiledEval(comp->comp, xpctxt);
351
352 xpctxt->node = oldXPContextNode;
353 xpctxt->proximityPosition = oldXPProximityPosition;
354 xpctxt->contextSize = oldXPContextSize;
355 xpctxt->nsNr = oldXPNsNr;
356 xpctxt->namespaces = oldXPNamespaces;
357
358 return(res);
359}
xmlXPathCompExprPtr comp

Referenced by xsltApplyTemplates(), xsltChoose(), xsltCopyOf(), xsltForEach(), xsltIf(), and xsltValueOf().

◆ xsltPreCompEvalToBoolean()

static int xsltPreCompEvalToBoolean ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xsltStylePreCompPtr  comp 
)
static

xsltPreCompEvalToBoolean: @ctxt: transform context @node: context node @comp: precompiled expression

Evaluate a precompiled XPath expression as boolean.

Definition at line 370 of file transform.c.

371 {
372 int res;
373 xmlXPathContextPtr xpctxt;
374 xmlNodePtr oldXPContextNode;
375 xmlNsPtr *oldXPNamespaces;
376 int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
377
378 xpctxt = ctxt->xpathCtxt;
379 oldXPContextNode = xpctxt->node;
380 oldXPProximityPosition = xpctxt->proximityPosition;
381 oldXPContextSize = xpctxt->contextSize;
382 oldXPNsNr = xpctxt->nsNr;
383 oldXPNamespaces = xpctxt->namespaces;
384
385 xpctxt->node = node;
386#ifdef XSLT_REFACTORED
387 if (comp->inScopeNs != NULL) {
388 xpctxt->namespaces = comp->inScopeNs->list;
389 xpctxt->nsNr = comp->inScopeNs->xpathNumber;
390 } else {
391 xpctxt->namespaces = NULL;
392 xpctxt->nsNr = 0;
393 }
394#else
395 xpctxt->namespaces = comp->nsList;
396 xpctxt->nsNr = comp->nsNr;
397#endif
398
399 res = xmlXPathCompiledEvalToBoolean(comp->comp, xpctxt);
400
401 xpctxt->node = oldXPContextNode;
402 xpctxt->proximityPosition = oldXPProximityPosition;
403 xpctxt->contextSize = oldXPContextSize;
404 xpctxt->nsNr = oldXPNsNr;
405 xpctxt->namespaces = oldXPNamespaces;
406
407 return(res);
408}

Referenced by xsltChoose(), and xsltIf().

◆ xsltProcessingInstruction()

void xsltProcessingInstruction ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltProcessingInstruction: @ctxt: a XSLT process context @node: the node in the source tree. @inst: the xslt processing-instruction node @castedComp: precomputed information

Process the xslt processing-instruction node on the source node

Definition at line 4269 of file transform.c.

4270 {
4271#ifdef XSLT_REFACTORED
4272 xsltStyleItemPIPtr comp = (xsltStyleItemPIPtr) castedComp;
4273#else
4274 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
4275#endif
4276 const xmlChar *name;
4277 xmlChar *value = NULL;
4278 xmlNodePtr pi;
4279
4280
4281 if (ctxt->insert == NULL)
4282 return;
4283 if (comp->has_name == 0)
4284 return;
4285 if (comp->name == NULL) {
4286 name = xsltEvalAttrValueTemplate(ctxt, inst,
4287 (const xmlChar *)"name", NULL);
4288 if (name == NULL) {
4289 xsltTransformError(ctxt, NULL, inst,
4290 "xsl:processing-instruction : name is missing\n");
4291 goto error;
4292 }
4293 } else {
4294 name = comp->name;
4295 }
4296 /* TODO: check that it's both an an NCName and a PITarget. */
4297
4298
4299 value = xsltEvalTemplateString(ctxt, node, inst);
4300 if (xmlStrstr(value, BAD_CAST "?>") != NULL) {
4301 xsltTransformError(ctxt, NULL, inst,
4302 "xsl:processing-instruction: '?>' not allowed within PI content\n");
4303 goto error;
4304 }
4305#ifdef WITH_XSLT_DEBUG_PROCESS
4306 if (value == NULL) {
4308 "xsltProcessingInstruction: %s empty\n", name));
4309 } else {
4311 "xsltProcessingInstruction: %s content %s\n", name, value));
4312 }
4313#endif
4314
4315 pi = xmlNewDocPI(ctxt->insert->doc, name, value);
4316 pi = xsltAddChild(ctxt->insert, pi);
4317
4318error:
4319 if ((name != NULL) && (name != comp->name))
4320 xmlFree((xmlChar *) name);
4321 if (value != NULL)
4322 xmlFree(value);
4323}
static refpint_t pi[]
Definition: server.c:96
@ XSLT_TRACE_PI
Definition: xsltutils.h:106

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltProcessOneNode()

void xsltProcessOneNode ( xsltTransformContextPtr  ctxt,
xmlNodePtr  contextNode,
xsltStackElemPtr  withParams 
)

xsltProcessOneNode: @ctxt: a XSLT process context @contextNode: the "current node" in the source tree @withParams: extra parameters (e.g. xsl:with-param) passed to the template if any

Process the source node.

Definition at line 2064 of file transform.c.

2066{
2067 xsltTemplatePtr templ;
2068 xmlNodePtr oldNode;
2069
2070 templ = xsltGetTemplate(ctxt, contextNode, NULL);
2071 /*
2072 * If no template is found, apply the default rule.
2073 */
2074 if (templ == NULL) {
2075#ifdef WITH_XSLT_DEBUG_PROCESS
2076 if (contextNode->type == XML_DOCUMENT_NODE) {
2078 "xsltProcessOneNode: no template found for /\n"));
2079 } else if (contextNode->type == XML_CDATA_SECTION_NODE) {
2081 "xsltProcessOneNode: no template found for CDATA\n"));
2082 } else if (contextNode->type == XML_ATTRIBUTE_NODE) {
2084 "xsltProcessOneNode: no template found for attribute %s\n",
2085 ((xmlAttrPtr) contextNode)->name));
2086 } else {
2088 "xsltProcessOneNode: no template found for %s\n", contextNode->name));
2089 }
2090#endif
2091 oldNode = ctxt->node;
2092 ctxt->node = contextNode;
2093 xsltDefaultProcessOneNode(ctxt, contextNode, withParams);
2094 ctxt->node = oldNode;
2095 return;
2096 }
2097
2098 if (contextNode->type == XML_ATTRIBUTE_NODE) {
2099 xsltTemplatePtr oldCurTempRule = ctxt->currentTemplateRule;
2100 /*
2101 * Set the "current template rule".
2102 */
2103 ctxt->currentTemplateRule = templ;
2104
2105#ifdef WITH_XSLT_DEBUG_PROCESS
2107 "xsltProcessOneNode: applying template '%s' for attribute %s\n",
2108 templ->match, contextNode->name));
2109#endif
2110 xsltApplyXSLTTemplate(ctxt, contextNode, templ->content, templ, withParams);
2111
2112 ctxt->currentTemplateRule = oldCurTempRule;
2113 } else {
2114 xsltTemplatePtr oldCurTempRule = ctxt->currentTemplateRule;
2115 /*
2116 * Set the "current template rule".
2117 */
2118 ctxt->currentTemplateRule = templ;
2119
2120#ifdef WITH_XSLT_DEBUG_PROCESS
2121 if (contextNode->type == XML_DOCUMENT_NODE) {
2123 "xsltProcessOneNode: applying template '%s' for /\n",
2124 templ->match));
2125 } else {
2127 "xsltProcessOneNode: applying template '%s' for %s\n",
2128 templ->match, contextNode->name));
2129 }
2130#endif
2131 xsltApplyXSLTTemplate(ctxt, contextNode, templ->content, templ, withParams);
2132
2133 ctxt->currentTemplateRule = oldCurTempRule;
2134 }
2135}
xmlChar * match

Referenced by xsltApplyStylesheetInternal(), xsltApplyTemplates(), and xsltDefaultProcessOneNode().

◆ xsltProfileStylesheet()

xmlDocPtr xsltProfileStylesheet ( xsltStylesheetPtr  style,
xmlDocPtr  doc,
const char **  params,
FILE output 
)

xsltProfileStylesheet: @style: a parsed XSLT stylesheet @doc: a parsed XML document @params: a NULL terminated arry of parameters names/values tuples @output: a FILE * for the profiling output

Apply the stylesheet to the document and dump the profiling to the given output.

Returns the result document or NULL in case of error

Definition at line 6163 of file transform.c.

6165{
6166 xmlDocPtr res;
6167
6169 return (res);
6170}

◆ xsltRegisterAllElement()

void xsltRegisterAllElement ( xsltTransformContextPtr  ctxt)

xsltRegisterAllElement: @ctxt: the XPath context

Registers all default XSLT elements in this context

Definition at line 6307 of file transform.c.

6308{
6309 xsltRegisterExtElement(ctxt, (const xmlChar *) "apply-templates",
6312 xsltRegisterExtElement(ctxt, (const xmlChar *) "apply-imports",
6315 xsltRegisterExtElement(ctxt, (const xmlChar *) "call-template",
6318 xsltRegisterExtElement(ctxt, (const xmlChar *) "element",
6320 xsltElement);
6321 xsltRegisterExtElement(ctxt, (const xmlChar *) "attribute",
6324 xsltRegisterExtElement(ctxt, (const xmlChar *) "text",
6326 xsltText);
6327 xsltRegisterExtElement(ctxt, (const xmlChar *) "processing-instruction",
6330 xsltRegisterExtElement(ctxt, (const xmlChar *) "comment",
6332 xsltComment);
6333 xsltRegisterExtElement(ctxt, (const xmlChar *) "copy",
6335 xsltCopy);
6336 xsltRegisterExtElement(ctxt, (const xmlChar *) "value-of",
6338 xsltValueOf);
6339 xsltRegisterExtElement(ctxt, (const xmlChar *) "number",
6341 xsltNumber);
6342 xsltRegisterExtElement(ctxt, (const xmlChar *) "for-each",
6344 xsltForEach);
6345 xsltRegisterExtElement(ctxt, (const xmlChar *) "if",
6347 xsltIf);
6348 xsltRegisterExtElement(ctxt, (const xmlChar *) "choose",
6350 xsltChoose);
6351 xsltRegisterExtElement(ctxt, (const xmlChar *) "sort",
6353 xsltSort);
6354 xsltRegisterExtElement(ctxt, (const xmlChar *) "copy-of",
6356 xsltCopyOf);
6357 xsltRegisterExtElement(ctxt, (const xmlChar *) "message",
6360
6361 /*
6362 * Those don't have callable entry points but are registered anyway
6363 */
6364 xsltRegisterExtElement(ctxt, (const xmlChar *) "variable",
6366 xsltDebug);
6367 xsltRegisterExtElement(ctxt, (const xmlChar *) "param",
6369 xsltDebug);
6370 xsltRegisterExtElement(ctxt, (const xmlChar *) "with-param",
6372 xsltDebug);
6373 xsltRegisterExtElement(ctxt, (const xmlChar *) "decimal-format",
6375 xsltDebug);
6376 xsltRegisterExtElement(ctxt, (const xmlChar *) "when",
6378 xsltDebug);
6379 xsltRegisterExtElement(ctxt, (const xmlChar *) "otherwise",
6381 xsltDebug);
6382 xsltRegisterExtElement(ctxt, (const xmlChar *) "fallback",
6384 xsltDebug);
6385
6386}
int xsltRegisterExtElement(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *URI, xsltTransformFunction function)
Definition: extensions.c:621
void xsltAttribute(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: attributes.c:716
void xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: transform.c:5361
void xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: transform.c:4679
void xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: transform.c:4479
void xsltSort(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr inst, xsltElemPreCompPtr comp)
Definition: transform.c:3839
void xsltApplyImports(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
Definition: transform.c:4610
void xsltProcessingInstruction(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: transform.c:4269
static void xsltMessageWrapper(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
Definition: transform.c:6295
void xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: transform.c:4335
void xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: transform.c:4017
void xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: transform.c:5255
void xsltComment(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
Definition: transform.c:4225
void xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
Definition: transform.c:5096
void xsltText(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
Definition: transform.c:3980
void xsltCopy(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: transform.c:3861
void xsltNumber(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: transform.c:4553
void xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp)
Definition: transform.c:4782

◆ xsltReleaseLocalRVTs()

static void xsltReleaseLocalRVTs ( xsltTransformContextPtr  ctxt,
xmlDocPtr  base 
)
static

xsltReleaseLocalRVTs:

Fragments which are results of extension instructions are preserved; all other fragments are freed/cached.

Definition at line 2226 of file transform.c.

2227{
2228 xmlDocPtr cur = ctxt->localRVT, tmp;
2229
2230 if (cur == base)
2231 return;
2232 if (cur->prev != NULL)
2233 xsltTransformError(ctxt, NULL, NULL, "localRVT not head of list\n");
2234
2235 /* Reset localRVT early because some RVTs might be registered again. */
2236 ctxt->localRVT = base;
2237 if (base != NULL)
2238 base->prev = NULL;
2239
2240 do {
2241 tmp = cur;
2242 cur = (xmlDocPtr) cur->next;
2243 if (tmp->psvi == XSLT_RVT_LOCAL) {
2244 xsltReleaseRVT(ctxt, tmp);
2245 } else if (tmp->psvi == XSLT_RVT_GLOBAL) {
2246 xsltRegisterPersistRVT(ctxt, tmp);
2247 } else if (tmp->psvi == XSLT_RVT_FUNC_RESULT) {
2248 /*
2249 * This will either register the RVT again or move it to the
2250 * context variable.
2251 */
2252 xsltRegisterLocalRVT(ctxt, tmp);
2253 tmp->psvi = XSLT_RVT_FUNC_RESULT;
2254 } else {
2256 "xsltReleaseLocalRVTs: Unexpected RVT flag %p\n",
2257 tmp->psvi);
2258 }
2259 } while (cur != base);
2260}
int xsltRegisterLocalRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
Definition: variables.c:138
int xsltRegisterPersistRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
Definition: variables.c:394
#define XSLT_RVT_GLOBAL
Definition: variables.h:62
#define XSLT_RVT_FUNC_RESULT
Definition: variables.h:55
#define XSLT_RVT_LOCAL
Definition: variables.h:46

Referenced by xsltApplySequenceConstructor(), xsltApplyStylesheetInternal(), and xsltIf().

◆ xsltRunStylesheet()

int xsltRunStylesheet ( xsltStylesheetPtr  style,
xmlDocPtr  doc,
const char **  params,
const char output,
xmlSAXHandlerPtr  SAX,
xmlOutputBufferPtr  IObuf 
)

xsltRunStylesheet: @style: a parsed XSLT stylesheet @doc: a parsed XML document @params: a NULL terminated array of parameters names/values tuples @output: the URL/filename ot the generated resource if available @SAX: a SAX handler for progressive callback output (not implemented yet) @IObuf: an output buffer for progressive output (not implemented yet)

Apply the stylesheet to the document and generate the output according to @output @SAX and @IObuf. It's an error to specify both @SAX and @IObuf.

NOTE: This may lead to a non-wellformed output XML wise ! NOTE: This may also result in multiple files being generated NOTE: using IObuf, the result encoding used will be the one used for creating the output buffer, use the following macro to read it from the stylesheet XSLT_GET_IMPORT_PTR(encoding, style, encoding) NOTE: using SAX, any encoding specified in the stylesheet will be lost since the interface uses only UTF8

Returns the number of bytes written to the main resource or -1 in case of error.

Definition at line 6286 of file transform.c.

6289{
6290 return(xsltRunStylesheetUser(style, doc, params, output, SAX, IObuf,
6291 NULL, NULL));
6292}
int xsltRunStylesheetUser(xsltStylesheetPtr style, xmlDocPtr doc, const char **params, const char *output, xmlSAXHandlerPtr SAX, xmlOutputBufferPtr IObuf, FILE *profile, xsltTransformContextPtr userCtxt)
Definition: transform.c:6225

◆ xsltRunStylesheetUser()

int xsltRunStylesheetUser ( xsltStylesheetPtr  style,
xmlDocPtr  doc,
const char **  params,
const char output,
xmlSAXHandlerPtr  SAX,
xmlOutputBufferPtr  IObuf,
FILE profile,
xsltTransformContextPtr  userCtxt 
)

xsltRunStylesheetUser: @style: a parsed XSLT stylesheet @doc: a parsed XML document @params: a NULL terminated array of parameters names/values tuples @output: the URL/filename ot the generated resource if available @SAX: a SAX handler for progressive callback output (not implemented yet) @IObuf: an output buffer for progressive output (not implemented yet) @profile: profile FILE * output or NULL @userCtxt: user provided transform context

Apply the stylesheet to the document and generate the output according to @output @SAX and @IObuf. It's an error to specify both @SAX and @IObuf.

NOTE: This may lead to a non-wellformed output XML wise ! NOTE: This may also result in multiple files being generated NOTE: using IObuf, the result encoding used will be the one used for creating the output buffer, use the following macro to read it from the stylesheet XSLT_GET_IMPORT_PTR(encoding, style, encoding) NOTE: using SAX, any encoding specified in the stylesheet will be lost since the interface uses only UTF8

Returns the number of by written to the main resource or -1 in case of error.

Definition at line 6225 of file transform.c.

6229{
6230 xmlDocPtr tmp;
6231 int ret;
6232
6233 if ((output == NULL) && (SAX == NULL) && (IObuf == NULL))
6234 return (-1);
6235 if ((SAX != NULL) && (IObuf != NULL))
6236 return (-1);
6237
6238 /* unsupported yet */
6239 if (SAX != NULL) {
6240 XSLT_TODO /* xsltRunStylesheet xmlSAXHandlerPtr SAX */
6241 return (-1);
6242 }
6243
6244 tmp = xsltApplyStylesheetInternal(style, doc, params, output, profile,
6245 userCtxt);
6246 if (tmp == NULL) {
6248 "xsltRunStylesheet : run failed\n");
6249 return (-1);
6250 }
6251 if (IObuf != NULL) {
6252 /* TODO: incomplete, IObuf output not progressive */
6253 ret = xsltSaveResultTo(IObuf, tmp, style);
6254 } else {
6255 ret = xsltSaveResultToFilename(output, tmp, style, 0);
6256 }
6257 xmlFreeDoc(tmp);
6258 return (ret);
6259}
int xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, xsltStylesheetPtr style)
Definition: xsltutils.c:1460
#define XSLT_TODO
Definition: xsltutils.h:31

Referenced by xsltRunStylesheet().

◆ xsltSetXIncludeDefault()

void xsltSetXIncludeDefault ( int  xinclude)

xsltSetXIncludeDefault: @xinclude: whether to do XInclude processing

Set whether XInclude should be processed on document being loaded by default

Definition at line 425 of file transform.c.

425 {
426 xsltDoXIncludeDefault = (xinclude != 0);
427}

◆ xsltShallowCopyAttr()

static xmlAttrPtr xsltShallowCopyAttr ( xsltTransformContextPtr  ctxt,
xmlNodePtr  invocNode,
xmlNodePtr  target,
xmlAttrPtr  attr 
)
static

xsltShallowCopyAttr: @ctxt: a XSLT process context @invocNode: responsible node in the stylesheet; used for error reports @target: the element where the attribute will be grafted @attr: the attribute to be copied

Do a copy of an attribute. Called by:

Returns: a new xmlAttrPtr, or NULL in case of error.

Definition at line 1121 of file transform.c.

1123{
1125 xmlChar *value;
1126
1127 if (attr == NULL)
1128 return(NULL);
1129
1130 if (target->type != XML_ELEMENT_NODE) {
1131 xsltTransformError(ctxt, NULL, invocNode,
1132 "Cannot add an attribute node to a non-element node.\n");
1133 return(NULL);
1134 }
1135
1136 if (target->children != NULL) {
1137 xsltTransformError(ctxt, NULL, invocNode,
1138 "Attribute nodes must be added before "
1139 "any child nodes to an element.\n");
1140 return(NULL);
1141 }
1142
1143 value = xmlNodeListGetString(attr->doc, attr->children, 1);
1144 if (attr->ns != NULL) {
1145 xmlNsPtr ns;
1146
1147 ns = xsltGetSpecialNamespace(ctxt, invocNode,
1148 attr->ns->href, attr->ns->prefix, target);
1149 if (ns == NULL) {
1150 xsltTransformError(ctxt, NULL, invocNode,
1151 "Namespace fixup error: Failed to acquire an in-scope "
1152 "namespace binding of the copied attribute '{%s}%s'.\n",
1153 attr->ns->href, attr->name);
1154 /*
1155 * TODO: Should we just stop here?
1156 */
1157 }
1158 /*
1159 * Note that xmlSetNsProp() will take care of duplicates
1160 * and assigns the new namespace even to a duplicate.
1161 */
1162 copy = xmlSetNsProp(target, ns, attr->name, value);
1163 } else {
1164 copy = xmlSetNsProp(target, NULL, attr->name, value);
1165 }
1166 if (value != NULL)
1167 xmlFree(value);
1168
1169 if (copy == NULL)
1170 return(NULL);
1171
1172#if 0
1173 /*
1174 * NOTE: This was optimized according to bug #342695.
1175 * TODO: Can this further be optimized, if source and target
1176 * share the same dict and attr->children is just 1 text node
1177 * which is in the dict? How probable is such a case?
1178 */
1179 /*
1180 * TODO: Do we need to create an empty text node if the value
1181 * is the empty string?
1182 */
1183 value = xmlNodeListGetString(attr->doc, attr->children, 1);
1184 if (value != NULL) {
1185 txtNode = xmlNewDocText(target->doc, NULL);
1186 if (txtNode == NULL)
1187 return(NULL);
1188 if ((target->doc != NULL) &&
1189 (target->doc->dict != NULL))
1190 {
1191 txtNode->content =
1192 (xmlChar *) xmlDictLookup(target->doc->dict,
1193 BAD_CAST value, -1);
1194 xmlFree(value);
1195 } else
1196 txtNode->content = value;
1197 copy->children = txtNode;
1198 }
1199#endif
1200
1201 return(copy);
1202}
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocText(const xmlDoc *doc, const xmlChar *content)

Referenced by xsltCopy(), xsltCopyOf(), and xsltCopyTree().

◆ xsltShallowCopyElem()

static xmlNodePtr xsltShallowCopyElem ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  insert,
int  isLRE 
)
static

xsltShallowCopyElem: @ctxt: the XSLT process context @node: the element node in the source tree or the Literal Result Element @insert: the parent in the result tree @isLRE: if @node is a Literal Result Element

Make a copy of the element node @node and insert it as last child of @insert.

URGENT TODO: The problem with this one (for the non-refactored code) is that it is used for both, Literal Result Elements and copying input nodes.

BIG NOTE: This is only called for XML_ELEMENT_NODEs.

Called from: xsltApplySequenceConstructor() (for Literal Result Elements - which is a problem) xsltCopy() (for shallow-copying elements via xsl:copy)

Returns a pointer to the new node, or NULL in case of error

Definition at line 1296 of file transform.c.

1298{
1300
1301 if ((node->type == XML_DTD_NODE) || (insert == NULL))
1302 return(NULL);
1303 if ((node->type == XML_TEXT_NODE) ||
1304 (node->type == XML_CDATA_SECTION_NODE))
1305 return(xsltCopyText(ctxt, insert, node, 0));
1306
1307 copy = xmlDocCopyNode(node, insert->doc, 0);
1308 if (copy != NULL) {
1309 copy->doc = ctxt->output;
1311 if (copy == NULL) {
1313 "xsltShallowCopyElem: copy failed\n");
1314 return (copy);
1315 }
1316
1317 if (node->type == XML_ELEMENT_NODE) {
1318 /*
1319 * Add namespaces as they are needed
1320 */
1321 if (node->nsDef != NULL) {
1322 /*
1323 * TODO: Remove the LRE case in the refactored code
1324 * gets enabled.
1325 */
1326 if (isLRE)
1327 xsltCopyNamespaceList(ctxt, copy, node->nsDef);
1328 else
1330 }
1331
1332 /*
1333 * URGENT TODO: The problem with this is that it does not
1334 * copy over all namespace nodes in scope.
1335 * The damn thing about this is, that we would need to
1336 * use the xmlGetNsList(), for every single node; this is
1337 * also done in xsltCopyTree(), but only for the top node.
1338 */
1339 if (node->ns != NULL) {
1340 if (isLRE) {
1341 /*
1342 * REVISIT TODO: Since the non-refactored code still does
1343 * ns-aliasing, we need to call xsltGetNamespace() here.
1344 * Remove this when ready.
1345 */
1346 copy->ns = xsltGetNamespace(ctxt, node, node->ns, copy);
1347 } else {
1348 copy->ns = xsltGetSpecialNamespace(ctxt,
1349 node, node->ns->href, node->ns->prefix, copy);
1350
1351 }
1352 } else if ((insert->type == XML_ELEMENT_NODE) &&
1353 (insert->ns != NULL))
1354 {
1355 /*
1356 * "Undeclare" the default namespace.
1357 */
1359 }
1360 }
1361 } else {
1363 "xsltShallowCopyElem: copy %s failed\n", node->name);
1364 }
1365 return(copy);
1366}

Referenced by xsltApplySequenceConstructor(), and xsltCopy().

◆ xsltShallowCopyNsNode()

static xmlNsPtr xsltShallowCopyNsNode ( xsltTransformContextPtr  ctxt,
xmlNodePtr  invocNode,
xmlNodePtr  insert,
xmlNsPtr  ns 
)
static

xsltShallowCopyNsNode: @ctxt: the XSLT transformation context @invocNode: responsible node in the stylesheet; used for error reports @insert: the target element node in the result tree @ns: the namespace node

This is used for copying ns-nodes with xsl:copy-of and xsl:copy.

Returns a new/existing ns-node, or NULL.

Definition at line 1481 of file transform.c.

1485{
1486 /*
1487 * TODO: Contrary to header comments, this is declared as int.
1488 * be modified to return a node pointer, or NULL if any error
1489 */
1490 xmlNsPtr tmpns;
1491
1492 if ((insert == NULL) || (insert->type != XML_ELEMENT_NODE))
1493 return(NULL);
1494
1495 if (insert->children != NULL) {
1496 xsltTransformError(ctxt, NULL, invocNode,
1497 "Namespace nodes must be added before "
1498 "any child nodes are added to an element.\n");
1499 return(NULL);
1500 }
1501 /*
1502 * BIG NOTE: Xalan-J simply overwrites any ns-decls with
1503 * an equal prefix. We definitively won't do that.
1504 *
1505 * MSXML 4.0 and the .NET ignores ns-decls for which an
1506 * equal prefix is already in use.
1507 *
1508 * Saxon raises an error like:
1509 * "net.sf.saxon.xpath.DynamicError: Cannot create two namespace
1510 * nodes with the same name".
1511 *
1512 * NOTE: We'll currently follow MSXML here.
1513 * REVISIT TODO: Check if it's better to follow Saxon here.
1514 */
1515 if (ns->prefix == NULL) {
1516 /*
1517 * If we are adding ns-nodes to an element using e.g.
1518 * <xsl:copy-of select="/foo/namespace::*">, then we need
1519 * to ensure that we don't incorrectly declare a default
1520 * namespace on an element in no namespace, which otherwise
1521 * would move the element incorrectly into a namespace, if
1522 * the node tree is serialized.
1523 */
1524 if (insert->ns == NULL)
1525 goto occupied;
1526 } else if ((ns->prefix[0] == 'x') &&
1527 xmlStrEqual(ns->prefix, BAD_CAST "xml"))
1528 {
1529 /*
1530 * The XML namespace is built in.
1531 */
1532 return(NULL);
1533 }
1534
1535 if (insert->nsDef != NULL) {
1536 tmpns = insert->nsDef;
1537 do {
1538 if ((tmpns->prefix == NULL) == (ns->prefix == NULL)) {
1539 if ((tmpns->prefix == ns->prefix) ||
1540 xmlStrEqual(tmpns->prefix, ns->prefix))
1541 {
1542 /*
1543 * Same prefix.
1544 */
1545 if (xmlStrEqual(tmpns->href, ns->href))
1546 return(NULL);
1547 goto occupied;
1548 }
1549 }
1550 tmpns = tmpns->next;
1551 } while (tmpns != NULL);
1552 }
1553 tmpns = xmlSearchNs(insert->doc, insert, ns->prefix);
1554 if ((tmpns != NULL) && xmlStrEqual(tmpns->href, ns->href))
1555 return(NULL);
1556 /*
1557 * Declare a new namespace.
1558 * TODO: The problem (wrt efficiency) with this xmlNewNs() is
1559 * that it will again search the already declared namespaces
1560 * for a duplicate :-/
1561 */
1562 return(xmlNewNs(insert, ns->href, ns->prefix));
1563
1564occupied:
1565 /*
1566 * TODO: We could as well raise an error here (like Saxon does),
1567 * or at least generate a warning.
1568 */
1569 return(NULL);
1570}
const xmlChar * href
Definition: tree.h:392
const xmlChar * prefix
Definition: tree.h:393

Referenced by xsltCopy(), and xsltCopyTree().

◆ xsltSort()

void xsltSort ( xsltTransformContextPtr  ctxt,
xmlNodePtr node  ATTRIBUTE_UNUSED,
xmlNodePtr  inst,
xsltElemPreCompPtr  comp 
)

xsltSort: @ctxt: a XSLT process context @node: the node in the source tree. @inst: the xslt sort node @comp: precomputed information

function attached to xsl:sort nodes, but this should not be called directly

Definition at line 3839 of file transform.c.

3841 {
3842 if (comp == NULL) {
3843 xsltTransformError(ctxt, NULL, inst,
3844 "xsl:sort : compilation failed\n");
3845 return;
3846 }
3847 xsltTransformError(ctxt, NULL, inst,
3848 "xsl:sort : improper use this should not be reached\n");
3849}

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltTemplateParamsCleanup()

static void xsltTemplateParamsCleanup ( xsltTransformContextPtr  ctxt)
static

xsltTemplateParamsCleanup:

Removes xsl:param and xsl:with-param items from the variable-stack. Only xsl:with-param items are not freed.

Definition at line 180 of file transform.c.

181{
183
184 for (; ctxt->varsNr > ctxt->varsBase; ctxt->varsNr--) {
185 param = ctxt->varsTab[ctxt->varsNr -1];
186 /*
187 * Free xsl:param items.
188 * xsl:with-param items will have a level of -1 or -2.
189 */
190 if (param->level >= 0) {
192 }
193 }
194 if (ctxt->varsNr > 0)
195 ctxt->vars = ctxt->varsTab[ctxt->varsNr - 1];
196 else
197 ctxt->vars = NULL;
198}

Referenced by xsltApplyXSLTTemplate().

◆ xsltText()

void xsltText ( xsltTransformContextPtr  ctxt,
xmlNodePtr node  ATTRIBUTE_UNUSED,
xmlNodePtr  inst,
xsltElemPreCompPtr comp  ATTRIBUTE_UNUSED 
)

xsltText: @ctxt: a XSLT process context @node: the node in the source tree. @inst: the xslt text node @comp: precomputed information

Process the xslt text node on the source node

Definition at line 3980 of file transform.c.

3981 {
3982 if ((inst->children != NULL) && (comp != NULL)) {
3983 xmlNodePtr text = inst->children;
3985
3986 while (text != NULL) {
3987 if ((text->type != XML_TEXT_NODE) &&
3988 (text->type != XML_CDATA_SECTION_NODE)) {
3989 xsltTransformError(ctxt, NULL, inst,
3990 "xsl:text content problem\n");
3991 break;
3992 }
3993 copy = xmlNewDocText(ctxt->output, text->content);
3994 if (text->type != XML_CDATA_SECTION_NODE) {
3995#ifdef WITH_XSLT_DEBUG_PARSING
3997 "Disable escaping: %s\n", text->content);
3998#endif
3999 copy->name = xmlStringTextNoenc;
4000 }
4001 copy = xsltAddChild(ctxt->insert, copy);
4002 text = text->next;
4003 }
4004 }
4005}
const WCHAR * text
Definition: package.c:1799

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

◆ xsltTransformCacheCreate()

static xsltTransformCachePtr xsltTransformCacheCreate ( void  )
static

Definition at line 471 of file transform.c.

472{
474
476 if (ret == NULL) {
478 "xsltTransformCacheCreate : malloc failed\n");
479 return(NULL);
480 }
481 memset(ret, 0, sizeof(xsltTransformCache));
482 return(ret);
483}
xsltTransformCache * xsltTransformCachePtr

Referenced by xsltNewTransformContext().

◆ xsltTransformCacheFree()

static void xsltTransformCacheFree ( xsltTransformCachePtr  cache)
static

Definition at line 486 of file transform.c.

487{
488 if (cache == NULL)
489 return;
490 /*
491 * Free tree fragments.
492 */
493 if (cache->RVT) {
494 xmlDocPtr tmp, cur = cache->RVT;
495 while (cur) {
496 tmp = cur;
497 cur = (xmlDocPtr) cur->next;
498 if (tmp->_private != NULL) {
499 /*
500 * Tree the document info.
501 */
503 xmlFree(tmp->_private);
504 }
505 xmlFreeDoc(tmp);
506 }
507 }
508 /*
509 * Free vars/params.
510 */
511 if (cache->stackItems) {
512 xsltStackElemPtr tmp, cur = cache->stackItems;
513 while (cur) {
514 tmp = cur;
515 cur = cur->next;
516 /*
517 * REVISIT TODO: Should be call a destruction-function
518 * instead?
519 */
520 xmlFree(tmp);
521 }
522 }
523 xmlFree(cache);
524}
void xsltFreeDocumentKeys(xsltDocumentPtr idoc)
Definition: keys.c:925
void * _private
Definition: tree.h:552
Definition: cache.c:49

Referenced by xsltFreeTransformContext().

◆ xsltValueOf()

void xsltValueOf ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNodePtr  inst,
xsltElemPreCompPtr  castedComp 
)

xsltValueOf: @ctxt: a XSLT process context @node: the node in the source tree. @inst: the xslt value-of node @castedComp: precomputed information

Process the xslt value-of node on the source node

Definition at line 4479 of file transform.c.

4481{
4482#ifdef XSLT_REFACTORED
4483 xsltStyleItemValueOfPtr comp = (xsltStyleItemValueOfPtr) castedComp;
4484#else
4485 xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
4486#endif
4487 xmlXPathObjectPtr res = NULL;
4488 xmlChar *value = NULL;
4489
4490 if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
4491 return;
4492
4493 if ((comp == NULL) || (comp->select == NULL) || (comp->comp == NULL)) {
4494 xsltTransformError(ctxt, NULL, inst,
4495 "Internal error in xsltValueOf(): "
4496 "The XSLT 'value-of' instruction was not compiled.\n");
4497 return;
4498 }
4499
4500#ifdef WITH_XSLT_DEBUG_PROCESS
4502 "xsltValueOf: select %s\n", comp->select));
4503#endif
4504
4505 res = xsltPreCompEval(ctxt, node, comp);
4506
4507 /*
4508 * Cast the XPath object to string.
4509 */
4510 if (res != NULL) {
4511 value = xmlXPathCastToString(res);
4512 if (value == NULL) {
4513 xsltTransformError(ctxt, NULL, inst,
4514 "Internal error in xsltValueOf(): "
4515 "failed to cast an XPath object to string.\n");
4516 ctxt->state = XSLT_STATE_STOPPED;
4517 goto error;
4518 }
4519 if (value[0] != 0) {
4520 xsltCopyTextString(ctxt, ctxt->insert, value, comp->noescape);
4521 }
4522 } else {
4523 xsltTransformError(ctxt, NULL, inst,
4524 "XPath evaluation returned no result.\n");
4525 ctxt->state = XSLT_STATE_STOPPED;
4526 goto error;
4527 }
4528
4529#ifdef WITH_XSLT_DEBUG_PROCESS
4530 if (value) {
4532 "xsltValueOf: result '%s'\n", value));
4533 }
4534#endif
4535
4536error:
4537 if (value != NULL)
4538 xmlFree(value);
4539 if (res != NULL)
4540 xmlXPathFreeObject(res);
4541}
@ XSLT_TRACE_VALUE_OF
Definition: xsltutils.h:108

Referenced by xsltNewStylePreComp(), and xsltRegisterAllElement().

Variable Documentation

◆ xsltDefaultTrace

unsigned long xsltDefaultTrace = (unsigned long) XSLT_TRACE_ALL
static

◆ xsltDoXIncludeDefault

int xsltDoXIncludeDefault = 0
static

Definition at line 416 of file transform.c.

Referenced by xsltGetXIncludeDefault(), and xsltSetXIncludeDefault().

◆ xsltHTMLVersions

xsltHTMLVersion xsltHTMLVersions[]
static
Initial value:
= {
{ "5", NULL, "about:legacy-compat" },
{ "4.01frame", "-//W3C//DTD HTML 4.01 Frameset//EN",
"http://www.w3.org/TR/1999/REC-html401-19991224/frameset.dtd"},
{ "4.01strict", "-//W3C//DTD HTML 4.01//EN",
"http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd"},
{ "4.01trans", "-//W3C//DTD HTML 4.01 Transitional//EN",
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd"},
{ "4.01", "-//W3C//DTD HTML 4.01 Transitional//EN",
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd"},
{ "4.0strict", "-//W3C//DTD HTML 4.01//EN",
"http://www.w3.org/TR/html4/strict.dtd"},
{ "4.0trans", "-//W3C//DTD HTML 4.01 Transitional//EN",
"http://www.w3.org/TR/html4/loose.dtd"},
{ "4.0frame", "-//W3C//DTD HTML 4.01 Frameset//EN",
"http://www.w3.org/TR/html4/frameset.dtd"},
{ "4.0", "-//W3C//DTD HTML 4.01 Transitional//EN",
"http://www.w3.org/TR/html4/loose.dtd"},
{ "3.2", "-//W3C//DTD HTML 3.2//EN", NULL }
}

Definition at line 5550 of file transform.c.

Referenced by xsltGetHTMLIDs().

◆ xsltMaxDepth

int xsltMaxDepth = 3000

Definition at line 35 of file transform.c.

Referenced by xsltNewTransformContext().

◆ xsltMaxVars

int xsltMaxVars = 15000

Definition at line 36 of file transform.c.

Referenced by xsltNewTransformContext().