+Tue Feb 27 16:15:47 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+ * libxslt/xslt.c: extension prefix support for the full stylesheet
+ * libxslt/transform.c libxslt/extensions.[ch]: more work should
+ start working
+
Mon Feb 26 22:59:44 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* doc/xslt.html : cleaned up, added a bit more description on
</head>
<body bgcolor="#ffffff">
-<p><a href="http://www.gnome.org/"><img src="../smallfootonly.gif"
-alt="Gnome Logo"></a></p>
+<p><a href="http://www.gnome.org/"><img src="smallfootonly.gif"
+alt="Gnome Logo"></a><a href="http://www.redhat.com"><img src="redhat.gif"
+alt="Red Hat Logo"></a></p>
<h1 align="center">The XSLT C library for Gnome</h1>
}
/*
- * xsltInitCtxtExts:
+ * xsltFreeCtxtExts:
* @ctxt: an XSLT transformation context
*
- * Initialize the XSLT extension support
+ * Free the XSLT extension data
*/
void
-xsltInitCtxtExts(xsltTransformContextPtr ctxt) {
+xsltFreeCtxtExts(xsltTransformContextPtr ctxt) {
if (ctxt->extElements == NULL)
xmlHashFree(ctxt->extElements, NULL);
if (ctxt->extFunctions == NULL)
xmlHashFree(ctxt->extFunctions, NULL);
}
+/*
+ * xsltCheckExtPrefix:
+ * @style: the stylesheet
+ * @prefix: the namespace prefix (possibly NULL)
+ *
+ * Check if the given prefix is one of the declared extensions
+ *
+ * Returns 1 if this is an extension, 0 otherwise
+ */
+int
+xsltCheckExtPrefix(xsltStylesheetPtr style, const xmlChar *prefix) {
+ xsltExtDefPtr cur;
+
+ if ((style == NULL) || (style->nsDefs == NULL))
+ return(0);
+
+ cur = (xsltExtDefPtr) style->nsDefs;
+ while (cur != NULL) {
+ if (xmlStrEqual(prefix, cur->prefix))
+ return(1);
+ cur = cur->next;
+ }
+ return(0);
+}
+
int xsltRegisterExtPrefix (xsltStylesheetPtr style,
const xmlChar *prefix,
const xmlChar *URI);
+int xsltCheckExtPrefix (xsltStylesheetPtr style,
+ const xmlChar *prefix);
int xsltRegisterExtFunction (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *URI,
const xmlChar *name,
const xmlChar *URI,
xsltTransformFunction function);
-void xsltInitCtxtExts (xsltTransformContextPtr ctxt);
+void xsltFreeCtxtExts (xsltTransformContextPtr ctxt);
void xsltFreeExts (xsltStylesheetPtr style);
#ifdef __cplusplus
#include "imports.h"
#include "keys.h"
#include "documents.h"
+#include "extensions.h"
#define DEBUG_PROCESS
if (ctxt->varsTab != NULL)
xmlFree(ctxt->varsTab);
xsltFreeDocuments(ctxt);
+ xsltFreeCtxtExts(ctxt);
memset(ctxt, -1, sizeof(xsltTransformContext));
xmlFree(ctxt);
}
} else if ((cur->type == XML_ELEMENT_NODE) &&
(xmlStrEqual(cur->name, (const xmlChar *)"xsltdebug"))) {
xsltDebug(ctxt, cur);
+ } else if ((cur->type == XML_ELEMENT_NODE) &&
+ (cur->ns != NULL) && (cur->_private != NULL)) {
+ xsltTransformFunction function;
+
+ /*
+ * Flagged as an extension element
+ */
+ function = (xsltTransformFunction)
+ xmlHashLookup2(ctxt->extElements, cur->name, cur->ns->href);
+ if (function == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltApplyOneTemplate: failed to find extension %s\n",
+ cur->name);
+ } else {
+#ifdef DEBUG_PROCESS
+ xsltGenericDebug(xsltGenericDebugContext,
+ "xsltApplyOneTemplate: extension construct %s\n", cur->name);
+#endif
+ ctxt->insert = insert;
+ function(ctxt, node, cur);
+ ctxt->insert = oldInsert;
+ }
+ goto skip_children;
} else if (cur->type == XML_ELEMENT_NODE) {
#ifdef DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext,
#include "imports.h"
#include "keys.h"
#include "documents.h"
+#include "extensions.h"
#define DEBUG_PARSING
/* #define DEBUG_BLANKS */
return;
xsltFreeKeys(sheet);
+ xsltFreeExts(sheet);
xsltFreeTemplateHashes(sheet);
xsltFreeDecimalFormatList(sheet);
xsltFreeTemplateList(sheet->templates);
}
/**
+ * xsltParseStylesheetExtPrefix:
+ * @style: the XSLT stylesheet
+ * @template: the "strip-space" prefix
+ *
+ * parse an XSLT stylesheet strip-space prefix and record
+ * prefixes needing stripping
+ */
+
+void
+xsltParseStylesheetExtPrefix(xsltStylesheetPtr style, xmlNodePtr cur) {
+ xmlChar *prefixes;
+ xmlChar *prefix, *end;
+
+ if ((cur == NULL) || (style == NULL))
+ return;
+
+ prefixes = xmlGetNsProp(cur, (const xmlChar *)"extension-element-prefixes",
+ XSLT_NAMESPACE);
+ if (prefixes == NULL) {
+ return;
+ }
+
+ prefix = prefixes;
+ while (*prefix != 0) {
+ while (IS_BLANK(*prefix)) prefix++;
+ if (*prefix == 0)
+ break;
+ end = prefix;
+ while ((*end != 0) && (!IS_BLANK(*end))) end++;
+ prefix = xmlStrndup(prefix, end - prefix);
+ if (prefix) {
+ xmlNsPtr ns;
+
+ if (xmlStrEqual(prefix, (const xmlChar *)"#default"))
+ ns = xmlSearchNs(style->doc, cur, NULL);
+ else
+ ns = xmlSearchNs(style->doc, cur, prefix);
+ if (ns == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:extension-element-prefix : undefined namespace %s\n",
+ prefix);
+ } else {
+#ifdef DEBUG_PARSING
+ xsltGenericDebug(xsltGenericDebugContext,
+ "add extension prefix %s\n", prefix);
+#endif
+ xsltRegisterExtPrefix(style, prefix, ns->href);
+ }
+ xmlFree(prefix);
+ }
+ prefix = end;
+ }
+ xmlFree(prefixes);
+}
+
+/**
* xsltParseStylesheetStripSpace:
* @style: the XSLT stylesheet
* @template: the "strip-space" element
delete = cur;
goto skip_children;
}
+ } else if ((cur->ns != NULL) && (style->nsDefs != NULL)) {
+ if (xsltCheckExtPrefix(style, cur->ns->prefix)) {
+ /*
+ * Mark the element as being 'special'
+ */
+ cur->_private = (void *) style;
+ }
}
/*
xmlFree(prop);
}
+ xsltParseStylesheetExtPrefix(style, top);
+
cur = top->children;
while (cur != NULL) {