ReactOS 0.4.15-dev-7924-g5949c20
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;