+Wed Feb 14 15:39:06 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+ * 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 <breese@users.sourceforge.net>
* libxslt/pattern.c: added xsltMatchPattern()
YES select = node-set-expression
YES mode = qname
-NO xsl:apply-imports
+YES xsl:apply-imports
YES xsl:call-template
YES name = qname
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,
/**
* 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;
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
*/
/*
* 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) {
*/
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:
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,
return(ret);
/*
- * Cycle on next stylesheet import.
+ * Cycle on next curstylesheet import.
*/
- style = xsltNextImport(style);
+ curstyle = xsltNextImport(curstyle);
}
return(NULL);
}
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,
#define DEBUG_TEMPLATES
+
/************************************************************************
* *
* Module interfaces *
oldInsert = ctxt->insert;
ctxt->insert = insert;
- xsltApplyOneTemplate(ctxt, node, parent->children);
+ xsltApplyOneTemplate(ctxt, node, NULL, parent->children);
ctxt->insert = oldInsert;
#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)
/************************************************************************
* *
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);
}
if (docu == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltNewTransformContext : xsltNewDocument failed\n");
+ xmlFree(cur->templTab);
xmlFree(cur);
return(NULL);
}
return;
if (ctxt->xpathCtxt != NULL)
xmlXPathFreeContext(ctxt->xpathCtxt);
+ if (ctxt->templTab != NULL)
+ xmlFree(ctxt->templTab);
xsltFreeVariableHashes(ctxt);
xsltFreeDocuments(ctxt);
memset(ctxt, -1, sizeof(xsltTransformContext));
}
}
- 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;
}
xmlFree(attributes);
}
- xsltApplyOneTemplate(ctxt, ctxt->node, inst->children);
+ xsltApplyOneTemplate(ctxt, ctxt->node, NULL, inst->children);
error:
if (prop != NULL)
case XML_ELEMENT_NODE:
break;
case XML_CDATA_SECTION_NODE:
- template = xsltGetTemplate(ctxt, node);
+ template = xsltGetTemplate(ctxt, node, NULL);
if (template) {
xmlNodePtr oldNode;
#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
}
return;
case XML_TEXT_NODE:
- template = xsltGetTemplate(ctxt, node);
+ template = xsltGetTemplate(ctxt, node, NULL);
if (template) {
xmlNodePtr oldNode;
#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
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) {
*/
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;
xsltProcessOneNode(ctxt, cur);
break;
case XML_CDATA_SECTION_NODE:
- template = xsltGetTemplate(ctxt, node);
+ template = xsltGetTemplate(ctxt, node, NULL);
if (template) {
xmlNodePtr oldNode;
#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
}
break;
case XML_TEXT_NODE:
- template = xsltGetTemplate(ctxt, cur);
+ template = xsltGetTemplate(ctxt, cur, NULL);
if (template) {
xmlNodePtr oldNode;
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
break;
case XML_PI_NODE:
case XML_COMMENT_NODE:
- template = xsltGetTemplate(ctxt, cur);
+ template = xsltGetTemplate(ctxt, cur, NULL);
if (template) {
xmlNodePtr oldNode;
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;
}
/**
+ * 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.
}
cur = cur->next;
}
- xsltApplyOneTemplate(ctxt, node, template->content);
+ xsltApplyOneTemplate(ctxt, node, template, NULL);
error:
if (has_param == 1)
* 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) {
/*
xsltGenericDebug(xsltGenericDebugContext,
"xsltApplyOneTemplate: insert == NULL !\n");
#endif
+ if (has_variables != 0) {
+ xsltPopStack(ctxt);
+ }
+ if (templ != NULL)
+ templPop(ctxt);
return;
}
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);
"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
if (has_variables != 0) {
xsltPopStack(ctxt);
}
+ if (templ != NULL)
+ templPop(ctxt);
}
/**
"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)
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) {
"xsltIf: test evaluate to %d\n", doit);
#endif
if (doit) {
- xsltApplyOneTemplate(ctxt, node, inst->children);
+ xsltApplyOneTemplate(ctxt, node, NULL, inst->children);
}
error:
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;
xsltTemplatePtr template;
xmlNodePtr oldNode;
- template = xsltGetTemplate(ctxt, node);
+ template = xsltGetTemplate(ctxt, node, NULL);
/*
* If no template is found, apply the default rule.
*/
"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)
#endif
oldNode = ctxt->node;
ctxt->node = node;
- xsltApplyOneTemplate(ctxt, node, template->content);
+ xsltApplyOneTemplate(ctxt, node, template, NULL);
ctxt->node = oldNode;
}
}
xmlDocPtr doc);
void xsltApplyOneTemplate (xsltTransformContextPtr ctxt,
xmlNodePtr node,
+ xsltTemplatePtr templ,
xmlNodePtr list);
#ifdef __cplusplus
}
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;
return;
ret->next = style->templates;
style->templates = ret;
+ ret->style = style;
/*
* Get arguments
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 */
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 */
#include "xsltutils.h"
#include "templates.h"
#include "xsltInternals.h"
+#include "imports.h"
/************************************************************************
const xmlChar *encoding;
xmlNodePtr root;
int base;
+ const xmlChar *method;
if ((buf == NULL) || (result == NULL) || (style == NULL))
return(-1);
/* 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;
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, "<?xml version=");
if (result->version != NULL)
xmlBufferWriteQuotedString(buf->buffer, result->version);
xmlOutputBufferWriteString(buf, " encoding=");
xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding);
}
- switch (style->standalone) {
+ switch (standalone) {
case 0:
xmlOutputBufferWriteString(buf, " standalone=\"no\"");
break;
}
xmlOutputBufferWriteString(buf, "?>\n");
}
- if ((style->doctypePublic != NULL) || (style->doctypeSystem != NULL)) {
+ if ((doctypePublic != NULL) || (doctypeSystem != NULL)) {
xmlNodePtr cur = result->children;
while (cur != NULL) {
if ((cur != NULL) && (cur->name != NULL)) {
xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
xmlOutputBufferWriteString(buf, cur->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");
}
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;
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")))
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")))
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")))
@(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";\
--- /dev/null
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+<xsl:import href="diffspec.xsl"/>
+
+<xsl:template match="loc[@role='erratumref']">
+ <xsl:choose>
+ <xsl:when test="$show.diff.markup='0'">
+ <!-- nop -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-imports/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="loc[@role='erratumref']" mode="text">
+ <xsl:choose>
+ <xsl:when test="$show.diff.markup='0'">
+ <!-- nop -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-imports/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+</xsl:stylesheet>
+
--- /dev/null
+<?xml version="1.0"?>
+
+<!-- Version: $Id$ -->
+
+<!-- Stylesheet for @diff markup in XMLspec -->
+<!-- Author: Norman Walsh (Norman.Walsh@East.Sun.COM) -->
+<!-- Date Created: 2000.07.21 -->
+
+<!-- This stylesheet is copyright (c) 2000 by its authors. Free
+ distribution and modification is permitted, including adding to
+ the list of authors and copyright holders, as long as this
+ copyright notice is maintained. -->
+
+<!-- This stylesheet attempts to implement the XML Specification V2.1
+ DTD. Documents conforming to earlier DTDs may not be correctly
+ transformed.
+
+ This stylesheet supports the use of change-markup with the @diff
+ attribute. If you use @diff, you should always use this stylesheet.
+ If you want to turn off the highlighting of differences, use this
+ stylesheet, but set show.diff.markup to 0.
+
+ Using the original xmlspec stylesheet with @diff markup will cause
+ @diff=del text to be presented.
+-->
+
+<!-- ChangeLog:
+ 25 Sep 2000: (Norman.Walsh@East.Sun.COM)
+ - Use inline diff markup (as opposed to block) for name and
+ affiliation
+ - Handle @diff='del' correctly in bibl and other list-contexts.
+ 14 Aug 2000: (Norman.Walsh@East.Sun.COM)
+ - Support additional.title param
+ 27 Jul 2000: (Norman.Walsh@East.Sun.COM)
+ - Fix HTML markup problem with diff'd authors in authlist
+ 26 Jul 2000: (Norman.Walsh@East.Sun.COM)
+ - Update pointer to latest xmlspec-stylesheet.
+ 21 Jul 2000: (Norman.Walsh@East.Sun.COM)
+ - Initial version
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+<xsl:import href="xmlspec.xsl"/>
+
+<xsl:param name="show.diff.markup">1</xsl:param>
+
+<xsl:param name="additional.css">
+<xsl:if test="$show.diff.markup = '1'">
+<xsl:text>
+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 { }
+</xsl:text>
+</xsl:if>
+</xsl:param>
+
+<xsl:param name="additional.title">
+ <xsl:if test="$show.diff.markup != '0'">
+ <xsl:text>Review Version</xsl:text>
+ </xsl:if>
+</xsl:param>
+
+<xsl:param name="called.by.diffspec">1</xsl:param>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="diff-markup">
+ <xsl:param name="diff">off</xsl:param>
+ <xsl:choose>
+ <xsl:when test="ancestor::scrap">
+ <!-- forget it, we can't add stuff inside tables -->
+ <!-- handled in base stylesheet -->
+ <xsl:apply-imports/>
+ </xsl:when>
+ <xsl:when test="self::gitem or self::bibl">
+ <!-- forget it, we can't add stuff inside dls; handled below -->
+ <xsl:apply-imports/>
+ </xsl:when>
+ <xsl:when test="ancestor-or-self::phrase">
+ <span class="diff-{$diff}">
+ <xsl:apply-imports/>
+ </span>
+ </xsl:when>
+ <xsl:when test="ancestor::p and not(self::p)">
+ <span class="diff-{$diff}">
+ <xsl:apply-imports/>
+ </span>
+ </xsl:when>
+ <xsl:when test="ancestor-or-self::affiliation">
+ <span class="diff-{$diff}">
+ <xsl:apply-imports/>
+ </span>
+ </xsl:when>
+ <xsl:when test="ancestor-or-self::name">
+ <span class="diff-{$diff}">
+ <xsl:apply-imports/>
+ </span>
+ </xsl:when>
+ <xsl:otherwise>
+ <div class="diff-{$diff}">
+ <xsl:apply-imports/>
+ </div>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="*[@diff='chg']">
+ <xsl:choose>
+ <xsl:when test="$show.diff.markup='1'">
+ <xsl:call-template name="diff-markup">
+ <xsl:with-param name="diff">chg</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-imports/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="*[@diff='add']">
+ <xsl:choose>
+ <xsl:when test="$show.diff.markup='1'">
+ <xsl:call-template name="diff-markup">
+ <xsl:with-param name="diff">add</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-imports/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="*[@diff='del']">
+ <xsl:choose>
+ <xsl:when test="$show.diff.markup='1'">
+ <xsl:call-template name="diff-markup">
+ <xsl:with-param name="diff">del</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- suppress deleted markup -->
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="*[@diff='off']">
+ <xsl:choose>
+ <xsl:when test="$show.diff.markup='1'">
+ <xsl:call-template name="diff-markup">
+ <xsl:with-param name="diff">off</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-imports/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- ================================================================= -->
+
+ <xsl:template match="bibl[@diff]" priority="1">
+ <xsl:variable name="dt">
+ <xsl:if test="@id">
+ <a name="{@id}"/>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="@key">
+ <xsl:value-of select="@key"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@id"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="dd">
+ <xsl:apply-templates/>
+ <xsl:if test="@href">
+ <xsl:text> (See </xsl:text>
+ <a href="{@href}">
+ <xsl:value-of select="@href"/>
+ </a>
+ <xsl:text>.)</xsl:text>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="@diff and $show.diff.markup = '1'">
+ <dt class="label">
+ <span class="diff-{@diff}">
+ <xsl:copy-of select="$dt"/>
+ </span>
+ </dt>
+ <dd>
+ <div class="diff-{@diff}">
+ <xsl:copy-of select="$dd"/>
+ </div>
+ </dd>
+ </xsl:when>
+ <xsl:when test="@diff='del' and $show.diff.markup='0'">
+ <!-- suppressed -->
+ </xsl:when>
+ <xsl:otherwise>
+ <dt class="label">
+ <xsl:copy-of select="$dt"/>
+ </dt>
+ <dd>
+ <xsl:copy-of select="$dd"/>
+ </dd>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="gitem/label">
+ <xsl:variable name="diffval" select="ancestor-or-self::*/@diff"/>
+ <xsl:choose>
+ <xsl:when test="$diffval != '' and $show.diff.markup='1'">
+ <dt class="label">
+ <span class="diff-{ancestor-or-self::*/@diff}">
+ <xsl:apply-templates/>
+ </span>
+ </dt>
+ </xsl:when>
+ <xsl:when test="$diffval='del' and $show.diff.markup='0'">
+ <!-- suppressed -->
+ </xsl:when>
+ <xsl:otherwise>
+ <dt class="label">
+ <xsl:apply-templates/>
+ </dt>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="gitem/def">
+ <xsl:variable name="diffval" select="ancestor-or-self::*/@diff"/>
+ <xsl:choose>
+ <xsl:when test="$diffval != '' and $show.diff.markup='1'">
+ <dd>
+ <div class="diff-{ancestor-or-self::*/@diff}">
+ <xsl:apply-templates/>
+ </div>
+ </dd>
+ </xsl:when>
+ <xsl:when test="$diffval='del' and $show.diff.markup='0'">
+ <!-- suppressed -->
+ </xsl:when>
+ <xsl:otherwise>
+ <dd>
+ <xsl:apply-templates/>
+ </dd>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- authlist: list of authors (editors, really) -->
+ <!-- called in enforced order from header's template, in <dl>
+ context -->
+ <xsl:template match="authlist[@diff]">
+ <xsl:choose>
+ <xsl:when test="$show.diff.markup='1'">
+ <dt>
+ <span class="diff-{ancestor-or-self::*/@diff}">
+ <xsl:text>Editor</xsl:text>
+ <xsl:if test="count(author) > 1">
+ <xsl:text>s</xsl:text>
+ </xsl:if>
+ <xsl:text>:</xsl:text>
+ </span>
+ </dt>
+ </xsl:when>
+ <xsl:when test="@diff='del' and $show.diff.markup='0'">
+ <!-- suppressed -->
+ </xsl:when>
+ <xsl:otherwise>
+ <dt>
+ <xsl:text>Editor</xsl:text>
+ <xsl:if test="count(author) > 1">
+ <xsl:text>s</xsl:text>
+ </xsl:if>
+ <xsl:text>:</xsl:text>
+ </dt>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <!-- author: an editor of a spec -->
+ <!-- only appears in authlist -->
+ <!-- called in <dl> context -->
+ <xsl:template match="author[@diff]" priority="1">
+ <xsl:choose>
+ <xsl:when test="@diff and $show.diff.markup='1'">
+ <dd>
+ <span class="diff-{ancestor-or-self::*/@diff}">
+ <xsl:apply-templates/>
+ <xsl:if test="@role = '2e'">
+ <xsl:text> - Second Edition</xsl:text>
+ </xsl:if>
+ </span>
+ </dd>
+ </xsl:when>
+ <xsl:when test="@diff='del' and $show.diff.markup='0'">
+ <!-- suppressed -->
+ </xsl:when>
+ <xsl:otherwise>
+ <dd>
+ <xsl:apply-templates/>
+ <xsl:if test="@role = '2e'">
+ <xsl:text> - Second Edition</xsl:text>
+ </xsl:if>
+ </dd>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>