added xsltGetQNameURI() and cleaned up the way URI for QNames were
authorDaniel Veillard <veillard@src.gnome.org>
Fri, 29 Jun 2001 21:36:22 +0000 (21:36 +0000)
committerDaniel Veillard <veillard@src.gnome.org>
Fri, 29 Jun 2001 21:36:22 +0000 (21:36 +0000)
* libxslt/pattern.c libxslt/preproc.c libxslt/transform.c
  libxslt/xslt.c libxslt/xsltutils.[ch]: added xsltGetQNameURI()
  and cleaned up the way URI for QNames were computed through
  the code, serious cleanup.
* libxslt/xsltInternals.h libxslt/xslt.c: moved cdata-sections
  in their own hash table, implementation not yet finished.
Daniel

ChangeLog
libxslt/pattern.c
libxslt/preproc.c
libxslt/transform.c
libxslt/xslt.c
libxslt/xsltInternals.h
libxslt/xsltutils.c
libxslt/xsltutils.h

index aa1fded..7847d2a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Fri Jun 29 23:32:37 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+       * libxslt/pattern.c libxslt/preproc.c libxslt/transform.c
+         libxslt/xslt.c libxslt/xsltutils.[ch]: added xsltGetQNameURI()
+         and cleaned up the way URI for QNames were computed through
+         the code, serious cleanup.
+       * libxslt/xsltInternals.h libxslt/xslt.c: moved cdata-sections
+         in their own hash table, implementation not yet finished.
+
 Thu Jun 28 23:01:14 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
        * libxslt/keys.c libxslt/templates.c libxslt/transform.c
index e61fe7e..489da70 100644 (file)
@@ -234,7 +234,7 @@ xsltFreeParserContext(xsltParserContextPtr ctxt) {
  */
 static int
 xsltCompMatchAdd(xsltCompMatchPtr comp, xsltOp op, xmlChar *value,
-                  xmlChar *value2) {
+                xmlChar *value2) {
     if (comp->nbStep >= 20) {
         xsltGenericError(xsltGenericErrorContext,
                "xsltCompMatchAddOp: overflow\n");
@@ -1126,13 +1126,14 @@ error:
 static void
 xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token) {
     xmlChar *name = NULL;
-    xmlChar *prefix = NULL;
-    xmlChar *ncname = NULL;
+    const xmlChar *URI = NULL;
     xmlChar *URL = NULL;
     int level;
 
     SKIP_BLANKS;
     if ((token == NULL) && (CUR == '@')) {
+       xmlChar *prefix = NULL;
+
        NEXT;
        if (CUR == '*') {
            NEXT;
@@ -1205,23 +1206,14 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token) {
                ctxt->error = 1;
                goto error;
            }
-           ncname = xmlSplitQName2(name, &prefix);
-           if (ncname != NULL) {
-               if (prefix != NULL) {
-                   xmlNsPtr ns;
-
-                   ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix);
-                   if (ns == NULL) {
-                       xsltGenericError(xsltGenericErrorContext,
-                           "xsl: pattern, no namespace bound to prefix %s\n",
-                                        prefix);
-                   } else {
-                       URL = xmlStrdup(ns->href);
-                   }
-                   xmlFree(prefix);
-               }
-               xmlFree(name);
-               name = ncname;
+           URI = xsltGetQNameURI(ctxt->elem, &token);
+           if (token == NULL) {
+               ctxt->error = 1;
+               goto error;
+           } else {
+               name = xmlStrdup(token);
+               if (URI != NULL)
+                   URL = xmlStrdup(URI);
            }
            PUSH(XSLT_OP_CHILD, name, URL);
        } else if (xmlStrEqual(token, (const xmlChar *) "attribute")) {
@@ -1232,23 +1224,14 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token) {
                ctxt->error = 1;
                goto error;
            }
-           ncname = xmlSplitQName2(name, &prefix);
-           if (ncname != NULL) {
-               if (prefix != NULL) {
-                   xmlNsPtr ns;
-
-                   ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix);
-                   if (ns == NULL) {
-                       xsltGenericError(xsltGenericErrorContext,
-                           "xsl: pattern, no namespace bound to prefix %s\n",
-                                        prefix);
-                   } else {
-                       URL = xmlStrdup(ns->href);
-                   }
-                   xmlFree(prefix);
-               }
-               xmlFree(name);
-               name = ncname;
+           URI = xsltGetQNameURI(ctxt->elem, &token);
+           if (token == NULL) {
+               ctxt->error = 1;
+               goto error;
+           } else {
+               name = xmlStrdup(token);
+               if (URI != NULL)
+                   URL = xmlStrdup(URI);
            }
            PUSH(XSLT_OP_ATTR, name, URL);
        } else {
@@ -1262,24 +1245,13 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token) {
        NEXT;
        PUSH(XSLT_OP_ALL, token, NULL);
     } else {
-       ncname = xmlSplitQName2(token, &prefix);
-       if (ncname != NULL) {
-           if (prefix != NULL) {
-               xmlNsPtr ns;
-
-               ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix);
-               if (ns == NULL) {
-                   xsltGenericError(xsltGenericErrorContext,
-                       "xsl: pattern, no namespace bound to prefix %s\n",
-                                    prefix);
-               } else {
-                   URL = xmlStrdup(ns->href);
-               }
-               xmlFree(prefix);
-           }
-           xmlFree(token);
-           token = ncname;
+       URI = xsltGetQNameURI(ctxt->elem, &token);
+       if (token == NULL) {
+           ctxt->error = 1;
+           goto error;
        }
+       if (URI != NULL)
+           URL = xmlStrdup(URI);
        PUSH(XSLT_OP_ELEM, token, URL);
     }
 parse_predicate:
index 9168a41..9da6d95 100644 (file)
@@ -625,9 +625,6 @@ static void
 xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
     xsltStylePreCompPtr comp;
     xmlChar *prop;
-    xmlChar *ncname = NULL;
-    xmlChar *prefix = NULL;
-    xmlNsPtr ns = NULL;
 
     if ((style == NULL) || (inst == NULL))
        return;
@@ -646,28 +643,21 @@ xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
             "xslt:with-param : name is missing\n");
        style->errors++;
     } else {
+        const xmlChar *URI;
 
-       ncname = xmlSplitQName2(prop, &prefix);
-       if (ncname == NULL) {
-           ncname = prop;
-           prop = NULL;
-           prefix = NULL;
-       }
-       if (prefix != NULL) {
-           ns = xmlSearchNs(inst->doc, inst, prefix);
-           if (ns == NULL) {
-               xsltGenericError(xsltGenericErrorContext,
-               "xslt:with-param : no namespace bound to prefix %s\n", prefix);
-               style->warnings++;
+       URI = xsltGetQNameURI(inst, &prop);
+       if (prop == NULL) {
+           style->errors++;
+       } else {
+           comp->name = prop;
+           comp->has_name = 1;
+           if (URI != NULL) {
+               comp->ns = xmlStrdup(URI);
+               comp->has_ns = 1;
+           } else {
+               comp->has_ns = 0;
            }
        }
-       comp->name = xmlStrdup(ncname);
-       comp->has_name = 1;
-       if (ns != NULL) {
-           comp->has_ns = 1;
-           comp->ns = xmlStrdup(ns->href);
-       } else
-           comp->has_ns = 0;
     }
 
     comp->select = xsltGetNsProp(inst, (const xmlChar *)"select",
@@ -685,13 +675,6 @@ xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
            "xsl:param : content should be empty since select is present \n");
        style->warnings++;
     }
-
-    if (prop != NULL)
-        xmlFree(prop);
-    if (ncname != NULL)
-        xmlFree(ncname);
-    if (prefix != NULL)
-        xmlFree(prefix);
 }
 
 /**
@@ -828,9 +811,6 @@ static void
 xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) {
     xsltStylePreCompPtr comp;
     xmlChar *prop;
-    xmlChar *ncname = NULL;
-    xmlChar *prefix = NULL;
-    xmlNsPtr ns = NULL;
 
     if ((style == NULL) || (inst == NULL))
        return;
@@ -849,37 +829,23 @@ xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) {
             "xslt:call-template : name is missing\n");
        style->errors++;
     } else {
+        const xmlChar *URI;
 
-       ncname = xmlSplitQName2(prop, &prefix);
-       if (ncname == NULL) {
-           ncname = prop;
-           prop = NULL;
-           prefix = NULL;
-       }
-       if (prefix != NULL) {
-           ns = xmlSearchNs(inst->doc, inst, prefix);
-           if (ns == NULL) {
-               xsltGenericError(xsltGenericErrorContext,
-       "xslt:call-template : no namespace bound to prefix %s\n", prefix);
-               style->warnings++;
+       URI = xsltGetQNameURI(inst, &prop);
+       if (prop == NULL) {
+           style->errors++;
+       } else {
+           comp->name = prop;
+           comp->has_name = 1;
+           if (URI != NULL) {
+               comp->ns = xmlStrdup(URI);
+               comp->has_ns = 1;
+           } else {
+               comp->has_ns = 0;
            }
        }
-       comp->name = xmlStrdup(ncname);
-       comp->has_name = 1;
-       if (ns != NULL) {
-           comp->ns = xmlStrdup(ns->href);
-           comp->has_ns = 1;
-       } else
-           comp->has_ns = 0;
        comp->templ = NULL;
     }
-
-    if (prop != NULL)
-        xmlFree(prop);
-    if (ncname != NULL)
-        xmlFree(ncname);
-    if (prefix != NULL)
-        xmlFree(prefix);
 }
 
 /**
@@ -907,34 +873,18 @@ xsltApplyTemplatesComp(xsltStylesheetPtr style, xmlNodePtr inst) {
      */
     prop = xsltGetNsProp(inst, (const xmlChar *)"mode", XSLT_NAMESPACE);
     if (prop != NULL) {
-       xmlChar *prefix = NULL;
-
-       comp->mode = xmlSplitQName2(prop, &prefix);
-       if (comp->mode != NULL) {
-           if (prefix != NULL) {
-               xmlNsPtr ns;
-
-               ns = xmlSearchNs(inst->doc, inst, prefix);
-               if (ns == NULL) {
-                   xsltGenericError(xsltGenericErrorContext,
-                       "no namespace bound to prefix %s\n", prefix);
-                   style->warnings++;
-                   xmlFree(prefix);
-                   xmlFree(comp->mode);
-                   comp->mode = prop;
-                   comp->modeURI = NULL;
-               } else {
-                   comp->modeURI = xmlStrdup(ns->href);
-                   xmlFree(prefix);
-                   xmlFree(prop);
-               }
+        const xmlChar *URI;
+
+       URI = xsltGetQNameURI(inst, &prop);
+       if (prop == NULL) {
+           style->errors++;
+       } else {
+           comp->mode = prop;
+           if (URI != NULL) {
+               comp->modeURI = xmlStrdup(URI);
            } else {
-               xmlFree(prop);
                comp->modeURI = NULL;
            }
-       } else {
-           comp->mode = prop;
-           comp->modeURI = NULL;
        }
     }
     comp->select = xsltGetNsProp(inst, (const xmlChar *)"select",
@@ -1090,9 +1040,6 @@ static void
 xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) {
     xsltStylePreCompPtr comp;
     xmlChar *prop;
-    xmlChar *ncname = NULL;
-    xmlChar *prefix = NULL;
-    xmlNsPtr ns = NULL;
 
     if ((style == NULL) || (inst == NULL))
        return;
@@ -1111,27 +1058,21 @@ xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) {
             "xslt:variable : name is missing\n");
        style->errors++;
     } else {
-       ncname = xmlSplitQName2(prop, &prefix);
-       if (ncname == NULL) {
-           ncname = prop;
-           prop = NULL;
-           prefix = NULL;
-       }
-       if (prefix != NULL) {
-           ns = xmlSearchNs(inst->doc, inst, prefix);
-           if (ns == NULL) {
-               xsltGenericError(xsltGenericErrorContext,
-               "xsl:variable no namespace bound to prefix %s\n", prefix);
-               style->warnings++;
+        const xmlChar *URI;
+
+       URI = xsltGetQNameURI(inst, &prop);
+       if (prop == NULL) {
+           style->errors++;
+       } else {
+           comp->name = prop;
+           comp->has_name = 1;
+           if (URI != NULL) {
+               comp->ns = xmlStrdup(URI);
+               comp->has_ns = 1;
+           } else {
+               comp->has_ns = 0;
            }
        }
-       comp->name = xmlStrdup(ncname);
-       comp->has_name = 1;
-       if (ns != NULL) {
-           comp->ns = xmlStrdup(ns->href);
-           comp->has_ns = 1;
-       } else
-           comp->has_ns = 0;
     }
 
     comp->select = xsltGetNsProp(inst, (const xmlChar *)"select",
@@ -1149,13 +1090,6 @@ xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) {
        "xsl:variable : content should be empty since select is present \n");
        style->warnings++;
     }
-
-    if (prop != NULL)
-        xmlFree(prop);
-    if (ncname != NULL)
-        xmlFree(ncname);
-    if (prefix != NULL)
-        xmlFree(prefix);
 }
 
 /**
@@ -1169,9 +1103,6 @@ static void
 xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
     xsltStylePreCompPtr comp;
     xmlChar *prop;
-    xmlChar *ncname = NULL;
-    xmlChar *prefix = NULL;
-    xmlNsPtr ns = NULL;
 
     if ((style == NULL) || (inst == NULL))
        return;
@@ -1190,27 +1121,21 @@ xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
             "xslt:param : name is missing\n");
        style->errors++;
     } else {
-       ncname = xmlSplitQName2(prop, &prefix);
-       if (ncname == NULL) {
-           ncname = prop;
-           prop = NULL;
-           prefix = NULL;
-       }
-       if (prefix != NULL) {
-           ns = xmlSearchNs(inst->doc, inst, prefix);
-           if (ns == NULL) {
-               xsltGenericError(xsltGenericErrorContext,
-                   "xsl:param no namespace bound to prefix %s\n", prefix);
-               style->warnings++;
+        const xmlChar *URI;
+
+       URI = xsltGetQNameURI(inst, &prop);
+       if (prop == NULL) {
+           style->errors++;
+       } else {
+           comp->name = prop;
+           comp->has_name = 1;
+           if (URI != NULL) {
+               comp->ns = xmlStrdup(URI);
+               comp->has_ns = 1;
+           } else {
+               comp->has_ns = 0;
            }
        }
-       comp->name = xmlStrdup(ncname);
-       comp->has_name = 1;
-       if (ns != NULL) {
-           comp->ns = xmlStrdup(ns->href);
-           comp->has_ns = 1;
-       } else
-           comp->has_ns = 0;
     }
 
     comp->select = xsltGetNsProp(inst, (const xmlChar *)"select",
@@ -1228,13 +1153,6 @@ xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
        "xsl:param : content should be empty since select is present \n");
        style->warnings++;
     }
-
-    if (prop != NULL)
-        xmlFree(prop);
-    if (ncname != NULL)
-        xmlFree(ncname);
-    if (prefix != NULL)
-        xmlFree(prefix);
 }
 
 
index ddf4d93..81cc891 100644 (file)
@@ -1193,52 +1193,32 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
                                          (const xmlChar *) "method",
                                          XSLT_NAMESPACE);
         if (prop != NULL) {
-            xmlChar *ncname;
-            xmlChar *prefix = NULL;
-
-            if (style->method != NULL)
-                xmlFree(style->method);
-            style->method = NULL;
-            if (style->methodURI != NULL)
-                xmlFree(style->methodURI);
-            style->methodURI = NULL;
-
-            ncname = xmlSplitQName2(prop, &prefix);
-            if (ncname != NULL) {
-                if (prefix != NULL) {
-                    xmlNsPtr ns;
-
-                    ns = xmlSearchNs(inst->doc, inst, prefix);
-                    if (ns == NULL) {
-                        xsltGenericError(xsltGenericErrorContext,
-                                         "no namespace bound to prefix %s\n",
-                                         prefix);
-                        style->warnings++;
-                        xmlFree(prefix);
-                        xmlFree(ncname);
-                        style->method = prop;
-                    } else {
-                        style->methodURI = xmlStrdup(ns->href);
-                        style->method = ncname;
-                        xmlFree(prefix);
-                        xmlFree(prop);
-                    }
-                } else {
-                    style->method = ncname;
-                    xmlFree(prop);
-                }
-            } else {
-                if ((xmlStrEqual(prop, (const xmlChar *) "xml")) ||
-                    (xmlStrEqual(prop, (const xmlChar *) "html")) ||
-                    (xmlStrEqual(prop, (const xmlChar *) "text"))) {
-                    style->method = prop;
-                } else {
-                    xsltGenericError(xsltGenericErrorContext,
-                                     "invalid value for method: %s\n",
-                                     prop);
-                    style->warnings++;
-                }
-            }
+           const xmlChar *URI;
+
+           if (style->method != NULL)
+               xmlFree(style->method);
+           style->method = NULL;
+           if (style->methodURI != NULL)
+               xmlFree(style->methodURI);
+           style->methodURI = NULL;
+
+           URI = xsltGetQNameURI(inst, &prop);
+           if (prop == NULL) {
+               style->errors++;
+           } else if (URI == NULL) {
+               if ((xmlStrEqual(prop, (const xmlChar *) "xml")) ||
+                   (xmlStrEqual(prop, (const xmlChar *) "html")) ||
+                   (xmlStrEqual(prop, (const xmlChar *) "text"))) {
+                   style->method = prop;
+               } else {
+                   xsltGenericError(xsltGenericErrorContext,
+                                    "invalid value for method: %s\n", prop);
+                   style->warnings++;
+               }
+           } else {
+               style->method = prop;
+               style->methodURI = xmlStrdup(URI);
+           }
         }
         prop = xsltEvalAttrValueTemplate(ctxt, inst,
                                          (const xmlChar *)
index 61bac09..35aa9d9 100644 (file)
@@ -316,6 +316,8 @@ xsltFreeStylesheet(xsltStylesheetPtr sheet)
         xmlFreeDoc(sheet->doc);
     if (sheet->variables != NULL)
         xsltFreeStackElemList(sheet->variables);
+    if (sheet->cdataSection != NULL)
+        xmlHashFree(sheet->cdataSection, NULL);
     if (sheet->stripSpaces != NULL)
         xmlHashFree(sheet->stripSpaces, NULL);
     if (sheet->nsHash != NULL)
@@ -387,8 +389,7 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
     /* relaxed to support xt:document */
     prop = xmlGetProp(cur, (const xmlChar *) "method");
     if (prop != NULL) {
-        xmlChar *ncname;
-        xmlChar *prefix = NULL;
+        const xmlChar *URI;
 
         if (style->method != NULL)
             xmlFree(style->method);
@@ -397,31 +398,10 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
             xmlFree(style->methodURI);
         style->methodURI = NULL;
 
-        ncname = xmlSplitQName2(prop, &prefix);
-        if (ncname != NULL) {
-            if (prefix != NULL) {
-                xmlNsPtr ns;
-
-                ns = xmlSearchNs(cur->doc, cur, prefix);
-                if (ns == NULL) {
-                    xsltGenericError(xsltGenericErrorContext,
-                                     "no namespace bound to prefix %s\n",
-                                     prefix);
-                    style->warnings++;
-                    xmlFree(prefix);
-                    xmlFree(ncname);
-                    style->method = prop;
-                } else {
-                    style->methodURI = xmlStrdup(ns->href);
-                    style->method = ncname;
-                    xmlFree(prefix);
-                    xmlFree(prop);
-                }
-            } else {
-                style->method = ncname;
-                xmlFree(prop);
-            }
-        } else {
+       URI = xsltGetQNameURI(cur, &prop);
+       if (prop == NULL) {
+           style->errors++;
+       } else if (URI == NULL) {
             if ((xmlStrEqual(prop, (const xmlChar *) "xml")) ||
                 (xmlStrEqual(prop, (const xmlChar *) "html")) ||
                 (xmlStrEqual(prop, (const xmlChar *) "text"))) {
@@ -431,7 +411,10 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
                                  "invalid value for method: %s\n", prop);
                 style->warnings++;
             }
-        }
+       } else {
+           style->method = prop;
+           style->methodURI = xmlStrdup(URI);
+       }
     }
 
     prop =
@@ -501,9 +484,9 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
         xsltGetNsProp(cur, (const xmlChar *) "cdata-section-elements",
                       XSLT_NAMESPACE);
     if (elements != NULL) {
-        if (style->stripSpaces == NULL)
-            style->stripSpaces = xmlHashCreate(10);
-        if (style->stripSpaces == NULL)
+        if (style->cdataSection == NULL)
+            style->cdataSection = xmlHashCreate(10);
+        if (style->cdataSection == NULL)
             return;
 
         element = elements;
@@ -517,14 +500,21 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
                 end++;
             element = xmlStrndup(element, end - element);
             if (element) {
+               const xmlChar *URI;
 #ifdef WITH_XSLT_DEBUG_PARSING
                 xsltGenericDebug(xsltGenericDebugContext,
                                  "add cdata section output element %s\n",
                                  element);
 #endif
-                xmlHashAddEntry(style->stripSpaces, element,
-                                (xmlChar *) "cdata");
-                xmlFree(element);
+
+               URI = xsltGetQNameURI(cur, &element);
+               if (element == NULL) {
+                   style->errors++;
+               } else {
+                   xmlHashAddEntry2(style->cdataSection, element, URI,
+                                    (void *) "cdata");
+                   xmlFree(element);
+               }
             }
             element = end;
         }
@@ -1176,34 +1166,16 @@ xsltParseStylesheetKey(xsltStylesheetPtr style, xmlNodePtr key) {
      */
     prop = xsltGetNsProp(key, (const xmlChar *)"name", XSLT_NAMESPACE);
     if (prop != NULL) {
-       xmlChar *prefix = NULL;
-
-       name = xmlSplitQName2(prop, &prefix);
-       if (name != NULL) {
-           if (prefix != NULL) {
-               xmlNsPtr ns;
-
-               ns = xmlSearchNs(key->doc, key, prefix);
-               if (ns == NULL) {
-                   xsltGenericError(xsltGenericErrorContext,
-                       "no namespace bound to prefix %s\n", prefix);
-                   style->warnings++;
-                   xmlFree(prefix);
-                   xmlFree(name);
-                   name = prop;
-                   nameURI = NULL;
-               } else {
-                   nameURI = xmlStrdup(ns->href);
-                   xmlFree(prefix);
-                   xmlFree(prop);
-               }
-           } else {
-               xmlFree(prop);
-               nameURI = NULL;
-           }
+        const xmlChar *URI;
+
+       URI = xsltGetQNameURI(key, &prop);
+       if (prop == NULL) {
+           style->errors++;
+           goto error;
        } else {
            name = prop;
-           nameURI = NULL;
+           if (URI != NULL)
+               nameURI = xmlStrdup(URI);
        }
 #ifdef WITH_XSLT_DEBUG_PARSING
        xsltGenericDebug(xsltGenericDebugContext,
@@ -1260,8 +1232,8 @@ static void
 xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
     xsltTemplatePtr ret;
     xmlChar *prop;
-    xmlChar *mode;
-    xmlChar *modeURI;
+    xmlChar *mode = NULL;
+    xmlChar *modeURI = NULL;
     double  priority;
 
     if (template == NULL)
@@ -1282,34 +1254,16 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
      */
     prop = xsltGetNsProp(template, (const xmlChar *)"mode", XSLT_NAMESPACE);
     if (prop != NULL) {
-       xmlChar *prefix = NULL;
-
-       mode = xmlSplitQName2(prop, &prefix);
-       if (mode != NULL) {
-           if (prefix != NULL) {
-               xmlNsPtr ns;
-
-               ns = xmlSearchNs(template->doc, template, prefix);
-               if (ns == NULL) {
-                   xsltGenericError(xsltGenericErrorContext,
-                       "no namespace bound to prefix %s\n", prefix);
-                   style->warnings++;
-                   xmlFree(prefix);
-                   xmlFree(mode);
-                   mode = prop;
-                   modeURI = NULL;
-               } else {
-                   modeURI = xmlStrdup(ns->href);
-                   xmlFree(prefix);
-                   xmlFree(prop);
-               }
-           } else {
-               xmlFree(prop);
-               modeURI = NULL;
-           }
+        const xmlChar *URI;
+
+       URI = xsltGetQNameURI(template, &prop);
+       if (prop == NULL) {
+           style->errors++;
+           goto error;
        } else {
            mode = prop;
-           modeURI = NULL;
+           if (URI != NULL)
+               modeURI = xmlStrdup(URI);
        }
 #ifdef WITH_XSLT_DEBUG_PARSING
        xsltGenericDebug(xsltGenericDebugContext,
@@ -1334,39 +1288,23 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
 
     prop = xsltGetNsProp(template, (const xmlChar *)"name", XSLT_NAMESPACE);
     if (prop != NULL) {
-       xmlChar *ncname;
-       xmlChar *prefix = NULL;
+        const xmlChar *URI;
 
        if (ret->name != NULL) xmlFree(ret->name);
        ret->name = NULL;
        if (ret->nameURI != NULL) xmlFree(ret->nameURI);
        ret->nameURI = NULL;
 
-       ncname = xmlSplitQName2(prop, &prefix);
-       if (ncname != NULL) {
-           if (prefix != NULL) {
-               xmlNsPtr ns;
-
-               ns = xmlSearchNs(template->doc, template, prefix);
-               if (ns == NULL) {
-                   xsltGenericError(xsltGenericErrorContext,
-                       "no namespace bound to prefix %s\n", prefix);
-                   style->warnings++;
-                   xmlFree(prefix);
-                   xmlFree(ncname);
-                   ret->name = prop;
-               } else {
-                   ret->nameURI = xmlStrdup(ns->href);
-                   ret->name = ncname;
-                   xmlFree(prefix);
-                   xmlFree(prop);
-               }
-           } else {
-               ret->name = ncname;
-               xmlFree(prop);
-           }
+       URI = xsltGetQNameURI(template, &prop);
+       if (prop == NULL) {
+           style->errors++;
+           goto error;
        } else {
-           ret->name  = prop;
+           ret->name = prop;
+           if (URI != NULL)
+               ret->nameURI = xmlStrdup(URI);
+           else
+               ret->nameURI = NULL;
        }
     }
 
@@ -1376,6 +1314,7 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
     xsltParseTemplateContent(style, ret, template);
     xsltAddTemplate(style, ret, mode, modeURI);
 
+error:
     if (mode != NULL)
        xmlFree(mode);
     if (modeURI != NULL)
index c8fa47f..5eddd7f 100644 (file)
@@ -1,6 +1,8 @@
 /*
  * xsltInternals.h: internal data structures, constants and functions used
  *                  by the XSLT engine
+ *                  They are not part of the API or ABI, i.e. they can change
+ *                  without prior notice, use carefully.
  *
  * See Copyright for the status of this software.
  *
@@ -237,9 +239,10 @@ struct _xsltStylesheet {
      * General data on the style sheet document
      */
     xmlDocPtr doc;             /* the parsed XML stylesheet */
-    xmlHashTablePtr stripSpaces;/* the hash table of the strip-space
-                                  preserve space and cdata-section elements */
+    xmlHashTablePtr stripSpaces;/* the hash table of the strip-space and
+                                  preserve space elements */
     int             stripAll;  /* strip-space * (1) preserve-space * (-1) */
+    xmlHashTablePtr cdataSection;/* the hash table of the cdata-section */
 
     /*
      * Global variable or parameters
index 8a44eda..df69fac 100644 (file)
@@ -255,6 +255,91 @@ xsltSetGenericDebugFunc(void *ctx, xmlGenericErrorFunc handler) {
 
 /************************************************************************
  *                                                                     *
+ *                             QNames                                  *
+ *                                                                     *
+ ************************************************************************/
+
+/**
+ * xsltGetQNameURI:
+ * @node:  the node holding the QName
+ * @name:  pointer to the initial QName value
+ *
+ * This function analyze @name, if the name contains a prefix,
+ * the function seaches the associated namespace in scope for it.
+ * It will also replace @name value with the NCName, the old value being
+ * freed.
+ * Errors in the prefix lookup are signalled by setting @name to NULL.
+ *
+ * NOTE: the namespace returned is a pointer to the place where it is
+ *       defined and hence has the same lifespan as the document holding it.
+ *
+ * Returns the namespace URI if there is a prefix, or NULL if @name is
+ *         not prefixed.
+ */
+const xmlChar *
+xsltGetQNameURI(xmlNodePtr node, xmlChar ** name)
+{
+    int len = 0;
+    xmlChar *qname;
+    xmlNsPtr ns;
+
+    if (name == NULL)
+       return(NULL);
+    qname = *name;
+    if ((qname == NULL) || (*qname == 0))
+       return(NULL);
+    if (node == NULL) {
+       xsltGenericError(xsltGenericErrorContext,
+                        "QName: no element for namespace lookup %s\n",
+                        qname);
+       xmlFree(qname);
+       *name = NULL;
+       return(NULL);
+    }
+
+    /* nasty but valid */
+    if (qname[0] == ':')
+       return(NULL);
+
+    /*
+     * we are not trying to validate but just to cut, and yes it will
+     * work even if this is as set of UTF-8 encoded chars
+     */
+    while ((qname[len] != 0) && (qname[len] != ':')) 
+       len++;
+    
+    if (qname[len] == 0)
+       return(NULL);
+
+    /*
+     * handle xml: separately, this one is magical
+     */
+    if ((qname[0] == 'x') && (qname[1] == 'm') &&
+        (qname[2] == 'l') && (qname[3] == ':')) {
+       if (qname[4] == 0)
+           return(NULL);
+        *name = xmlStrdup(&qname[4]);
+       xmlFree(qname);
+       return(XML_XML_NAMESPACE);
+    }
+
+    qname[len] = 0;
+    ns = xmlSearchNs(node->doc, node, qname);
+    if (ns == NULL) {
+       xsltGenericError(xsltGenericErrorContext,
+               "%s:%s : no namespace bound to prefix %s\n",
+                        qname, &qname[len + 1]);
+       *name = NULL;
+       xmlFree(qname);
+       return(NULL);
+    }
+    *name = xmlStrdup(&qname[len + 1]);
+    xmlFree(qname);
+    return(ns->href);
+}
+
+/************************************************************************
+ *                                                                     *
  *                             Sorting                                 *
  *                                                                     *
  ************************************************************************/
index 8a54d9a..fce4c3c 100644 (file)
@@ -78,13 +78,21 @@ void                xsltSetGenericDebugFunc         (void *ctx,
                                                 xmlGenericErrorFunc handler);
 
 /*
- * Sorting ... this is definitely a temporary interface !
+ * Sorting
  */
 
 void           xsltDocumentSortFunction        (xmlNodeSetPtr list);
 void           xsltDoSortFunction              (xsltTransformContextPtr ctxt,
                                                 xmlNodePtr *sorts,
                                                 int nbsorts);
+
+/*
+ * QNames handling
+ */
+
+const xmlChar * xsltGetQNameURI                        (xmlNodePtr node,
+                                                xmlChar **name);
+
 /*
  * Output, reuse libxml I/O buffers
  */