More work on the extension support:
authorDaniel Veillard <veillard@src.gnome.org>
Tue, 27 Feb 2001 13:18:39 +0000 (13:18 +0000)
committerDaniel Veillard <veillard@src.gnome.org>
Tue, 27 Feb 2001 13:18:39 +0000 (13:18 +0000)
- libxslt/xslt.c: extension prefix support for the full stylesheet
- libxslt/transform.c libxslt/extensions.[ch]: more work should
  start working
Daniel

ChangeLog
doc/xslt.html
libxslt/extensions.c
libxslt/extensions.h
libxslt/transform.c
libxslt/xslt.c

index f878814..f1fe4dd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+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
index 50a9fdd..6ecd287 100644 (file)
@@ -8,8 +8,9 @@
 </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>
 
index 787c529..8df568e 100644 (file)
@@ -199,16 +199,41 @@ xsltRegisterExtElement(xsltTransformContextPtr ctxt, const xmlChar *name,
 }
 
 /*
- * 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);
+}
+
index 5522d53..6568584 100644 (file)
@@ -19,6 +19,8 @@ extern "C" {
 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,
@@ -27,7 +29,7 @@ int           xsltRegisterExtElement  (xsltTransformContextPtr ctxt,
                                         const xmlChar *name,
                                         const xmlChar *URI,
                                         xsltTransformFunction function);
-void           xsltInitCtxtExts        (xsltTransformContextPtr ctxt);
+void           xsltFreeCtxtExts        (xsltTransformContextPtr ctxt);
 void           xsltFreeExts            (xsltStylesheetPtr style);
 
 #ifdef __cplusplus
index 1884cbf..2e98472 100644 (file)
@@ -38,6 +38,7 @@
 #include "imports.h"
 #include "keys.h"
 #include "documents.h"
+#include "extensions.h"
 
 #define DEBUG_PROCESS
 
@@ -199,6 +200,7 @@ xsltFreeTransformContext(xsltTransformContextPtr ctxt) {
     if (ctxt->varsTab != NULL)
        xmlFree(ctxt->varsTab);
     xsltFreeDocuments(ctxt);
+    xsltFreeCtxtExts(ctxt);
     memset(ctxt, -1, sizeof(xsltTransformContext));
     xmlFree(ctxt);
 }
@@ -1883,6 +1885,29 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
        } 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,
index d09ac0e..5fd14a9 100644 (file)
@@ -31,6 +31,7 @@
 #include "imports.h"
 #include "keys.h"
 #include "documents.h"
+#include "extensions.h"
 
 #define DEBUG_PARSING
 /* #define DEBUG_BLANKS */
@@ -283,6 +284,7 @@ xsltFreeStylesheet(xsltStylesheetPtr sheet) {
        return;
 
     xsltFreeKeys(sheet);
+    xsltFreeExts(sheet);
     xsltFreeTemplateHashes(sheet);
     xsltFreeDecimalFormatList(sheet);
     xsltFreeTemplateList(sheet->templates);
@@ -629,6 +631,62 @@ xsltParseStylesheetPreserveSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
 }
 
 /**
+ * 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
@@ -912,6 +970,13 @@ xsltParseTemplateContent(xsltStylesheetPtr style, xsltTemplatePtr ret,
                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;
+           }
        }
 
        /*
@@ -1232,6 +1297,8 @@ xsltParseStylesheetTop(xsltStylesheetPtr style, xmlNodePtr top) {
        xmlFree(prop);
     }
 
+    xsltParseStylesheetExtPrefix(style, top);
+
     cur = top->children;
 
     while (cur != NULL) {