From 1a3df8fbed571ff7426e36feaf47c212ea772b0e Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Wed, 14 Feb 2001 14:45:10 +0000 Subject: [PATCH] The XML Rec formatting test starts looking okay, also added apply-imports support: - FEATURES libxslt/imports.h libxslt/pattern.[ch] libxslt/xsltInternals.h libxslt/transform.[ch] libxslt/templates.c libxslt/xslt.c: Added apply-imports, keep a stack of running templates - libxslt/xsltutils.c: bugfixes, gather the output informations down the cascade - tests/xmlspec/Makefile.am tests/xmlspec/REC-xml-2e.xsl tests/xmlspec/diffspec.xsl tests/xmlspec/xmlspec.xsl: running the real set of transformation on XML-1.0 2e generages a near perfect HTML. Needs just more number fixes and implementation and an obscure problem in 3.3.3 Daniel --- ChangeLog | 14 ++ FEATURES | 2 +- libxslt/imports.h | 22 +++ libxslt/pattern.c | 42 +++--- libxslt/pattern.h | 3 +- libxslt/templates.c | 3 +- libxslt/transform.c | 159 +++++++++++++++++---- libxslt/transform.h | 1 + libxslt/variables.c | 2 +- libxslt/xslt.c | 1 + libxslt/xsltInternals.h | 6 + libxslt/xsltutils.c | 74 ++++++---- tests/xmlspec/Makefile.am | 4 +- tests/xmlspec/REC-xml-2e.xsl | 31 ++++ tests/xmlspec/diffspec.xsl | 329 +++++++++++++++++++++++++++++++++++++++++++ 15 files changed, 620 insertions(+), 73 deletions(-) create mode 100644 tests/xmlspec/REC-xml-2e.xsl create mode 100644 tests/xmlspec/diffspec.xsl diff --git a/ChangeLog b/ChangeLog index 0d6bd2f..321594d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Wed Feb 14 15:39:06 CET 2001 Daniel Veillard + + * FEATURES libxslt/imports.h libxslt/pattern.[ch] + libxslt/xsltInternals.h libxslt/transform.[ch] + libxslt/templates.c libxslt/xslt.c: + Added apply-imports, keep a stack of running templates + * libxslt/xsltutils.c: bugfixes, gather the output informations + down the cascade + * tests/xmlspec/Makefile.am tests/xmlspec/REC-xml-2e.xsl + tests/xmlspec/diffspec.xsl tests/xmlspec/xmlspec.xsl: running + the real set of transformation on XML-1.0 2e generages a near + perfect HTML. Needs just more number fixes and implementation + and an obscure problem in 3.3.3 + Tue Feb 13 20:31:03 CET 2001 Bjorn Reese * libxslt/pattern.c: added xsltMatchPattern() diff --git a/FEATURES b/FEATURES index 4f7653b..50cab8e 100644 --- a/FEATURES +++ b/FEATURES @@ -87,7 +87,7 @@ YES xsl:apply-templates YES select = node-set-expression YES mode = qname -NO xsl:apply-imports +YES xsl:apply-imports YES xsl:call-template YES name = qname diff --git a/libxslt/imports.h b/libxslt/imports.h index 9aa280a..63bbdd1 100644 --- a/libxslt/imports.h +++ b/libxslt/imports.h @@ -16,6 +16,28 @@ extern "C" { #endif +/* + * A couple of macros to apply the cascade + */ +#define XSLT_GET_IMPORT_PTR(res, style, name) { \ + xsltStylesheetPtr st = style; \ + res = NULL; \ + while (st != NULL) { \ + if (st->name != NULL) { res = st->name; break; } \ + st = xsltNextImport(st); \ + }} + +#define XSLT_GET_IMPORT_INT(res, style, name) { \ + xsltStylesheetPtr st = style; \ + res = -1; \ + while (st != NULL) { \ + if (st->name != -1) { res = st->name; break; } \ + st = xsltNextImport(st); \ + }} + +/* + * Module interfaces + */ void xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur); void xsltParseStylesheetInclude(xsltStylesheetPtr style, diff --git a/libxslt/pattern.c b/libxslt/pattern.c index 9b767ab..53c663f 100644 --- a/libxslt/pattern.c +++ b/libxslt/pattern.c @@ -1389,15 +1389,18 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, /** * xsltGetTemplate: * @ctxt: a XSLT process context - * @mode: the mode name or NULL + * @mode: the mode + * @style: the current style * - * Finds the template applying to this node + * Finds the template applying to this node, if @style is non-NULL + * it means one need to look for the next imported template in scope. * * Returns the xsltTemplatePtr or NULL if not found */ xsltTemplatePtr -xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node) { - xsltStylesheetPtr style; +xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, + xsltStylesheetPtr style) { + xsltStylesheetPtr curstyle; xsltTemplatePtr ret = NULL; const xmlChar *name = NULL; xsltCompMatchPtr list = NULL; @@ -1405,10 +1408,15 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node) { if ((ctxt == NULL) || (node == NULL)) return(NULL); - style = ctxt->style; - while (style != NULL) { + if (style == NULL) { + curstyle = ctxt->style; + } else { + curstyle = xsltNextImport(style); + } + + while ((curstyle != NULL) && (curstyle != style)) { /* TODO : handle IDs/keys here ! */ - if (style->templatesHash != NULL) { + if (curstyle->templatesHash != NULL) { /* * Use the top name as selector */ @@ -1445,7 +1453,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node) { /* * find the list of appliable expressions based on the name */ - list = (xsltCompMatchPtr) xmlHashLookup3(style->templatesHash, + list = (xsltCompMatchPtr) xmlHashLookup3(curstyle->templatesHash, name, ctxt->mode, ctxt->modeURI); } while (list != NULL) { @@ -1463,24 +1471,24 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node) { */ switch (node->type) { case XML_ELEMENT_NODE: - list = style->elemMatch; + list = curstyle->elemMatch; break; case XML_ATTRIBUTE_NODE: - list = style->attrMatch; + list = curstyle->attrMatch; break; case XML_PI_NODE: - list = style->piMatch; + list = curstyle->piMatch; break; case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE: - list = style->rootMatch; + list = curstyle->rootMatch; break; case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: - list = style->textMatch; + list = curstyle->textMatch; break; case XML_COMMENT_NODE: - list = style->commentMatch; + list = curstyle->commentMatch; break; case XML_ENTITY_REF_NODE: case XML_ENTITY_NODE: @@ -1509,7 +1517,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node) { list = list->next; } if (node->_private != NULL) { - list = style->keyMatch; + list = curstyle->keyMatch; while ((list != NULL) && ((ret == NULL) || (list->priority > ret->priority))) { if (xsltTestCompMatch(ctxt, list, node, @@ -1525,9 +1533,9 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node) { return(ret); /* - * Cycle on next stylesheet import. + * Cycle on next curstylesheet import. */ - style = xsltNextImport(style); + curstyle = xsltNextImport(curstyle); } return(NULL); } diff --git a/libxslt/pattern.h b/libxslt/pattern.h index 67b7073..4320ec9 100644 --- a/libxslt/pattern.h +++ b/libxslt/pattern.h @@ -20,7 +20,8 @@ int xsltAddTemplate (xsltStylesheetPtr style, const xmlChar *mode, const xmlChar *modeURI); xsltTemplatePtr xsltGetTemplate (xsltTransformContextPtr ctxt, - xmlNodePtr node); + xmlNodePtr node, + xsltStylesheetPtr style); void xsltFreeTemplateHashes (xsltStylesheetPtr style); int xsltMatchPattern (xsltTransformContextPtr ctxt, xmlNodePtr node, diff --git a/libxslt/templates.c b/libxslt/templates.c index 6e2fe6f..5274056 100644 --- a/libxslt/templates.c +++ b/libxslt/templates.c @@ -30,6 +30,7 @@ #define DEBUG_TEMPLATES + /************************************************************************ * * * Module interfaces * @@ -163,7 +164,7 @@ xsltEvalTemplateString(xsltTransformContextPtr ctxt, xmlNodePtr node, oldInsert = ctxt->insert; ctxt->insert = insert; - xsltApplyOneTemplate(ctxt, node, parent->children); + xsltApplyOneTemplate(ctxt, node, NULL, parent->children); ctxt->insert = oldInsert; diff --git a/libxslt/transform.c b/libxslt/transform.c index c52efc1..61f40cc 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -53,6 +53,43 @@ #define IS_BLANK_NODE(n) \ (((n)->type == XML_TEXT_NODE) && (xsltIsBlank((n)->content))) +/* + * Generic function for accessing stacks in the transform Context + */ + +#define PUSH_AND_POP(scope, type, name) \ +scope int name##Push(xsltTransformContextPtr ctxt, type value) { \ + if (ctxt->name##Nr >= ctxt->name##Max) { \ + ctxt->name##Max *= 2; \ + ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \ + ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \ + if (ctxt->name##Tab == NULL) { \ + xmlGenericError(xmlGenericErrorContext, \ + "realloc failed !\n"); \ + return(0); \ + } \ + } \ + ctxt->name##Tab[ctxt->name##Nr] = value; \ + ctxt->name = value; \ + return(ctxt->name##Nr++); \ +} \ +scope type name##Pop(xsltTransformContextPtr ctxt) { \ + type ret; \ + if (ctxt->name##Nr <= 0) return(0); \ + ctxt->name##Nr--; \ + if (ctxt->name##Nr > 0) \ + ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \ + else \ + ctxt->name = NULL; \ + ret = ctxt->name##Tab[ctxt->name##Nr]; \ + ctxt->name##Tab[ctxt->name##Nr] = 0; \ + return(ret); \ +} \ + +/* + * Those macros actually generate the functions + */ +PUSH_AND_POP(extern, xsltTemplatePtr, templ) /************************************************************************ * * @@ -81,12 +118,24 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { return(NULL); } memset(cur, 0, sizeof(xsltTransformContext)); + cur->templTab = (xsltTemplatePtr *) + xmlMalloc(10 * sizeof(xsltTemplatePtr)); + if (cur->templTab == NULL) { + xmlGenericError(xmlGenericErrorContext, + "xsltNewTransformContext: out of memory\n"); + xmlFree(cur); + return(NULL); + } + cur->templNr = 0; + cur->templMax = 5; + cur->templ = NULL; cur->style = style; xmlXPathInit(); cur->xpathCtxt = xmlXPathNewContext(doc); if (cur->xpathCtxt == NULL) { xsltGenericError(xsltGenericErrorContext, "xsltNewTransformContext : xmlXPathNewContext failed\n"); + xmlFree(cur->templTab); xmlFree(cur); return(NULL); } @@ -95,6 +144,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { if (docu == NULL) { xsltGenericError(xsltGenericErrorContext, "xsltNewTransformContext : xsltNewDocument failed\n"); + xmlFree(cur->templTab); xmlFree(cur); return(NULL); } @@ -115,6 +165,8 @@ xsltFreeTransformContext(xsltTransformContextPtr ctxt) { return; if (ctxt->xpathCtxt != NULL) xmlXPathFreeContext(ctxt->xpathCtxt); + if (ctxt->templTab != NULL) + xmlFree(ctxt->templTab); xsltFreeVariableHashes(ctxt); xsltFreeDocuments(ctxt); memset(ctxt, -1, sizeof(xsltTransformContext)); @@ -450,7 +502,15 @@ xsltCopy(xsltTransformContextPtr ctxt, xmlNodePtr node, } } - xsltApplyOneTemplate(ctxt, ctxt->node, inst->children); + switch (node->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + case XML_ELEMENT_NODE: + xsltApplyOneTemplate(ctxt, ctxt->node, NULL, inst->children); + break; + default: + break; + } ctxt->insert = oldInsert; } @@ -529,7 +589,7 @@ xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlFree(attributes); } - xsltApplyOneTemplate(ctxt, ctxt->node, inst->children); + xsltApplyOneTemplate(ctxt, ctxt->node, NULL, inst->children); error: if (prop != NULL) @@ -949,7 +1009,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { case XML_ELEMENT_NODE: break; case XML_CDATA_SECTION_NODE: - template = xsltGetTemplate(ctxt, node); + template = xsltGetTemplate(ctxt, node, NULL); if (template) { xmlNodePtr oldNode; @@ -960,7 +1020,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { #endif oldNode = ctxt->node; ctxt->node = node; - xsltApplyOneTemplate(ctxt, node, template->content); + xsltApplyOneTemplate(ctxt, node, template, NULL); ctxt->node = oldNode; } else /* if (ctxt->mode == NULL) */ { #ifdef DEBUG_PROCESS @@ -978,7 +1038,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { } return; case XML_TEXT_NODE: - template = xsltGetTemplate(ctxt, node); + template = xsltGetTemplate(ctxt, node, NULL); if (template) { xmlNodePtr oldNode; @@ -989,7 +1049,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { #endif oldNode = ctxt->node; ctxt->node = node; - xsltApplyOneTemplate(ctxt, node, template->content); + xsltApplyOneTemplate(ctxt, node, template, NULL); ctxt->node = oldNode; } else /* if (ctxt->mode == NULL) */ { #ifdef DEBUG_PROCESS @@ -1013,13 +1073,13 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { case XML_ATTRIBUTE_NODE: if (ctxt->insert->type == XML_ELEMENT_NODE) { xmlAttrPtr attr = (xmlAttrPtr) node, ret = NULL, cur; - template = xsltGetTemplate(ctxt, node); + template = xsltGetTemplate(ctxt, node, NULL); if (template) { xmlNodePtr oldNode; oldNode = ctxt->node; ctxt->node = node; - xsltApplyOneTemplate(ctxt, node, template->content); + xsltApplyOneTemplate(ctxt, node, template, NULL); ctxt->node = oldNode; } else if (ctxt->mode == NULL) { if (attr->ns != NULL) { @@ -1100,13 +1160,13 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { */ attrs = node->properties; while (attrs != NULL) { - template = xsltGetTemplate(ctxt, (xmlNodePtr) attrs); + template = xsltGetTemplate(ctxt, (xmlNodePtr) attrs, NULL); if (template) { xmlNodePtr oldNode; oldNode = ctxt->node; ctxt->node = node; - xsltApplyOneTemplate(ctxt, node, template->content); + xsltApplyOneTemplate(ctxt, node, template, NULL); ctxt->node = oldNode; } attrs = attrs->next; @@ -1125,7 +1185,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { xsltProcessOneNode(ctxt, cur); break; case XML_CDATA_SECTION_NODE: - template = xsltGetTemplate(ctxt, node); + template = xsltGetTemplate(ctxt, node, NULL); if (template) { xmlNodePtr oldNode; @@ -1136,7 +1196,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { #endif oldNode = ctxt->node; ctxt->node = node; - xsltApplyOneTemplate(ctxt, node, template->content); + xsltApplyOneTemplate(ctxt, node, template, NULL); ctxt->node = oldNode; } else /* if (ctxt->mode == NULL) */ { #ifdef DEBUG_PROCESS @@ -1154,7 +1214,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { } break; case XML_TEXT_NODE: - template = xsltGetTemplate(ctxt, cur); + template = xsltGetTemplate(ctxt, cur, NULL); if (template) { xmlNodePtr oldNode; @@ -1167,7 +1227,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { ctxt->node = cur; ctxt->xpathCtxt->contextSize = nbchild; ctxt->xpathCtxt->proximityPosition = childno; - xsltApplyOneTemplate(ctxt, cur, template->content); + xsltApplyOneTemplate(ctxt, cur, template, NULL); ctxt->node = oldNode; } else /* if (ctxt->mode == NULL) */ { #ifdef DEBUG_PROCESS @@ -1190,7 +1250,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { break; case XML_PI_NODE: case XML_COMMENT_NODE: - template = xsltGetTemplate(ctxt, cur); + template = xsltGetTemplate(ctxt, cur, NULL); if (template) { xmlNodePtr oldNode; @@ -1198,7 +1258,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { ctxt->node = cur; ctxt->xpathCtxt->contextSize = nbchild; ctxt->xpathCtxt->proximityPosition = childno; - xsltApplyOneTemplate(ctxt, cur, template->content); + xsltApplyOneTemplate(ctxt, cur, template, NULL); ctxt->node = oldNode; } break; @@ -1212,6 +1272,30 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { } /** + * xsltApplyImports: + * @ctxt: a XSLT process context + * @node: the node in the source tree. + * @inst: the xslt apply-imports node + * + * Process the xslt apply-imports node on the source node + */ +void +xsltApplyImports(xsltTransformContextPtr ctxt, xmlNodePtr node, + xmlNodePtr inst) { + xsltTemplatePtr template; + + if ((ctxt->templ == NULL) || (ctxt->templ->style == NULL)) { + xsltGenericError(xsltGenericErrorContext, + "xslt:apply-imports : internal error no current template\n"); + return; + } + template = xsltGetTemplate(ctxt, node, ctxt->templ->style); + if (template != NULL) { + xsltApplyOneTemplate(ctxt, node, template, NULL); + } +} + +/** * xsltCallTemplate: * @ctxt: a XSLT process context * @node: the node in the source tree. @@ -1282,7 +1366,7 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, } cur = cur->next; } - xsltApplyOneTemplate(ctxt, node, template->content); + xsltApplyOneTemplate(ctxt, node, template, NULL); error: if (has_param == 1) @@ -1511,23 +1595,35 @@ error: * xsltApplyOneTemplate: * @ctxt: a XSLT process context * @node: the node in the source tree. + * @templ: the template * @list: the template replacement nodelist * * Process the apply-templates node on the source node */ void xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, - xmlNodePtr list) { + xsltTemplatePtr templ, xmlNodePtr list) { xmlNodePtr cur = NULL, insert, copy = NULL; xmlNodePtr oldInsert; xmlAttrPtr attrs; int has_variables = 0; + if ((templ == NULL) && (list == NULL)) + return; CHECK_STOPPED; + + /* + * stack and saves + */ + if (templ != NULL) + templPush(ctxt, templ); oldInsert = insert = ctxt->insert; + /* * Insert all non-XSLT nodes found in the template */ + if ((list == NULL) && (templ != NULL)) + list = templ->content; cur = list; while (cur != NULL) { /* @@ -1538,6 +1634,11 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltGenericDebug(xsltGenericDebugContext, "xsltApplyOneTemplate: insert == NULL !\n"); #endif + if (has_variables != 0) { + xsltPopStack(ctxt); + } + if (templ != NULL) + templPop(ctxt); return; } @@ -1570,6 +1671,10 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, ctxt->insert = insert; xsltForEach(ctxt, node, cur); ctxt->insert = oldInsert; + } else if (IS_XSLT_NAME(cur, "apply-imports")) { + ctxt->insert = insert; + xsltApplyImports(ctxt, node, cur); + ctxt->insert = oldInsert; } else if (IS_XSLT_NAME(cur, "attribute")) { ctxt->insert = insert; xsltAttribute(ctxt, node, cur); @@ -1644,7 +1749,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, "xsltApplyOneTemplate: text copy failed\n"); } } else if ((cur->type == XML_ELEMENT_NODE) && - (xmlStrEqual(cur->name, "xsltdebug"))) { + (xmlStrEqual(cur->name, (const xmlChar *)"xsltdebug"))) { xsltDebug(ctxt, cur); } else if (cur->type == XML_ELEMENT_NODE) { #ifdef DEBUG_PROCESS @@ -1703,6 +1808,8 @@ skip_children: if (has_variables != 0) { xsltPopStack(ctxt); } + if (templ != NULL) + templPop(ctxt); } /** @@ -1785,7 +1892,7 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node, "xsl:when: test evaluate to %d\n", doit); #endif if (doit) { - xsltApplyOneTemplate(ctxt, ctxt->node, when->children); + xsltApplyOneTemplate(ctxt, ctxt->node, NULL, when->children); goto done; } if (xpathParserCtxt != NULL) @@ -1800,7 +1907,7 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node, replacement = replacement->next; } if (IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "otherwise"))) { - xsltApplyOneTemplate(ctxt, ctxt->node, replacement->children); + xsltApplyOneTemplate(ctxt, ctxt->node, NULL, replacement->children); replacement = replacement->next; } if (replacement != NULL) { @@ -1884,7 +1991,7 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr node, "xsltIf: test evaluate to %d\n", doit); #endif if (doit) { - xsltApplyOneTemplate(ctxt, node, inst->children); + xsltApplyOneTemplate(ctxt, node, NULL, inst->children); } error: @@ -1976,7 +2083,7 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node, for (i = 0;i < list->nodeNr;i++) { ctxt->node = list->nodeTab[i]; ctxt->xpathCtxt->proximityPosition = i + 1; - xsltApplyOneTemplate(ctxt, list->nodeTab[i], replacement); + xsltApplyOneTemplate(ctxt, list->nodeTab[i], NULL, replacement); } ctxt->nodeList = oldlist; ctxt->xpathCtxt->contextSize = oldContextSize; @@ -2003,7 +2110,7 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { xsltTemplatePtr template; xmlNodePtr oldNode; - template = xsltGetTemplate(ctxt, node); + template = xsltGetTemplate(ctxt, node, NULL); /* * If no template is found, apply the default rule. */ @@ -2032,7 +2139,7 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { "xsltProcessOneNode: applying template for attribute %s\n", node->name); #endif - xsltApplyOneTemplate(ctxt, node, template->content); + xsltApplyOneTemplate(ctxt, node, template, NULL); } else { #ifdef DEBUG_PROCESS if (node->type == XML_DOCUMENT_NODE) @@ -2044,7 +2151,7 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { #endif oldNode = ctxt->node; ctxt->node = node; - xsltApplyOneTemplate(ctxt, node, template->content); + xsltApplyOneTemplate(ctxt, node, template, NULL); ctxt->node = oldNode; } } diff --git a/libxslt/transform.h b/libxslt/transform.h index de953fb..cd2a3d8 100644 --- a/libxslt/transform.h +++ b/libxslt/transform.h @@ -23,6 +23,7 @@ xmlDocPtr xsltApplyStylesheet (xsltStylesheetPtr style, xmlDocPtr doc); void xsltApplyOneTemplate (xsltTransformContextPtr ctxt, xmlNodePtr node, + xsltTemplatePtr templ, xmlNodePtr list); #ifdef __cplusplus } diff --git a/libxslt/variables.c b/libxslt/variables.c index 4ea0175..9ac4095 100644 --- a/libxslt/variables.c +++ b/libxslt/variables.c @@ -354,7 +354,7 @@ xsltEvalVariables(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) { oldNode = ctxt->node; ctxt->insert = container; - xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree); + xsltApplyOneTemplate(ctxt, ctxt->node, NULL, elem->tree); ctxt->insert = oldInsert; ctxt->node = oldNode; diff --git a/libxslt/xslt.c b/libxslt/xslt.c index 37f9e57..3565b7c 100644 --- a/libxslt/xslt.c +++ b/libxslt/xslt.c @@ -1019,6 +1019,7 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { return; ret->next = style->templates; style->templates = ret; + ret->style = style; /* * Get arguments diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h index caca594..3a89fe7 100644 --- a/libxslt/xsltInternals.h +++ b/libxslt/xsltInternals.h @@ -52,6 +52,7 @@ typedef struct _xsltTemplate xsltTemplate; typedef xsltTemplate *xsltTemplatePtr; struct _xsltTemplate { struct _xsltTemplate *next;/* chained list sorted by priority */ + struct _xsltStylesheet *style;/* the containing stylesheet */ xmlChar *match; /* the matching string */ int priority; /* as given from the stylesheet, not computed */ xmlChar *name; /* the local part of the name QName */ @@ -194,6 +195,11 @@ struct _xsltTransformContext { xsltStylesheetPtr style; /* the stylesheet used */ xsltOutputType type; /* the type of output */ + xsltTemplatePtr templ; /* the current template */ + int templNr; /* Nb of templates in the stack */ + int templMax; /* Size of the templtes stack */ + xsltTemplatePtr *templTab; /* the template stack */ + const xmlChar *mode; /* the current mode */ const xmlChar *modeURI; /* the current mode URI */ diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c index 3f9ec1d..e7d6048 100644 --- a/libxslt/xsltutils.c +++ b/libxslt/xsltutils.c @@ -22,6 +22,7 @@ #include "xsltutils.h" #include "templates.h" #include "xsltInternals.h" +#include "imports.h" /************************************************************************ @@ -293,6 +294,7 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, const xmlChar *encoding; xmlNodePtr root; int base; + const xmlChar *method; if ((buf == NULL) || (result == NULL) || (style == NULL)) return(-1); @@ -307,19 +309,23 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, /* TODO: when outputing and having imported stylesheets, apply cascade */ base = buf->written; - encoding = style->encoding; - if (style->method == NULL) + + XSLT_GET_IMPORT_PTR(method, style, method) + XSLT_GET_IMPORT_PTR(encoding, style, encoding) + + if (method == NULL) root = xmlDocGetRootElement(result); else root = NULL; - if ((style->method != NULL) && - (xmlStrEqual(style->method, (const xmlChar *) "html"))) { + + if ((method != NULL) && + (xmlStrEqual(method, (const xmlChar *) "html"))) { htmlDocContentDumpOutput(buf, result, (const char *) encoding); - } else if ((style->method != NULL) && - (xmlStrEqual(style->method, (const xmlChar *) "xhtml"))) { + } else if ((method != NULL) && + (xmlStrEqual(method, (const xmlChar *) "xhtml"))) { htmlDocContentDumpOutput(buf, result, (const char *) encoding); - } else if ((style->method != NULL) && - (xmlStrEqual(style->method, (const xmlChar *) "text"))) { + } else if ((method != NULL) && + (xmlStrEqual(method, (const xmlChar *) "text"))) { xmlNodePtr cur; cur = result->children; @@ -329,7 +335,21 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, cur = cur->next; } } else { - if (style->omitXmlDeclaration != 1) { + int omitXmlDecl; + int standalone; + int indent; + const xmlChar *version; + const xmlChar *doctypePublic; + const xmlChar *doctypeSystem; + + XSLT_GET_IMPORT_INT(omitXmlDecl, style, omitXmlDeclaration); + XSLT_GET_IMPORT_INT(standalone, style, standalone); + XSLT_GET_IMPORT_INT(indent, style, indent); + XSLT_GET_IMPORT_PTR(version, style, version) + XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic) + XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem) + + if (omitXmlDecl != 1) { xmlOutputBufferWriteString(buf, "version != NULL) xmlBufferWriteQuotedString(buf->buffer, result->version); @@ -347,7 +367,7 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, xmlOutputBufferWriteString(buf, " encoding="); xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding); } - switch (style->standalone) { + switch (standalone) { case 0: xmlOutputBufferWriteString(buf, " standalone=\"no\""); break; @@ -359,7 +379,7 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, } xmlOutputBufferWriteString(buf, "?>\n"); } - if ((style->doctypePublic != NULL) || (style->doctypeSystem != NULL)) { + if ((doctypePublic != NULL) || (doctypeSystem != NULL)) { xmlNodePtr cur = result->children; while (cur != NULL) { @@ -370,24 +390,24 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, if ((cur != NULL) && (cur->name != NULL)) { xmlOutputBufferWriteString(buf, "name); - if (style->doctypePublic != NULL) { - if (style->doctypeSystem != NULL) { + if (doctypePublic != NULL) { + if (doctypeSystem != NULL) { xmlOutputBufferWriteString(buf, " PUBLIC "); xmlBufferWriteQuotedString(buf->buffer, - style->doctypePublic); + doctypePublic); xmlOutputBufferWriteString(buf, " "); xmlBufferWriteQuotedString(buf->buffer, - style->doctypeSystem); + doctypeSystem); } else { xmlOutputBufferWriteString(buf, " PUBLIC \"-\" "); xmlBufferWriteQuotedString(buf->buffer, - style->doctypeSystem); + doctypeSystem); } } else { xmlOutputBufferWriteString(buf, " SYSTEM "); xmlBufferWriteQuotedString(buf->buffer, - style->doctypeSystem); + doctypeSystem); } xmlOutputBufferWriteString(buf, ">\n"); } @@ -396,7 +416,7 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, xmlNodePtr child = result->children; while (child != NULL) { - xmlNodeDumpOutput(buf, result, child, 0, (style->indent == 1), + xmlNodeDumpOutput(buf, result, child, 0, (indent == 1), (const char *) encoding); xmlOutputBufferWriteString(buf, "\n"); child = child->next; @@ -423,15 +443,17 @@ int xsltSaveResultToFilename(const char *URL, xmlDocPtr result, xsltStylesheetPtr style, int compression) { xmlOutputBufferPtr buf; + const xmlChar *encoding; int ret; if ((URL == NULL) || (result == NULL) || (style == NULL)) return(-1); - if (style->encoding != NULL) { + XSLT_GET_IMPORT_PTR(encoding, style, encoding) + if (encoding != NULL) { xmlCharEncodingHandlerPtr encoder; - encoder = xmlFindCharEncodingHandler((char *)style->encoding); + encoder = xmlFindCharEncodingHandler((char *)encoding); if ((encoder != NULL) && (xmlStrEqual((const xmlChar *)encoder->name, (const xmlChar *) "UTF-8"))) @@ -462,15 +484,17 @@ xsltSaveResultToFilename(const char *URL, xmlDocPtr result, int xsltSaveResultToFile(FILE *file, xmlDocPtr result, xsltStylesheetPtr style) { xmlOutputBufferPtr buf; + const xmlChar *encoding; int ret; if ((file == NULL) || (result == NULL) || (style == NULL)) return(-1); - if (style->encoding != NULL) { + XSLT_GET_IMPORT_PTR(encoding, style, encoding) + if (encoding != NULL) { xmlCharEncodingHandlerPtr encoder; - encoder = xmlFindCharEncodingHandler((char *)style->encoding); + encoder = xmlFindCharEncodingHandler((char *)encoding); if ((encoder != NULL) && (xmlStrEqual((const xmlChar *)encoder->name, (const xmlChar *) "UTF-8"))) @@ -502,15 +526,17 @@ xsltSaveResultToFile(FILE *file, xmlDocPtr result, xsltStylesheetPtr style) { int xsltSaveResultToFd(int fd, xmlDocPtr result, xsltStylesheetPtr style) { xmlOutputBufferPtr buf; + const xmlChar *encoding; int ret; if ((fd < 0) || (result == NULL) || (style == NULL)) return(-1); - if (style->encoding != NULL) { + XSLT_GET_IMPORT_PTR(encoding, style, encoding) + if (encoding != NULL) { xmlCharEncodingHandlerPtr encoder; - encoder = xmlFindCharEncodingHandler((char *)style->encoding); + encoder = xmlFindCharEncodingHandler((char *)encoding); if ((encoder != NULL) && (xmlStrEqual((const xmlChar *)encoder->name, (const xmlChar *) "UTF-8"))) diff --git a/tests/xmlspec/Makefile.am b/tests/xmlspec/Makefile.am index f1cf513..b6bf213 100644 --- a/tests/xmlspec/Makefile.am +++ b/tests/xmlspec/Makefile.am @@ -4,13 +4,13 @@ $(top_builddir)/libxslt/xsltproc: @(cd ../../libxslt ; make xsltproc) EXTRA_DIST = REC-xml-20001006.xml xmlspec-v21.dtd W3C-REC.css \ - logo-REC xmlspec.xsl + logo-REC xmlspec.xsl REC-xml-2e.xsl diffspec.xsl all: test test tests: $(top_builddir)/libxslt/xsltproc @(rm -f .memdump ; touch .memdump) - @($(top_builddir)/libxslt/xsltproc -timing -v xmlspec.xsl REC-xml-20001006.xml > REC-xml-20001006.html 2> debug ; \ + @($(top_builddir)/libxslt/xsltproc -timing -v REC-xml-2e.xsl REC-xml-20001006.xml > REC-xml-20001006.html 2> debug ; \ grep implemented debug | sort | uniq -c ; \ grep " ms$$" debug ; \ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\ diff --git a/tests/xmlspec/REC-xml-2e.xsl b/tests/xmlspec/REC-xml-2e.xsl new file mode 100644 index 0000000..afe3fc1 --- /dev/null +++ b/tests/xmlspec/REC-xml-2e.xsl @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/xmlspec/diffspec.xsl b/tests/xmlspec/diffspec.xsl new file mode 100644 index 0000000..50e5887 --- /dev/null +++ b/tests/xmlspec/diffspec.xsl @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + +1 + + + + +div.diff-add { background-color: yellow } +div.diff-del { text-decoration: line-through } +div.diff-chg { background-color: lime } +div.diff-off { } + +span.diff-add { background-color: yellow } +span.diff-del { text-decoration: line-through } +span.diff-chg { background-color: lime } +span.diff-off { } + +td.diff-add { background-color: yellow } +td.diff-del { text-decoration: line-through } +td.diff-chg { background-color: lime } +td.diff-off { } + + + + + + + Review Version + + + +1 + + + + + off + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+ + + + + + chg + + + + + + + + + + + + + add + + + + + + + + + + + + + del + + + + + + + + + + + + + off + + + + + + + + + + + + + + + + + + + + + + + + + + + + (See + + + + .) + + + + + +
+ + + +
+
+
+ +
+
+
+ + + + +
+ +
+
+ +
+
+
+
+ + + + + +
+ + + +
+
+ + + + +
+ +
+
+
+
+ + + + + +
+
+ +
+
+
+ + + + +
+ +
+
+
+
+ + + + + + +
+ + Editor + + s + + : + +
+
+ + + + +
+ Editor + + s + + : +
+
+
+ +
+ + + + + + + +
+ + + + - Second Edition + + +
+
+ + + + +
+ + + - Second Edition + +
+
+
+
+ +
-- 2.7.4