/* * transform.c: Implementation of the XSL Transformation 1.0 engine * transform part, i.e. applying a Stylesheet to a document * * References: * http://www.w3.org/TR/1999/REC-xslt-19991116 * * Michael Kay "XSLT Programmer's Reference" pp 637-643 * Writing Multiple Output Files * * XSLT-1.1 Working Draft * http://www.w3.org/TR/xslt11#multiple-output * * See Copyright for the status of this software. * * [email protected] */ #define IN_LIBXSLT #include "libxslt.h" #include <limits.h> #include <string.h> #include <stdio.h> #include <stddef.h> #include <libxml/xmlmemory.h> #include <libxml/parser.h> #include <libxml/tree.h> #include <libxml/valid.h> #include <libxml/hash.h> #include <libxml/encoding.h> #include <libxml/xmlerror.h> #include <libxml/xpath.h> #include <libxml/parserInternals.h> #include <libxml/xpathInternals.h> #include <libxml/HTMLtree.h> #include <libxml/debugXML.h> #include <libxml/uri.h> #include "xslt.h" #include "xsltInternals.h" #include "xsltutils.h" #include "xsltlocale.h" #include "pattern.h" #include "transform.h" #include "variables.h" #include "numbersInternals.h" #include "namespaces.h" #include "attributes.h" #include "templates.h" #include "imports.h" #include "keys.h" #include "documents.h" #include "extensions.h" #include "extra.h" #include "preproc.h" #include "security.h" #ifdef WITH_XSLT_DEBUG #define WITH_XSLT_DEBUG_EXTRA #define WITH_XSLT_DEBUG_PROCESS #define WITH_XSLT_DEBUG_VARIABLE #endif #define XSLT_GENERATE_HTML_DOCTYPE #ifdef XSLT_GENERATE_HTML_DOCTYPE static int xsltGetHTMLIDs(const xmlChar *version, const xmlChar **publicID, const xmlChar **systemID); #endif int xsltMaxDepth = …; int xsltMaxVars = …; /* * Useful macros */ #ifndef FALSE #define FALSE … #define TRUE … #endif #define IS_BLANK_NODE(n) … /* * Forward declarations */ 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); /** * 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 */ static int templPush(xsltTransformContextPtr ctxt, xsltTemplatePtr value) { … } /** * templPop: * @ctxt: the transformation context * * Pop a template value from the stack * * Returns the stored template value */ static xsltTemplatePtr templPop(xsltTransformContextPtr ctxt) { … } /** * xsltLocalVariablePop: * @ctxt: the transformation context * @limitNr: number of variables which should remain * @level: the depth in the xsl:template's tree * * Pops all variable values at the given @depth from the stack. * * Returns the stored variable value * **NOTE:** * This is an internal routine and should not be called by users! */ void xsltLocalVariablePop(xsltTransformContextPtr ctxt, int limitNr, int level) { … } /** * xsltTemplateParamsCleanup: * * Removes xsl:param and xsl:with-param items from the * variable-stack. Only xsl:with-param items are not freed. */ static void xsltTemplateParamsCleanup(xsltTransformContextPtr ctxt) { … } #ifdef WITH_PROFILER /** * profPush: * @ctxt: the transformation context * @value: the profiling value to push on the stack * * Push a profiling value on the stack * * Returns the new index in the stack or 0 in case of error */ static int profPush(xsltTransformContextPtr ctxt, long value) { … } /** * profPop: * @ctxt: the transformation context * * Pop a profiling value from the stack * * Returns the stored profiling value */ static long profPop(xsltTransformContextPtr ctxt) { … } static void profCallgraphAdd(xsltTemplatePtr templ, xsltTemplatePtr parent) { … } #endif /* WITH_PROFILER */ /** * xsltPreCompEval: * @ctxt: transform context * @node: context node * @comp: precompiled expression * * Evaluate a precompiled XPath expression. */ static xmlXPathObjectPtr xsltPreCompEval(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStylePreCompPtr comp) { … } /** * xsltPreCompEvalToBoolean: * @ctxt: transform context * @node: context node * @comp: precompiled expression * * Evaluate a precompiled XPath expression as boolean. */ static int xsltPreCompEvalToBoolean(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStylePreCompPtr comp) { … } /************************************************************************ * * * XInclude default settings * * * ************************************************************************/ static int xsltDoXIncludeDefault = …; /** * xsltSetXIncludeDefault: * @xinclude: whether to do XInclude processing * * Set whether XInclude should be processed on document being loaded by default */ void xsltSetXIncludeDefault(int xinclude) { … } /** * xsltGetXIncludeDefault: * * Provides the default state for XInclude processing * * Returns 0 if there is no processing 1 otherwise */ int xsltGetXIncludeDefault(void) { … } static unsigned long xsltDefaultTrace = …; /** * xsltDebugSetDefaultTrace: * @val: tracing level mask * * Set the default debug tracing level mask */ void xsltDebugSetDefaultTrace(xsltDebugTraceCodes val) { … } /** * xsltDebugGetDefaultTrace: * * Get the current default debug tracing level mask * * Returns the current default debug tracing level mask */ xsltDebugTraceCodes xsltDebugGetDefaultTrace(void) { … } /************************************************************************ * * * Handling of Transformation Contexts * * * ************************************************************************/ static xsltTransformCachePtr xsltTransformCacheCreate(void) { … } static void xsltTransformCacheFree(xsltTransformCachePtr cache) { … } /** * xsltNewTransformContext: * @style: a parsed XSLT stylesheet * @doc: the input document * * Create a new XSLT TransformContext * * Returns the newly allocated xsltTransformContextPtr or NULL in case of error */ xsltTransformContextPtr xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { … } /** * xsltFreeTransformContext: * @ctxt: an XSLT transform context * * Free up the memory allocated by @ctxt */ void xsltFreeTransformContext(xsltTransformContextPtr ctxt) { … } /************************************************************************ * * * Copy of Nodes in an XSLT fashion * * * ************************************************************************/ /** * 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 */ static xmlNodePtr xsltAddChild(xmlNodePtr parent, xmlNodePtr cur) { … } /** * 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 */ static xmlNodePtr xsltAddTextString(xsltTransformContextPtr ctxt, xmlNodePtr target, const xmlChar *string, int len) { … } /** * 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. */ xmlNodePtr xsltCopyTextString(xsltTransformContextPtr ctxt, xmlNodePtr target, const xmlChar *string, int noescape) { … } /** * 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. */ static xmlNodePtr xsltCopyText(xsltTransformContextPtr ctxt, xmlNodePtr target, xmlNodePtr cur, int interned) { … } /** * xsltShallowCopyAttr: * @ctxt: a XSLT process context * @invocNode: responsible node in the stylesheet; used for error reports * @target: the element where the attribute will be grafted * @attr: the attribute to be copied * * Do a copy of an attribute. * Called by: * - xsltCopyTree() * - xsltCopyOf() * - xsltCopy() * * Returns: a new xmlAttrPtr, or NULL in case of error. */ static xmlAttrPtr xsltShallowCopyAttr(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr target, xmlAttrPtr attr) { … } /** * 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: * - xsltCopyTree() * * Returns 0 on success and -1 on errors and internal errors. */ static int xsltCopyAttrListNoOverwrite(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr target, xmlAttrPtr attr) { … } /** * xsltShallowCopyElem: * @ctxt: the XSLT process context * @node: the element node in the source tree * or the Literal Result Element * @insert: the parent in the result tree * @isLRE: if @node is a Literal Result Element * * Make a copy of the element node @node * and insert it as last child of @insert. * * URGENT TODO: The problem with this one (for the non-refactored code) * is that it is used for both, Literal Result Elements *and* * copying input nodes. * * BIG NOTE: This is only called for XML_ELEMENT_NODEs. * * Called from: * xsltApplySequenceConstructor() * (for Literal Result Elements - which is a problem) * xsltCopy() (for shallow-copying elements via xsl:copy) * * Returns a pointer to the new node, or NULL in case of error */ static xmlNodePtr xsltShallowCopyElem(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr insert, int isLRE) { … } /** * 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: * - xsltCopyOf() * * Returns a pointer to the new list, or NULL in case of error */ static xmlNodePtr xsltCopyTreeList(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr list, xmlNodePtr insert, int isLRE, int topElemVisited) { … } /** * 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. */ static xmlNsPtr xsltCopyNamespaceListInternal(xmlNodePtr elem, xmlNsPtr ns) { … } /** * xsltShallowCopyNsNode: * @ctxt: the XSLT transformation context * @invocNode: responsible node in the stylesheet; used for error reports * @insert: the target element node in the result tree * @ns: the namespace node * * This is used for copying ns-nodes with xsl:copy-of and xsl:copy. * * Returns a new/existing ns-node, or NULL. */ static xmlNsPtr xsltShallowCopyNsNode(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr insert, xmlNsPtr ns) { … } /** * 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: * - xsltCopyOf() * * Returns a pointer to the new tree, or NULL in case of error */ static xmlNodePtr xsltCopyTree(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, xmlNodePtr node, xmlNodePtr insert, int isLRE, int topElemVisited) { … } /************************************************************************ * * * Error/fallback processing * * * ************************************************************************/ /** * 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 */ static int xsltApplyFallbacks(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst) { … } /************************************************************************ * * * Default processing * * * ************************************************************************/ /** * 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. */ static void xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStackElemPtr params) { … } /** * xsltProcessOneNode: * @ctxt: a XSLT process context * @contextNode: the "current node" in the source tree * @withParams: extra parameters (e.g. xsl:with-param) passed to the * template if any * * Process the source node. */ void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xsltStackElemPtr withParams) { … } #ifdef WITH_DEBUGGER static xmlNodePtr xsltDebuggerStartSequenceConstructor(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr list, xsltTemplatePtr templ, int *addCallResult) { xmlNodePtr debugedNode = NULL; if (ctxt->debugStatus != XSLT_DEBUG_NONE) { if (templ) { *addCallResult = xslAddCall(templ, templ->elem); } else { *addCallResult = xslAddCall(NULL, list); } switch (ctxt->debugStatus) { case XSLT_DEBUG_RUN_RESTART: case XSLT_DEBUG_QUIT: if (*addCallResult) xslDropCall(); return(NULL); } if (templ) { xslHandleDebugger(templ->elem, contextNode, templ, ctxt); debugedNode = templ->elem; } else if (list) { xslHandleDebugger(list, contextNode, templ, ctxt); debugedNode = list; } else if (ctxt->inst) { xslHandleDebugger(ctxt->inst, contextNode, templ, ctxt); debugedNode = ctxt->inst; } } return(debugedNode); } #endif /* WITH_DEBUGGER */ /** * xsltLocalVariablePush: * @ctxt: the transformation context * @variable: variable to be pushed to the variable stack * @level: new value for variable's level * * Places the variable onto the local variable stack * * Returns: 0 for success, -1 for any error * **NOTE:** * This is an internal routine and should not be called by users! */ int xsltLocalVariablePush(xsltTransformContextPtr ctxt, xsltStackElemPtr variable, int level) { … } /** * xsltReleaseLocalRVTs: * * Fragments which are results of extension instructions * are preserved; all other fragments are freed/cached. */ static void xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base) { … } /** * 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. */ static void xsltApplySequenceConstructor(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr list, xsltTemplatePtr templ) { … } /* * xsltApplyXSLTTemplate: * @ctxt: a XSLT transformation context * @contextNode: the node in the source tree. * @list: the nodes of a sequence constructor; * (plus leading xsl:param elements) * @templ: the compiled xsl:template declaration; * NULL if a sequence constructor * @withParams: a set of caller-parameters (xsl:with-param) or NULL * * Called by: * - xsltApplyImports() * - xsltCallTemplate() * - xsltDefaultProcessOneNode() * - xsltProcessOneNode() */ static void xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr list, xsltTemplatePtr templ, xsltStackElemPtr withParams) { … } /** * 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: * - xsltEvalVariable() (variables.c) * - exsltFuncFunctionFunction() (libexsl/functions.c) */ void xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr list, xsltTemplatePtr templ ATTRIBUTE_UNUSED, xsltStackElemPtr params) { … } /************************************************************************ * * * XSLT-1.1 extensions * * * ************************************************************************/ /** * 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 */ void xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp) { … } /************************************************************************ * * * Most of the XSLT-1.0 transformations * * * ************************************************************************/ /** * xsltSort: * @ctxt: a XSLT process context * @node: the node in the source tree. * @inst: the xslt sort node * @comp: precomputed information * * function attached to xsl:sort nodes, but this should not be * called directly */ void xsltSort(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr inst, xsltElemPreCompPtr comp) { … } /** * 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. */ void xsltCopy(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp) { … } /** * xsltText: * @ctxt: a XSLT process context * @node: the node in the source tree. * @inst: the xslt text node * @comp: precomputed information * * Process the xslt text node on the source node */ void xsltText(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED) { … } /** * xsltElement: * @ctxt: a XSLT process context * @node: the node in the source tree. * @inst: the xslt element node * @castedComp: precomputed information * * Process the xslt element node on the source node */ void xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp) { … } /** * 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 */ void xsltComment(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED) { … } /** * xsltProcessingInstruction: * @ctxt: a XSLT process context * @node: the node in the source tree. * @inst: the xslt processing-instruction node * @castedComp: precomputed information * * Process the xslt processing-instruction node on the source node */ void xsltProcessingInstruction(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. */ void xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp) { … } /** * xsltValueOf: * @ctxt: a XSLT process context * @node: the node in the source tree. * @inst: the xslt value-of node * @castedComp: precomputed information * * Process the xslt value-of node on the source node */ void xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp) { … } /** * xsltNumber: * @ctxt: a XSLT process context * @node: the node in the source tree. * @inst: the xslt number node * @castedComp: precomputed information * * Process the xslt number node on the source node */ void xsltNumber(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp) { … } /** * 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. */ void xsltApplyImports(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED) { … } /** * 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. */ void xsltCallTemplate(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. */ void xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, xsltElemPreCompPtr castedComp) { … } /** * 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. */ void xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr comp ATTRIBUTE_UNUSED) { … } /** * xsltIf: * @ctxt: a XSLT process context * @contextNode: the current node in the source tree * @inst: the xsl:if instruction * @castedComp: compiled information of the instruction * * Processes the xsl:if instruction on the source node. */ void xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr castedComp) { … } /** * xsltForEach: * @ctxt: an XSLT transformation context * @contextNode: the "current node" in the source tree * @inst: the element node of the xsl:for-each instruction * @castedComp: the compiled information of the instruction * * Process the xslt for-each node on the source node */ void xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst, xsltElemPreCompPtr castedComp) { … } /************************************************************************ * * * Generic interface * * * ************************************************************************/ #ifdef XSLT_GENERATE_HTML_DOCTYPE xsltHTMLVersion; static xsltHTMLVersion xsltHTMLVersions[] = …; /** * xsltGetHTMLIDs: * @version: the version string * @publicID: used to return the public ID * @systemID: used to return the system ID * * Returns -1 if not found, 0 otherwise and the system and public * Identifier for this given verion of HTML */ static int xsltGetHTMLIDs(const xmlChar *version, const xmlChar **publicID, const xmlChar **systemID) { … } #endif /** * xsltApplyStripSpaces: * @ctxt: a XSLT process context * @node: the root of the XML tree * * Strip the unwanted ignorable spaces from the input tree */ void xsltApplyStripSpaces(xsltTransformContextPtr ctxt, xmlNodePtr node) { … } static int xsltCountKeys(xsltTransformContextPtr ctxt) { … } /** * xsltCleanupSourceDoc: * @doc: Document * * Resets source node flags and ids stored in 'psvi' member. */ static void xsltCleanupSourceDoc(xmlDocPtr doc) { … } /** * 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 */ static xmlDocPtr xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc, const char **params, const char *output, FILE * profile, xsltTransformContextPtr userCtxt) { … } /** * 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 */ xmlDocPtr xsltApplyStylesheet(xsltStylesheetPtr style, xmlDocPtr doc, const char **params) { … } /** * xsltProfileStylesheet: * @style: a parsed XSLT stylesheet * @doc: a parsed XML document * @params: a NULL terminated arry of parameters names/values tuples * @output: a FILE * for the profiling output * * Apply the stylesheet to the document and dump the profiling to * the given output. * * Returns the result document or NULL in case of error */ xmlDocPtr xsltProfileStylesheet(xsltStylesheetPtr style, xmlDocPtr doc, const char **params, FILE * output) { … } /** * 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 */ xmlDocPtr xsltApplyStylesheetUser(xsltStylesheetPtr style, xmlDocPtr doc, const char **params, const char *output, FILE * profile, xsltTransformContextPtr userCtxt) { … } /** * xsltRunStylesheetUser: * @style: a parsed XSLT stylesheet * @doc: a parsed XML document * @params: a NULL terminated array of parameters names/values tuples * @output: the URL/filename ot the generated resource if available * @SAX: a SAX handler for progressive callback output (not implemented yet) * @IObuf: an output buffer for progressive output (not implemented yet) * @profile: profile FILE * output or NULL * @userCtxt: user provided transform context * * Apply the stylesheet to the document and generate the output according * to @output @SAX and @IObuf. It's an error to specify both @SAX and @IObuf. * * NOTE: This may lead to a non-wellformed output XML wise ! * NOTE: This may also result in multiple files being generated * NOTE: using IObuf, the result encoding used will be the one used for * creating the output buffer, use the following macro to read it * from the stylesheet * XSLT_GET_IMPORT_PTR(encoding, style, encoding) * NOTE: using SAX, any encoding specified in the stylesheet will be lost * since the interface uses only UTF8 * * Returns the number of by written to the main resource or -1 in case of * error. */ int xsltRunStylesheetUser(xsltStylesheetPtr style, xmlDocPtr doc, const char **params, const char *output, xmlSAXHandlerPtr SAX, xmlOutputBufferPtr IObuf, FILE * profile, xsltTransformContextPtr userCtxt) { … } /** * xsltRunStylesheet: * @style: a parsed XSLT stylesheet * @doc: a parsed XML document * @params: a NULL terminated array of parameters names/values tuples * @output: the URL/filename ot the generated resource if available * @SAX: a SAX handler for progressive callback output (not implemented yet) * @IObuf: an output buffer for progressive output (not implemented yet) * * Apply the stylesheet to the document and generate the output according * to @output @SAX and @IObuf. It's an error to specify both @SAX and @IObuf. * * NOTE: This may lead to a non-wellformed output XML wise ! * NOTE: This may also result in multiple files being generated * NOTE: using IObuf, the result encoding used will be the one used for * creating the output buffer, use the following macro to read it * from the stylesheet * XSLT_GET_IMPORT_PTR(encoding, style, encoding) * NOTE: using SAX, any encoding specified in the stylesheet will be lost * since the interface uses only UTF8 * * Returns the number of bytes written to the main resource or -1 in case of * error. */ 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) { … } /** * xsltRegisterAllElement: * @ctxt: the XPath context * * Registers all default XSLT elements in this context */ void xsltRegisterAllElement(xsltTransformContextPtr ctxt) { … }