mirror of
https://github.com/darlinghq/darling-libxslt.git
synced 2024-12-12 06:16:23 +00:00
- libxslt/templates.c libxslt/transform.c libxslt/transform.h
libxslt/variables.c: big cleanup on the way templates or template fragments are processed, cleanup of stack building - tests/docs/Makefile.am tests/general/Makefile.am tests/general/bug-4[1-8]-* tests/docs/bug-4[1-8]-*: added a series of regression test for the variable/params lookups - libxslt/transform.c libxslt/xsltutils.[ch] libxslt/xsltproc.c: started working on profiling code, there is just invocation counting yet but the framework is in place. Daniel
This commit is contained in:
parent
78e30d87ad
commit
6744bd096b
14
ChangeLog
14
ChangeLog
@ -1,4 +1,16 @@
|
||||
Sat Jul 7 11:20:59 CEST 2001 Wiliam Brack <wbrack@mmm.com.hk>
|
||||
Sat Jul 7 18:58:56 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||
|
||||
* libxslt/templates.c libxslt/transform.c libxslt/transform.h
|
||||
libxslt/variables.c: big cleanup on the way templates or
|
||||
template fragments are processed, cleanup of stack building
|
||||
* tests/docs/Makefile.am tests/general/Makefile.am
|
||||
tests/general/bug-4[1-8]-* tests/docs/bug-4[1-8]-*: added a
|
||||
series of regression test for the variable/params lookups
|
||||
* libxslt/transform.c libxslt/xsltutils.[ch] libxslt/xsltproc.c:
|
||||
started working on profiling code, there is just invocation counting
|
||||
yet but the framework is in place.
|
||||
|
||||
Sat Jul 7 11:20:59 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||
|
||||
* tests/docs/Makefile.am tests/general/Makefile.am
|
||||
tests/general/bug-40-* tests/docs/bug-40-*: added a specific
|
||||
|
@ -169,8 +169,8 @@ xsltEvalXPathString(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp) {
|
||||
xmlChar *
|
||||
xsltEvalTemplateString(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xmlNodePtr parent) {
|
||||
xmlChar *ret;
|
||||
xmlNodePtr oldInsert, insert = NULL;
|
||||
xmlChar *ret;
|
||||
|
||||
if ((ctxt == NULL) || (node == NULL) || (parent == NULL))
|
||||
return(NULL);
|
||||
@ -185,7 +185,7 @@ xsltEvalTemplateString(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
oldInsert = ctxt->insert;
|
||||
ctxt->insert = insert;
|
||||
|
||||
xsltApplyOneTemplate(ctxt, node, parent->children, 0);
|
||||
xsltApplyOneTemplate(ctxt, node, parent->children, NULL, NULL);
|
||||
|
||||
ctxt->insert = oldInsert;
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
||||
#define WITH_XSLT_DEBUG_PROCESS
|
||||
#endif
|
||||
|
||||
int xsltMaxDepth = 250;
|
||||
int xsltMaxDepth = 500;
|
||||
|
||||
/*
|
||||
* Useful macros
|
||||
@ -601,7 +601,8 @@ xsltCopyTree(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node);
|
||||
void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xsltStackElemPtr params);
|
||||
/**
|
||||
* xsltDefaultProcessOneNode:
|
||||
* @ctxt: a XSLT process context
|
||||
@ -631,7 +632,6 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
int strip_spaces = -1;
|
||||
int nbchild = 0, oldSize;
|
||||
int childno = 0, oldPos;
|
||||
int oldBase;
|
||||
xsltTemplatePtr template;
|
||||
|
||||
CHECK_STOPPED;
|
||||
@ -757,17 +757,8 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
while (attrs != NULL) {
|
||||
template = xsltGetTemplate(ctxt, (xmlNodePtr) attrs, NULL);
|
||||
if (template) {
|
||||
xmlNodePtr oldNode;
|
||||
|
||||
oldNode = ctxt->node;
|
||||
ctxt->node = node;
|
||||
templPush(ctxt, template);
|
||||
oldBase = ctxt->varsBase;
|
||||
ctxt->varsBase = ctxt->varsNr - 1;
|
||||
xsltApplyOneTemplate(ctxt, node, template->content, 1);
|
||||
templPop(ctxt);
|
||||
ctxt->varsBase = oldBase;
|
||||
ctxt->node = oldNode;
|
||||
xsltApplyOneTemplate(ctxt, node, template->content, template,
|
||||
NULL);
|
||||
}
|
||||
attrs = attrs->next;
|
||||
}
|
||||
@ -782,29 +773,18 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
case XML_ELEMENT_NODE:
|
||||
ctxt->xpathCtxt->contextSize = nbchild;
|
||||
ctxt->xpathCtxt->proximityPosition = childno;
|
||||
varsPush( ctxt, NULL );
|
||||
xsltProcessOneNode(ctxt, cur);
|
||||
xsltFreeStackElemList( varsPop(ctxt) );
|
||||
xsltProcessOneNode(ctxt, cur, NULL);
|
||||
break;
|
||||
case XML_CDATA_SECTION_NODE:
|
||||
template = xsltGetTemplate(ctxt, node, NULL);
|
||||
if (template) {
|
||||
xmlNodePtr oldNode;
|
||||
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltDefaultProcessOneNode: applying template for CDATA %s\n",
|
||||
node->content);
|
||||
#endif
|
||||
oldNode = ctxt->node;
|
||||
ctxt->node = node;
|
||||
templPush(ctxt, template);
|
||||
oldBase = ctxt->varsBase;
|
||||
ctxt->varsBase = ctxt->varsNr - 1;
|
||||
xsltApplyOneTemplate(ctxt, node, template->content, 1);
|
||||
templPop(ctxt);
|
||||
ctxt->varsBase = oldBase;
|
||||
ctxt->node = oldNode;
|
||||
xsltApplyOneTemplate(ctxt, node, template->content,
|
||||
template, NULL);
|
||||
} else /* if (ctxt->mode == NULL) */ {
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
@ -823,24 +803,15 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
case XML_TEXT_NODE:
|
||||
template = xsltGetTemplate(ctxt, cur, NULL);
|
||||
if (template) {
|
||||
xmlNodePtr oldNode;
|
||||
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltDefaultProcessOneNode: applying template for text %s\n",
|
||||
node->content);
|
||||
#endif
|
||||
oldNode = ctxt->node;
|
||||
ctxt->node = cur;
|
||||
ctxt->xpathCtxt->contextSize = nbchild;
|
||||
ctxt->xpathCtxt->proximityPosition = childno;
|
||||
templPush(ctxt, template);
|
||||
oldBase = ctxt->varsBase;
|
||||
ctxt->varsBase = ctxt->varsNr - 1;
|
||||
xsltApplyOneTemplate(ctxt, cur, template->content, 1);
|
||||
templPop(ctxt);
|
||||
ctxt->varsBase = oldBase;
|
||||
ctxt->node = oldNode;
|
||||
xsltApplyOneTemplate(ctxt, cur, template->content,
|
||||
template, NULL);
|
||||
} else /* if (ctxt->mode == NULL) */ {
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
if (cur->content == NULL)
|
||||
@ -864,8 +835,6 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
case XML_COMMENT_NODE:
|
||||
template = xsltGetTemplate(ctxt, cur, NULL);
|
||||
if (template) {
|
||||
xmlNodePtr oldNode;
|
||||
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
if (cur->type == XML_PI_NODE)
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
@ -875,17 +844,10 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltDefaultProcessOneNode: template found for comment\n");
|
||||
#endif
|
||||
oldNode = ctxt->node;
|
||||
ctxt->node = cur;
|
||||
ctxt->xpathCtxt->contextSize = nbchild;
|
||||
ctxt->xpathCtxt->proximityPosition = childno;
|
||||
templPush(ctxt, template);
|
||||
oldBase = ctxt->varsBase;
|
||||
ctxt->varsBase = ctxt->varsNr - 1;
|
||||
xsltApplyOneTemplate(ctxt, cur, template->content, 1);
|
||||
templPop(ctxt);
|
||||
ctxt->varsBase = oldBase;
|
||||
ctxt->node = oldNode;
|
||||
xsltApplyOneTemplate(ctxt, cur, template->content,
|
||||
template, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -905,10 +867,10 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
* Process the source node.
|
||||
*/
|
||||
void
|
||||
xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xsltStackElemPtr params) {
|
||||
xsltTemplatePtr template;
|
||||
xmlNodePtr oldNode;
|
||||
int oldBase;
|
||||
|
||||
/*
|
||||
* Cleanup children empty nodes if asked for
|
||||
@ -967,12 +929,7 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
"xsltProcessOneNode: applying template '%s' for attribute %s\n",
|
||||
template->match, node->name);
|
||||
#endif
|
||||
templPush(ctxt, template);
|
||||
oldBase = ctxt->varsBase;
|
||||
ctxt->varsBase = ctxt->varsNr - 1;
|
||||
xsltApplyOneTemplate(ctxt, node, template->content, 1);
|
||||
templPop(ctxt);
|
||||
ctxt->varsBase = oldBase;
|
||||
xsltApplyOneTemplate(ctxt, node, template->content, template, params);
|
||||
} else {
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
if (node->type == XML_DOCUMENT_NODE)
|
||||
@ -984,15 +941,7 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
"xsltProcessOneNode: applying template '%s' for %s\n",
|
||||
template->match, node->name);
|
||||
#endif
|
||||
oldNode = ctxt->node;
|
||||
ctxt->node = node;
|
||||
templPush(ctxt, template);
|
||||
oldBase = ctxt->varsBase;
|
||||
ctxt->varsBase = ctxt->varsNr - 1;
|
||||
xsltApplyOneTemplate(ctxt, node, template->content, 1);
|
||||
templPop(ctxt);
|
||||
ctxt->varsBase = oldBase;
|
||||
ctxt->node = oldNode;
|
||||
xsltApplyOneTemplate(ctxt, node, template->content, template, params);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1001,21 +950,26 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
|
||||
* @ctxt: a XSLT process context
|
||||
* @node: the node in the source tree.
|
||||
* @list: the template replacement nodelist
|
||||
* @real: is this a real template processing
|
||||
* @templ: if is this a real template processing, the template processed
|
||||
* @params: a set of parameters for the template or NULL
|
||||
*
|
||||
* Process the apply-templates node on the source node
|
||||
* Process the apply-templates node on the source node, if params are passed
|
||||
* they are pushed on the variable stack but not popped, it's left to the
|
||||
* caller to handle them back (they may be reused).
|
||||
*/
|
||||
void
|
||||
xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xmlNodePtr list, int real)
|
||||
xmlNodePtr list, xsltTemplatePtr templ,
|
||||
xsltStackElemPtr params)
|
||||
{
|
||||
xmlNodePtr cur = NULL, insert, copy = NULL;
|
||||
xmlNodePtr oldInsert;
|
||||
xmlNodePtr oldCurrent = NULL;
|
||||
xmlNodePtr oldInst = NULL;
|
||||
xmlAttrPtr attrs;
|
||||
int oldBase;
|
||||
|
||||
if (list == NULL)
|
||||
if ((ctxt == NULL) || (list == NULL))
|
||||
return;
|
||||
CHECK_STOPPED;
|
||||
|
||||
@ -1033,9 +987,22 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
*/
|
||||
oldInsert = insert = ctxt->insert;
|
||||
oldInst = ctxt->inst;
|
||||
if (real) {
|
||||
oldCurrent = ctxt->node;
|
||||
oldCurrent = ctxt->node;
|
||||
varsPush(ctxt, params);
|
||||
oldBase = ctxt->varsBase; /* only needed if templ != NULL */
|
||||
if (templ != NULL) {
|
||||
ctxt->varsBase = ctxt->varsNr - 1;
|
||||
ctxt->node = node;
|
||||
if (ctxt->profile) {
|
||||
templ->nbCalls++;
|
||||
}
|
||||
templPush(ctxt, templ);
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
if (templ->name != NULL)
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"applying template '%s'\n",
|
||||
templ->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1052,9 +1019,29 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltApplyOneTemplate: insert == NULL !\n");
|
||||
#endif
|
||||
if (real)
|
||||
ctxt->node = oldCurrent;
|
||||
ctxt->node = oldCurrent;
|
||||
ctxt->inst = oldInst;
|
||||
ctxt->insert = oldInsert;
|
||||
if (params == NULL)
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
else {
|
||||
xsltStackElemPtr p, tmp = varsPop(ctxt);
|
||||
if (tmp != params) {
|
||||
p = tmp;
|
||||
while ((p != NULL) && (p->next != params))
|
||||
p = p->next;
|
||||
if (p == NULL) {
|
||||
xsltFreeStackElemList(tmp);
|
||||
} else {
|
||||
p->next = NULL;
|
||||
xsltFreeStackElemList(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (templ != NULL) {
|
||||
ctxt->varsBase = oldBase;
|
||||
templPop(ctxt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1145,7 +1132,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
(IS_XSLT_NAME(child, "fallback"))) {
|
||||
found = 1;
|
||||
xsltApplyOneTemplate(ctxt, node, child->children,
|
||||
1);
|
||||
NULL, NULL);
|
||||
}
|
||||
child = child->next;
|
||||
}
|
||||
@ -1215,9 +1202,29 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
}
|
||||
} while (cur != NULL);
|
||||
}
|
||||
if (real)
|
||||
ctxt->node = oldCurrent;
|
||||
ctxt->node = oldCurrent;
|
||||
ctxt->inst = oldInst;
|
||||
ctxt->insert = oldInsert;
|
||||
if (params == NULL)
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
else {
|
||||
xsltStackElemPtr p, tmp = varsPop(ctxt);
|
||||
if (tmp != params) {
|
||||
p = tmp;
|
||||
while ((p != NULL) && (p->next != params))
|
||||
p = p->next;
|
||||
if (p == NULL) {
|
||||
xsltFreeStackElemList(tmp);
|
||||
} else {
|
||||
p->next = NULL;
|
||||
xsltFreeStackElemList(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (templ != NULL) {
|
||||
ctxt->varsBase = oldBase;
|
||||
templPop(ctxt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1543,9 +1550,7 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
res->encoding = xmlStrdup(style->encoding);
|
||||
ctxt->output = res;
|
||||
ctxt->insert = (xmlNodePtr) res;
|
||||
varsPush(ctxt, NULL);
|
||||
xsltApplyOneTemplate(ctxt, node, inst->children, 0);
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
xsltApplyOneTemplate(ctxt, node, inst->children, NULL, NULL);
|
||||
|
||||
/*
|
||||
* Save the result
|
||||
@ -1584,7 +1589,8 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node);
|
||||
void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xsltStackElemPtr params);
|
||||
|
||||
/**
|
||||
* xsltSort:
|
||||
@ -1712,9 +1718,8 @@ xsltCopy(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
case XML_DOCUMENT_NODE:
|
||||
case XML_HTML_DOCUMENT_NODE:
|
||||
case XML_ELEMENT_NODE:
|
||||
varsPush(ctxt, NULL);
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, inst->children, 0);
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, inst->children,
|
||||
NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1867,9 +1872,7 @@ xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
}
|
||||
}
|
||||
|
||||
varsPush(ctxt, NULL);
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, inst->children, 0);
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, inst->children, NULL, NULL);
|
||||
|
||||
ctxt->insert = oldInsert;
|
||||
|
||||
@ -2296,9 +2299,9 @@ xsltNumber(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
*/
|
||||
void
|
||||
xsltApplyImports(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xmlNodePtr inst ATTRIBUTE_UNUSED, xsltStylePreCompPtr comp ATTRIBUTE_UNUSED) {
|
||||
xmlNodePtr inst ATTRIBUTE_UNUSED,
|
||||
xsltStylePreCompPtr comp ATTRIBUTE_UNUSED) {
|
||||
xsltTemplatePtr template;
|
||||
int oldBase;
|
||||
|
||||
if ((ctxt->templ == NULL) || (ctxt->templ->style == NULL)) {
|
||||
xsltGenericError(xsltGenericErrorContext,
|
||||
@ -2307,14 +2310,7 @@ xsltApplyImports(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
}
|
||||
template = xsltGetTemplate(ctxt, node, ctxt->templ->style);
|
||||
if (template != NULL) {
|
||||
templPush(ctxt, template);
|
||||
oldBase = ctxt->varsBase;
|
||||
ctxt->varsBase = ctxt->varsNr - 1;
|
||||
varsPush(ctxt, NULL);
|
||||
xsltApplyOneTemplate(ctxt, node, template->content, 1);
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
templPop(ctxt);
|
||||
ctxt->varsBase = oldBase;
|
||||
xsltApplyOneTemplate(ctxt, node, template->content, template, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2332,7 +2328,6 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xmlNodePtr inst, xsltStylePreCompPtr comp) {
|
||||
xmlNodePtr cur = NULL;
|
||||
xsltStackElemPtr params = NULL, param;
|
||||
int oldBase;
|
||||
|
||||
if (ctxt->insert == NULL)
|
||||
return;
|
||||
@ -2354,6 +2349,12 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
if ((comp != NULL) && (comp->name != NULL))
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"call-template: name %s\n", comp->name);
|
||||
#endif
|
||||
|
||||
cur = inst->children;
|
||||
while (cur != NULL) {
|
||||
if (ctxt->state == XSLT_STATE_STOPPED) break;
|
||||
@ -2375,16 +2376,17 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
cur = cur->next;
|
||||
}
|
||||
/*
|
||||
* Create a new frame but block access to variables
|
||||
* Create a new frame using the params first
|
||||
*/
|
||||
templPush(ctxt, comp->templ);
|
||||
oldBase = ctxt->varsBase; /* Save the original variable base */
|
||||
varsPush(ctxt, params);
|
||||
ctxt->varsBase = ctxt->varsNr - 1; /* Reset base to be new templ params */
|
||||
xsltApplyOneTemplate(ctxt, node, comp->templ->content, 1);
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
templPop(ctxt);
|
||||
ctxt->varsBase = oldBase; /* Restore the original variable base */
|
||||
xsltApplyOneTemplate(ctxt, node, comp->templ->content, comp->templ, params);
|
||||
if (params != NULL)
|
||||
xsltFreeStackElemList(params);
|
||||
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
if ((comp != NULL) && (comp->name != NULL))
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"call-template returned: name %s\n", comp->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2404,7 +2406,7 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xmlNodeSetPtr list = NULL, oldList;
|
||||
int i, oldProximityPosition, oldContextSize;
|
||||
const xmlChar *oldMode, *oldModeURI;
|
||||
xsltStackElemPtr params = NULL, param, tmp, p;
|
||||
xsltStackElemPtr params = NULL, param;
|
||||
int nbsorts = 0;
|
||||
xmlNodePtr sorts[XSLT_MAX_SORT];
|
||||
xmlDocPtr oldXDocPtr;
|
||||
@ -2558,17 +2560,17 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
} else if (IS_XSLT_NAME(cur, "sort")) {
|
||||
if (nbsorts >= XSLT_MAX_SORT) {
|
||||
xsltGenericError(xsltGenericDebugContext,
|
||||
"xsl:call-template: %s too many sort\n", node->name);
|
||||
"xsl:apply-template: %s too many sort\n", node->name);
|
||||
} else {
|
||||
sorts[nbsorts++] = cur;
|
||||
}
|
||||
} else {
|
||||
xsltGenericError(xsltGenericDebugContext,
|
||||
"xsl:call-template: misplaced xsl:%s\n", cur->name);
|
||||
"xsl:apply-template: misplaced xsl:%s\n", cur->name);
|
||||
}
|
||||
} else {
|
||||
xsltGenericError(xsltGenericDebugContext,
|
||||
"xsl:call-template: misplaced %s element\n", cur->name);
|
||||
"xsl:apply-template: misplaced %s element\n", cur->name);
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
@ -2599,28 +2601,10 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
ctxt->document->doc->URL, ctxt->xpathCtxt->doc->URL);
|
||||
#endif
|
||||
}
|
||||
varsPush(ctxt, params);
|
||||
xsltProcessOneNode(ctxt, list->nodeTab[i]);
|
||||
tmp = varsPop(ctxt);
|
||||
/*
|
||||
* Free other parameter and variables which may have been
|
||||
* added to the set defined in the caller.
|
||||
*/
|
||||
if (params == NULL) {
|
||||
xsltFreeStackElemList(tmp);
|
||||
} else if (tmp != params) {
|
||||
p = tmp;
|
||||
while ((p != NULL) && (p->next != params))
|
||||
p = p->next;
|
||||
if (p == NULL) {
|
||||
xsltFreeStackElemList(tmp);
|
||||
} else {
|
||||
p->next = NULL;
|
||||
xsltFreeStackElemList(tmp);
|
||||
}
|
||||
}
|
||||
xsltProcessOneNode(ctxt, list->nodeTab[i], params);
|
||||
}
|
||||
xsltFreeStackElemList(params); /* free the parameter list */
|
||||
if (params != NULL)
|
||||
xsltFreeStackElemList(params); /* free the parameter list */
|
||||
error:
|
||||
|
||||
ctxt->nodeList = oldList;
|
||||
@ -2724,9 +2708,8 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
"xsltChoose: test evaluate to %d\n", doit);
|
||||
#endif
|
||||
if (doit) {
|
||||
varsPush(ctxt, NULL);
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, when->children, 0);
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, when->children,
|
||||
NULL, NULL);
|
||||
goto done;
|
||||
}
|
||||
if (prop != NULL)
|
||||
@ -2738,9 +2721,12 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
replacement = replacement->next;
|
||||
}
|
||||
if (IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "otherwise"))) {
|
||||
varsPush(ctxt, NULL);
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, replacement->children, 0);
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"evaluating xsl:otherwise\n");
|
||||
#endif
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, replacement->children,
|
||||
NULL, NULL);
|
||||
replacement = replacement->next;
|
||||
}
|
||||
if (replacement != NULL) {
|
||||
@ -2819,9 +2805,7 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
"xsltIf: test evaluate to %d\n", doit);
|
||||
#endif
|
||||
if (doit) {
|
||||
varsPush(ctxt, NULL);
|
||||
xsltApplyOneTemplate(ctxt, node, inst->children, 0);
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
xsltApplyOneTemplate(ctxt, node, inst->children, NULL, NULL);
|
||||
}
|
||||
|
||||
error:
|
||||
@ -2934,20 +2918,17 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
if ((ctxt->document =
|
||||
xsltFindDocument(ctxt,list->nodeTab[i]->doc->doc))==NULL) {
|
||||
xsltGenericError(xsltGenericErrorContext,
|
||||
"xsl:apply-templates : can't find doc\n");
|
||||
"xsl:for-each : can't find doc\n");
|
||||
goto error;
|
||||
}
|
||||
ctxt->xpathCtxt->node = list->nodeTab[i];
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltApplyTemplates: Changing document - context doc %s, xpathdoc %s\n",
|
||||
"xsltForEach: Changing document - context doc %s, xpathdoc %s\n",
|
||||
ctxt->document->doc->URL, ctxt->xpathCtxt->doc->URL);
|
||||
#endif
|
||||
}
|
||||
/* ctxt->insert = oldInsert; */
|
||||
varsPush(ctxt, NULL);
|
||||
xsltApplyOneTemplate(ctxt, list->nodeTab[i], replacement, 0);
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
xsltApplyOneTemplate(ctxt, list->nodeTab[i], replacement, NULL, NULL);
|
||||
}
|
||||
ctxt->document = oldCDocPtr;
|
||||
ctxt->nodeList = oldList;
|
||||
@ -3032,6 +3013,7 @@ xsltGetHTMLIDs(const xmlChar *version, const xmlChar **public,
|
||||
* @doc: a parsed XML document
|
||||
* @params: a NULL terminated arry of parameters names/values tuples
|
||||
* @output: the targetted output
|
||||
* @profile: profile FILE * output or NULL
|
||||
*
|
||||
* Apply the stylesheet to the document
|
||||
* NOTE: This may lead to a non-wellformed output XML wise !
|
||||
@ -3040,7 +3022,9 @@ xsltGetHTMLIDs(const xmlChar *version, const xmlChar **public,
|
||||
*/
|
||||
static xmlDocPtr
|
||||
xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
|
||||
const char **params, const char *output) {
|
||||
const char **params, const char *output,
|
||||
FILE * profile)
|
||||
{
|
||||
xmlDocPtr res = NULL;
|
||||
xsltTransformContextPtr ctxt = NULL;
|
||||
xmlNodePtr root;
|
||||
@ -3052,65 +3036,69 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
|
||||
xsltStackElemPtr vptr;
|
||||
|
||||
if ((style == NULL) || (doc == NULL))
|
||||
return(NULL);
|
||||
return (NULL);
|
||||
ctxt = xsltNewTransformContext(style, doc);
|
||||
if (ctxt == NULL)
|
||||
return(NULL);
|
||||
return (NULL);
|
||||
|
||||
if (profile != NULL)
|
||||
ctxt->profile = 1;
|
||||
|
||||
xsltRegisterExtras(ctxt);
|
||||
if (output != NULL)
|
||||
ctxt->outputFile = output;
|
||||
ctxt->outputFile = output;
|
||||
else
|
||||
ctxt->outputFile = NULL;
|
||||
ctxt->outputFile = NULL;
|
||||
|
||||
XSLT_GET_IMPORT_PTR(method, style, method)
|
||||
XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
|
||||
XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
|
||||
XSLT_GET_IMPORT_PTR(version, style, version)
|
||||
XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
|
||||
XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
|
||||
XSLT_GET_IMPORT_PTR(version, style, version)
|
||||
|
||||
if ((method != NULL) &&
|
||||
(!xmlStrEqual(method, (const xmlChar *) "xml"))) {
|
||||
if (xmlStrEqual(method, (const xmlChar *) "html")) {
|
||||
ctxt->type = XSLT_OUTPUT_HTML;
|
||||
if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
|
||||
res = htmlNewDoc(doctypeSystem, doctypePublic);
|
||||
else {
|
||||
if (version == NULL)
|
||||
version = (const xmlChar *) "4.0";
|
||||
if ((method != NULL) &&
|
||||
(!xmlStrEqual(method, (const xmlChar *) "xml"))) {
|
||||
if (xmlStrEqual(method, (const xmlChar *) "html")) {
|
||||
ctxt->type = XSLT_OUTPUT_HTML;
|
||||
if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
|
||||
res = htmlNewDoc(doctypeSystem, doctypePublic);
|
||||
else {
|
||||
if (version == NULL)
|
||||
version = (const xmlChar *) "4.0";
|
||||
#ifdef XSLT_GENERATE_HTML_DOCTYPE
|
||||
xsltGetHTMLIDs(version, &doctypePublic, &doctypeSystem);
|
||||
xsltGetHTMLIDs(version, &doctypePublic, &doctypeSystem);
|
||||
#endif
|
||||
res = htmlNewDoc(doctypeSystem, doctypePublic);
|
||||
}
|
||||
if (res == NULL)
|
||||
goto error;
|
||||
} else if (xmlStrEqual(method, (const xmlChar *) "xhtml")) {
|
||||
xsltGenericError(xsltGenericErrorContext,
|
||||
"xsltApplyStylesheetInternal: unsupported method xhtml, using html\n",
|
||||
style->method);
|
||||
ctxt->type = XSLT_OUTPUT_HTML;
|
||||
res = htmlNewDoc(doctypeSystem, doctypePublic);
|
||||
if (res == NULL)
|
||||
goto error;
|
||||
} else if (xmlStrEqual(style->method, (const xmlChar *) "text")) {
|
||||
ctxt->type = XSLT_OUTPUT_TEXT;
|
||||
res = xmlNewDoc(style->version);
|
||||
if (res == NULL)
|
||||
goto error;
|
||||
} else {
|
||||
xsltGenericError(xsltGenericErrorContext,
|
||||
"xsltApplyStylesheetInternal: unsupported method %s\n",
|
||||
style->method);
|
||||
goto error;
|
||||
}
|
||||
res = htmlNewDoc(doctypeSystem, doctypePublic);
|
||||
}
|
||||
if (res == NULL)
|
||||
goto error;
|
||||
} else if (xmlStrEqual(method, (const xmlChar *) "xhtml")) {
|
||||
xsltGenericError(xsltGenericErrorContext,
|
||||
"xsltApplyStylesheetInternal: unsupported method xhtml, using html\n",
|
||||
style->method);
|
||||
ctxt->type = XSLT_OUTPUT_HTML;
|
||||
res = htmlNewDoc(doctypeSystem, doctypePublic);
|
||||
if (res == NULL)
|
||||
goto error;
|
||||
} else if (xmlStrEqual(style->method, (const xmlChar *) "text")) {
|
||||
ctxt->type = XSLT_OUTPUT_TEXT;
|
||||
res = xmlNewDoc(style->version);
|
||||
if (res == NULL)
|
||||
goto error;
|
||||
} else {
|
||||
xsltGenericError(xsltGenericErrorContext,
|
||||
"xsltApplyStylesheetInternal: unsupported method %s\n",
|
||||
style->method);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
ctxt->type = XSLT_OUTPUT_XML;
|
||||
res = xmlNewDoc(style->version);
|
||||
if (res == NULL)
|
||||
goto error;
|
||||
ctxt->type = XSLT_OUTPUT_XML;
|
||||
res = xmlNewDoc(style->version);
|
||||
if (res == NULL)
|
||||
goto error;
|
||||
}
|
||||
res->charset = XML_CHAR_ENCODING_UTF8;
|
||||
if (style->encoding != NULL)
|
||||
res->encoding = xmlStrdup(style->encoding);
|
||||
res->encoding = xmlStrdup(style->encoding);
|
||||
variables = style->variables;
|
||||
|
||||
/*
|
||||
@ -3121,13 +3109,13 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
|
||||
ctxt->insert = (xmlNodePtr) res;
|
||||
ctxt->globalVars = xmlHashCreate(20);
|
||||
if (params != NULL)
|
||||
xsltEvalUserParams(ctxt, params);
|
||||
xsltEvalUserParams(ctxt, params);
|
||||
xsltInitCtxtExts(ctxt);
|
||||
xsltEvalGlobalVariables(ctxt);
|
||||
ctxt->node = (xmlNodePtr) doc;
|
||||
xsltInitCtxtExts(ctxt);
|
||||
varsPush(ctxt, NULL);
|
||||
ctxt->varsBase = ctxt->varsNr - 1;
|
||||
xsltProcessOneNode(ctxt, ctxt->node);
|
||||
xsltProcessOneNode(ctxt, ctxt->node, NULL);
|
||||
xsltFreeStackElemList(varsPop(ctxt));
|
||||
xsltShutdownCtxtExts(ctxt);
|
||||
|
||||
@ -3140,23 +3128,23 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
|
||||
* and not evaluated directly anymore, keep this as a check
|
||||
*/
|
||||
if (style->variables != variables) {
|
||||
vptr = style->variables;
|
||||
while (vptr->next!=variables)
|
||||
vptr = vptr->next;
|
||||
vptr->next = NULL;
|
||||
xsltFreeStackElemList(style->variables);
|
||||
style->variables = variables;
|
||||
vptr = style->variables;
|
||||
while (vptr->next != variables)
|
||||
vptr = vptr->next;
|
||||
vptr->next = NULL;
|
||||
xsltFreeStackElemList(style->variables);
|
||||
style->variables = variables;
|
||||
}
|
||||
vptr = style->variables;
|
||||
while(vptr!=NULL) {
|
||||
if (vptr->computed) {
|
||||
if (vptr->value != NULL) {
|
||||
xmlXPathFreeObject(vptr->value);
|
||||
vptr->value = NULL;
|
||||
vptr->computed = 0;
|
||||
}
|
||||
}
|
||||
vptr = vptr->next;
|
||||
while (vptr != NULL) {
|
||||
if (vptr->computed) {
|
||||
if (vptr->value != NULL) {
|
||||
xmlXPathFreeObject(vptr->value);
|
||||
vptr->value = NULL;
|
||||
vptr->computed = 0;
|
||||
}
|
||||
}
|
||||
vptr = vptr->next;
|
||||
}
|
||||
|
||||
|
||||
@ -3165,57 +3153,67 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
|
||||
*/
|
||||
root = xmlDocGetRootElement(res);
|
||||
if (root != NULL) {
|
||||
/*
|
||||
* Apply the default selection of the method
|
||||
*/
|
||||
if ((method == NULL) &&
|
||||
(root->ns == NULL) &&
|
||||
(!xmlStrcasecmp(root->name, (const xmlChar *) "html"))) {
|
||||
xmlNodePtr tmp;
|
||||
tmp = res->children;
|
||||
while ((tmp != NULL) && (tmp != root)) {
|
||||
if (tmp->type == XML_ELEMENT_NODE)
|
||||
break;
|
||||
if ((tmp->type == XML_TEXT_NODE) && (!xmlIsBlankNode(tmp)))
|
||||
break;
|
||||
}
|
||||
if (tmp == root) {
|
||||
ctxt->type = XSLT_OUTPUT_HTML;
|
||||
res->type = XML_HTML_DOCUMENT_NODE;
|
||||
if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
|
||||
res->intSubset = xmlCreateIntSubset(res, root->name,
|
||||
doctypePublic, doctypeSystem);
|
||||
#ifdef XSLT_GENERATE_HTML_DOCTYPE
|
||||
else {
|
||||
if (version == NULL)
|
||||
version = (const xmlChar *) "4.0";
|
||||
xsltGetHTMLIDs(version, &doctypePublic, &doctypeSystem);
|
||||
if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
|
||||
res->intSubset = xmlCreateIntSubset(res, root->name,
|
||||
doctypePublic, doctypeSystem);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Apply the default selection of the method
|
||||
*/
|
||||
if ((method == NULL) &&
|
||||
(root->ns == NULL) &&
|
||||
(!xmlStrcasecmp(root->name, (const xmlChar *) "html"))) {
|
||||
xmlNodePtr tmp;
|
||||
|
||||
}
|
||||
if (ctxt->type == XSLT_OUTPUT_XML) {
|
||||
XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
|
||||
XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
|
||||
if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
|
||||
res->intSubset = xmlCreateIntSubset(res, root->name,
|
||||
doctypePublic, doctypeSystem);
|
||||
}
|
||||
tmp = res->children;
|
||||
while ((tmp != NULL) && (tmp != root)) {
|
||||
if (tmp->type == XML_ELEMENT_NODE)
|
||||
break;
|
||||
if ((tmp->type == XML_TEXT_NODE) && (!xmlIsBlankNode(tmp)))
|
||||
break;
|
||||
}
|
||||
if (tmp == root) {
|
||||
ctxt->type = XSLT_OUTPUT_HTML;
|
||||
res->type = XML_HTML_DOCUMENT_NODE;
|
||||
if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
|
||||
res->intSubset = xmlCreateIntSubset(res, root->name,
|
||||
doctypePublic,
|
||||
doctypeSystem);
|
||||
#ifdef XSLT_GENERATE_HTML_DOCTYPE
|
||||
else {
|
||||
if (version == NULL)
|
||||
version = (const xmlChar *) "4.0";
|
||||
xsltGetHTMLIDs(version, &doctypePublic,
|
||||
&doctypeSystem);
|
||||
if (((doctypePublic != NULL)
|
||||
|| (doctypeSystem != NULL)))
|
||||
res->intSubset =
|
||||
xmlCreateIntSubset(res, root->name,
|
||||
doctypePublic,
|
||||
doctypeSystem);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
if (ctxt->type == XSLT_OUTPUT_XML) {
|
||||
XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
|
||||
XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
|
||||
if (((doctypePublic != NULL) || (doctypeSystem != NULL)))
|
||||
res->intSubset = xmlCreateIntSubset(res, root->name,
|
||||
doctypePublic,
|
||||
doctypeSystem);
|
||||
}
|
||||
}
|
||||
xmlXPathFreeNodeSet(ctxt->nodeList);
|
||||
if (profile != NULL) {
|
||||
xsltSaveProfiling(ctxt, profile);
|
||||
}
|
||||
xsltFreeTransformContext(ctxt);
|
||||
return(res);
|
||||
return (res);
|
||||
|
||||
error:
|
||||
if (res != NULL)
|
||||
xmlFreeDoc(res);
|
||||
if (ctxt != NULL)
|
||||
xsltFreeTransformContext(ctxt);
|
||||
return(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3231,8 +3229,31 @@ error:
|
||||
*/
|
||||
xmlDocPtr
|
||||
xsltApplyStylesheet(xsltStylesheetPtr style, xmlDocPtr doc,
|
||||
const char **params) {
|
||||
return(xsltApplyStylesheetInternal(style, doc, params, NULL));
|
||||
const char **params)
|
||||
{
|
||||
return (xsltApplyStylesheetInternal(style, doc, params, NULL, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
xmlDocPtr res;
|
||||
|
||||
res = xsltApplyStylesheetInternal(style, doc, params, NULL, output);
|
||||
return (res);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3260,36 +3281,36 @@ xsltApplyStylesheet(xsltStylesheetPtr style, xmlDocPtr doc,
|
||||
* error.
|
||||
*/
|
||||
int
|
||||
xsltRunStylesheet(xsltStylesheetPtr style, xmlDocPtr doc, const char **params,
|
||||
const char *output, xmlSAXHandlerPtr SAX,
|
||||
xmlOutputBufferPtr IObuf)
|
||||
xsltRunStylesheet(xsltStylesheetPtr style, xmlDocPtr doc,
|
||||
const char **params, const char *output,
|
||||
xmlSAXHandlerPtr SAX, xmlOutputBufferPtr IObuf)
|
||||
{
|
||||
xmlDocPtr tmp;
|
||||
int ret;
|
||||
|
||||
if ((output == NULL) && (SAX == NULL) && (IObuf == NULL))
|
||||
return(-1);
|
||||
return (-1);
|
||||
if ((SAX != NULL) && (IObuf != NULL))
|
||||
return(-1);
|
||||
return (-1);
|
||||
|
||||
/* unsupported yet */
|
||||
if (SAX != NULL) {
|
||||
TODO /* xsltRunStylesheet xmlSAXHandlerPtr SAX */
|
||||
return(-1);
|
||||
TODO /* xsltRunStylesheet xmlSAXHandlerPtr SAX */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
tmp = xsltApplyStylesheetInternal(style, doc, params, output);
|
||||
tmp = xsltApplyStylesheetInternal(style, doc, params, output, NULL);
|
||||
if (tmp == NULL) {
|
||||
xsltGenericError(xsltGenericErrorContext,
|
||||
"xsltRunStylesheet : run failed\n");
|
||||
return(-1);
|
||||
xsltGenericError(xsltGenericErrorContext,
|
||||
"xsltRunStylesheet : run failed\n");
|
||||
return (-1);
|
||||
}
|
||||
if (IObuf != NULL) {
|
||||
/* TODO: incomplete, IObuf output not progressive */
|
||||
ret = xsltSaveResultTo(IObuf, tmp, style);
|
||||
/* TODO: incomplete, IObuf output not progressive */
|
||||
ret = xsltSaveResultTo(IObuf, tmp, style);
|
||||
} else {
|
||||
ret = xsltSaveResultToFilename(output, tmp, style, 0);
|
||||
ret = xsltSaveResultToFilename(output, tmp, style, 0);
|
||||
}
|
||||
xmlFreeDoc(tmp);
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -29,6 +29,10 @@ int xsltGetXIncludeDefault (void);
|
||||
xmlDocPtr xsltApplyStylesheet (xsltStylesheetPtr style,
|
||||
xmlDocPtr doc,
|
||||
const char **params);
|
||||
xmlDocPtr xsltProfileStylesheet (xsltStylesheetPtr style,
|
||||
xmlDocPtr doc,
|
||||
const char **params,
|
||||
FILE * output);
|
||||
int xsltRunStylesheet (xsltStylesheetPtr style,
|
||||
xmlDocPtr doc,
|
||||
const char **params,
|
||||
@ -38,7 +42,8 @@ int xsltRunStylesheet (xsltStylesheetPtr style,
|
||||
void xsltApplyOneTemplate (xsltTransformContextPtr ctxt,
|
||||
xmlNodePtr node,
|
||||
xmlNodePtr list,
|
||||
int real);
|
||||
xsltTemplatePtr templ,
|
||||
xsltStackElemPtr params);
|
||||
void xsltDocumentElem (xsltTransformContextPtr ctxt,
|
||||
xmlNodePtr node,
|
||||
xmlNodePtr inst,
|
||||
|
@ -347,7 +347,7 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem,
|
||||
* This is a result tree fragment.
|
||||
*/
|
||||
xmlNodePtr container;
|
||||
xmlNodePtr oldInsert, oldNode;
|
||||
xmlNodePtr oldInsert;
|
||||
|
||||
container = xmlNewDocNode(ctxt->output, NULL,
|
||||
(const xmlChar *) "fake", NULL);
|
||||
@ -355,11 +355,9 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem,
|
||||
return(NULL);
|
||||
|
||||
oldInsert = ctxt->insert;
|
||||
oldNode = ctxt->node;
|
||||
ctxt->insert = container;
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, 0);
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, NULL, NULL);
|
||||
ctxt->insert = oldInsert;
|
||||
ctxt->node = oldNode;
|
||||
|
||||
result = xmlXPathNewValueTree(container);
|
||||
if (result == NULL) {
|
||||
@ -462,7 +460,7 @@ xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt) {
|
||||
* This is a result tree fragment.
|
||||
*/
|
||||
xmlNodePtr container;
|
||||
xmlNodePtr oldInsert, oldNode;
|
||||
xmlNodePtr oldInsert;
|
||||
|
||||
container = xmlNewDocNode(ctxt->output, NULL,
|
||||
(const xmlChar *) "fake", NULL);
|
||||
@ -470,11 +468,9 @@ xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt) {
|
||||
return(NULL);
|
||||
|
||||
oldInsert = ctxt->insert;
|
||||
oldNode = ctxt->node;
|
||||
ctxt->insert = container;
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, 0);
|
||||
xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, NULL, NULL);
|
||||
ctxt->insert = oldInsert;
|
||||
ctxt->node = oldNode;
|
||||
|
||||
result = xmlXPathNewValueTree(container);
|
||||
if (result == NULL) {
|
||||
@ -847,7 +843,7 @@ xsltRegisterVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
|
||||
#ifdef WITH_XSLT_DEBUG_VARIABLE
|
||||
else
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"param %s defined by caller", comp->name);
|
||||
"param %s defined by caller\n", comp->name);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
@ -54,6 +54,10 @@ struct _xsltTemplate {
|
||||
xmlChar *modeURI; /* the URI part of the mode QName */
|
||||
xmlNodePtr content; /* the template replacement value */
|
||||
xmlNodePtr elem; /* the source element */
|
||||
|
||||
/* Profiling informations */
|
||||
int nbCalls; /* the number of time the template was called */
|
||||
unsigned long time; /* the time spent in this template */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -310,7 +314,7 @@ struct _xsltStylesheet {
|
||||
int warnings; /* number of warnings found at compilation */
|
||||
int errors; /* number of errors found at compilation */
|
||||
|
||||
xmlChar *exclPrefix; /* array of excluded prefixes */
|
||||
xmlChar *exclPrefix; /* last excluded prefixes */
|
||||
xmlChar **exclPrefixTab; /* array of excluded prefixes */
|
||||
int exclPrefixNr; /* number of excluded prefixes in scope */
|
||||
int exclPrefixMax; /* size of the array */
|
||||
@ -379,6 +383,8 @@ struct _xsltTransformContext {
|
||||
int xinclude; /* should XInclude be processed */
|
||||
|
||||
const char * outputFile; /* the output URI if known */
|
||||
|
||||
int profile; /* is this run profiled */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -64,6 +64,7 @@ static int html = 0;
|
||||
#ifdef LIBXML_XINCLUDE_ENABLED
|
||||
static int xinclude = 0;
|
||||
#endif
|
||||
static int profile = 0;
|
||||
static int nonet;
|
||||
static xmlExternalEntityLoader defaultLoader = NULL;
|
||||
|
||||
@ -113,6 +114,7 @@ static void usage(const char *name) {
|
||||
#ifdef LIBXML_XINCLUDE_ENABLED
|
||||
printf(" --xinclude : do XInclude processing on document intput\n");
|
||||
#endif
|
||||
printf(" --profile : dump profiling informations \n");
|
||||
}
|
||||
|
||||
int
|
||||
@ -187,6 +189,9 @@ main(int argc, char **argv)
|
||||
} else if ((!strcmp(argv[i], "-timing")) ||
|
||||
(!strcmp(argv[i], "--timing"))) {
|
||||
timing++;
|
||||
} else if ((!strcmp(argv[i], "-profile")) ||
|
||||
(!strcmp(argv[i], "--profile"))) {
|
||||
profile++;
|
||||
} else if ((!strcmp(argv[i], "-warnnet")) ||
|
||||
(!strcmp(argv[i], "--warnnet"))) {
|
||||
xmlSetExternalEntityLoader(xsltNoNetExternalEntityLoader);
|
||||
@ -351,7 +356,11 @@ main(int argc, char **argv)
|
||||
doc = xmlParseFile(argv[i]);
|
||||
}
|
||||
}
|
||||
res = xsltApplyStylesheet(cur, doc, params);
|
||||
if (profile) {
|
||||
res = xsltProfileStylesheet(cur, doc, params, stderr);
|
||||
} else {
|
||||
res = xsltApplyStylesheet(cur, doc, params);
|
||||
}
|
||||
if (timing) {
|
||||
long msec;
|
||||
|
||||
|
@ -939,3 +939,99 @@ xsltSaveResultToFd(int fd, xmlDocPtr result, xsltStylesheetPtr style) {
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Generating proviling output *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
#define MAX_TEMPLATES 10000
|
||||
|
||||
/**
|
||||
* xsltSaveProfiling:
|
||||
* @ctxt: an XSLT context
|
||||
* @output: a FILE * for saving the informations
|
||||
*
|
||||
* Save the profiling informations on @output
|
||||
*/
|
||||
void
|
||||
xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
|
||||
int nb, i,j;
|
||||
int max;
|
||||
int total;
|
||||
xsltTemplatePtr *templates;
|
||||
xsltStylesheetPtr style;
|
||||
xsltTemplatePtr template;
|
||||
|
||||
if ((output == NULL) || (ctxt == NULL))
|
||||
return;
|
||||
if (ctxt->profile == 0)
|
||||
return;
|
||||
|
||||
nb = 0;
|
||||
max = MAX_TEMPLATES;
|
||||
templates = xmlMalloc(max * sizeof(xsltTemplatePtr));
|
||||
if (templates == NULL)
|
||||
return;
|
||||
|
||||
style = ctxt->style;
|
||||
while (style != NULL) {
|
||||
template = style->templates;
|
||||
while (template != NULL) {
|
||||
if (nb >= max)
|
||||
break;
|
||||
|
||||
templates[nb++] = template;
|
||||
template = template->next;
|
||||
}
|
||||
|
||||
style = xsltNextImport(style);
|
||||
}
|
||||
|
||||
for (i = 0;i < nb -1;i++) {
|
||||
for (j = i + 1; j < nb; j++) {
|
||||
if (templates[i]->nbCalls <= templates[j]->nbCalls) {
|
||||
template = templates[j];
|
||||
templates[j] = templates[i];
|
||||
templates[i] = template;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(output, "%6s%20s%20s%10s NbCalls\n\n",
|
||||
"number", "match", "name", "mode");
|
||||
total = 0;
|
||||
for (i = 0;i < nb;i++) {
|
||||
fprintf(output, "%5d ", i);
|
||||
if (templates[i]->match != NULL) {
|
||||
if (xmlStrlen(templates[i]->match) > 20)
|
||||
fprintf(output, "%s\n%26s", templates[i]->match, "");
|
||||
else
|
||||
fprintf(output, "%20s", templates[i]->match);
|
||||
} else {
|
||||
fprintf(output, "%20s", "");
|
||||
}
|
||||
if (templates[i]->name != NULL) {
|
||||
if (xmlStrlen(templates[i]->name) > 20)
|
||||
fprintf(output, "%s\n%46s", templates[i]->name, "");
|
||||
else
|
||||
fprintf(output, "%20s", templates[i]->name);
|
||||
} else {
|
||||
fprintf(output, "%20s", "");
|
||||
}
|
||||
if (templates[i]->mode != NULL) {
|
||||
if (xmlStrlen(templates[i]->mode) > 10)
|
||||
fprintf(output, "%s\n%56s", templates[i]->mode, "");
|
||||
else
|
||||
fprintf(output, "%10s", templates[i]->mode);
|
||||
} else {
|
||||
fprintf(output, "%10s", "");
|
||||
}
|
||||
fprintf(output, " %6d\n", templates[i]->nbCalls);
|
||||
total += templates[i]->nbCalls;
|
||||
}
|
||||
fprintf(output, "\n%30s%26s %6d\n", "Total", "", total);
|
||||
|
||||
xmlFree(templates);
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,13 @@ int xsltSaveResultToFile (FILE *file,
|
||||
int xsltSaveResultToFd (int fd,
|
||||
xmlDocPtr result,
|
||||
xsltStylesheetPtr style);
|
||||
|
||||
/*
|
||||
* profiling
|
||||
*/
|
||||
void xsltSaveProfiling (xsltTransformContextPtr ctxt,
|
||||
FILE *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -44,6 +44,14 @@ EXTRA_DIST = \
|
||||
bug-38-.xml \
|
||||
bug-39-.xml \
|
||||
bug-40-.xml \
|
||||
bug-41-.xml \
|
||||
bug-42-.xml \
|
||||
bug-43-.xml \
|
||||
bug-44-.xml \
|
||||
bug-45-.xml \
|
||||
bug-46-.xml \
|
||||
bug-47-.xml \
|
||||
bug-48-.xml \
|
||||
character.xml \
|
||||
array.xml \
|
||||
items.xml
|
||||
|
1
tests/docs/bug-41-.xml
Normal file
1
tests/docs/bug-41-.xml
Normal file
@ -0,0 +1 @@
|
||||
<doc/>
|
1
tests/docs/bug-42-.xml
Normal file
1
tests/docs/bug-42-.xml
Normal file
@ -0,0 +1 @@
|
||||
<doc/>
|
1
tests/docs/bug-43-.xml
Normal file
1
tests/docs/bug-43-.xml
Normal file
@ -0,0 +1 @@
|
||||
<doc/>
|
1
tests/docs/bug-44-.xml
Normal file
1
tests/docs/bug-44-.xml
Normal file
@ -0,0 +1 @@
|
||||
<doc/>
|
1
tests/docs/bug-45-.xml
Normal file
1
tests/docs/bug-45-.xml
Normal file
@ -0,0 +1 @@
|
||||
<doc/>
|
1
tests/docs/bug-46-.xml
Normal file
1
tests/docs/bug-46-.xml
Normal file
@ -0,0 +1 @@
|
||||
<doc/>
|
1
tests/docs/bug-47-.xml
Normal file
1
tests/docs/bug-47-.xml
Normal file
@ -0,0 +1 @@
|
||||
<doc/>
|
1
tests/docs/bug-48-.xml
Normal file
1
tests/docs/bug-48-.xml
Normal file
@ -0,0 +1 @@
|
||||
<doc/>
|
@ -46,6 +46,14 @@ EXTRA_DIST = \
|
||||
bug-38-.out bug-38-.xsl \
|
||||
bug-39-.out bug-39-.xsl \
|
||||
bug-40-.out bug-40-.xsl \
|
||||
bug-41-.out bug-41-.xsl \
|
||||
bug-42-.out bug-42-.xsl \
|
||||
bug-43-.out bug-43-.xsl \
|
||||
bug-44-.out bug-44-.xsl \
|
||||
bug-45-.out bug-45-.xsl \
|
||||
bug-46-.out bug-46-.xsl \
|
||||
bug-47-.out bug-47-.xsl \
|
||||
bug-48-.out bug-48-.xsl \
|
||||
character.out character.xsl \
|
||||
character2.out character2.xsl \
|
||||
itemschoose.out itemschoose.xsl \
|
||||
|
2
tests/general/bug-41-.out
Normal file
2
tests/general/bug-41-.out
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
SUCCESS
|
18
tests/general/bug-41-.xsl
Normal file
18
tests/general/bug-41-.xsl
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'>
|
||||
|
||||
<xsl:variable name="foo" select="'FAILURE'"/>
|
||||
|
||||
<xsl:template name="test">
|
||||
<xsl:value-of select="$foo"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:variable name="foo" select="'FAILURE'"/>
|
||||
<xsl:call-template name="test">
|
||||
<xsl:with-param name="foo" select="'SUCCESS'"/>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
2
tests/general/bug-42-.out
Normal file
2
tests/general/bug-42-.out
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
SUCCESS
|
16
tests/general/bug-42-.xsl
Normal file
16
tests/general/bug-42-.xsl
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'>
|
||||
|
||||
<xsl:variable name="foo" select="'SUCCESS'"/>
|
||||
|
||||
<xsl:template match="doc">
|
||||
<xsl:value-of select="$foo"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:variable name="foo" select="'FAILURE'"/>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
2
tests/general/bug-43-.out
Normal file
2
tests/general/bug-43-.out
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
SUCCESS
|
18
tests/general/bug-43-.xsl
Normal file
18
tests/general/bug-43-.xsl
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'>
|
||||
|
||||
<xsl:variable name="foo" select="'FAILURE'"/>
|
||||
|
||||
<xsl:template match="doc">
|
||||
<xsl:value-of select="$foo"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:variable name="foo" select="'FAILURE'"/>
|
||||
<xsl:apply-templates>
|
||||
<xsl:with-param name="foo" select="'SUCCESS'"/>
|
||||
</xsl:apply-templates>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
2
tests/general/bug-44-.out
Normal file
2
tests/general/bug-44-.out
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
SUCCESS
|
19
tests/general/bug-44-.xsl
Normal file
19
tests/general/bug-44-.xsl
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'>
|
||||
|
||||
<xsl:variable name="foo" select="'FAILURE'"/>
|
||||
|
||||
<xsl:template name="test">
|
||||
<xsl:param name="foo" select="'FAILURE'"/>
|
||||
<xsl:value-of select="$foo"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:variable name="foo" select="'FAILURE'"/>
|
||||
<xsl:call-template name="test">
|
||||
<xsl:with-param name="foo" select="'SUCCESS'"/>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
2
tests/general/bug-45-.out
Normal file
2
tests/general/bug-45-.out
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
SUCCESS
|
27
tests/general/bug-45-.xsl
Normal file
27
tests/general/bug-45-.xsl
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'>
|
||||
|
||||
<xsl:variable name="foo" select="'1'"/>
|
||||
|
||||
<xsl:template name="test">
|
||||
<xsl:param name="foo" select="'2'"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$foo = '0'">
|
||||
<xsl:text>SUCCESS</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>FAILURE </xsl:text>
|
||||
<xsl:value-of select="$foo"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:variable name="foo" select="'3'"/>
|
||||
<xsl:call-template name="test">
|
||||
<xsl:with-param name="foo" select="'0'"/>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
2
tests/general/bug-46-.out
Normal file
2
tests/general/bug-46-.out
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
SUCCESS
|
16
tests/general/bug-46-.xsl
Normal file
16
tests/general/bug-46-.xsl
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'>
|
||||
|
||||
<xsl:template name="test">
|
||||
<xsl:text>SUCCESS</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:variable name="foo">
|
||||
<xsl:call-template name="test"/>
|
||||
</xsl:variable>
|
||||
<xsl:value-of select="$foo"/>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
2
tests/general/bug-47-.out
Normal file
2
tests/general/bug-47-.out
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
SUCCESS
|
18
tests/general/bug-47-.xsl
Normal file
18
tests/general/bug-47-.xsl
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'>
|
||||
|
||||
<xsl:template name="test">
|
||||
<xsl:text>SUCCESS</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:variable name="foo">
|
||||
<xsl:call-template name="test"/>
|
||||
</xsl:variable>
|
||||
<xsl:if test="1">
|
||||
<xsl:value-of select="$foo"/>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
2
tests/general/bug-48-.out
Normal file
2
tests/general/bug-48-.out
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
SUCCESS
|
24
tests/general/bug-48-.xsl
Normal file
24
tests/general/bug-48-.xsl
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'>
|
||||
|
||||
<xsl:template name="empty">
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="test">
|
||||
<xsl:text>SUCCESS</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:variable name="foo">
|
||||
<xsl:call-template name="test"/>
|
||||
</xsl:variable>
|
||||
<xsl:if test="1">
|
||||
<xsl:apply-templates select="doc" name="empty">
|
||||
<xsl:with-param name="unused" select="$foo"/>
|
||||
</xsl:apply-templates>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="$foo"/>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
Loading…
Reference in New Issue
Block a user