fixed handling of #default in namespace-alias for default namespace (bug
authorWilliam M. Brack <wbrack@src.gnome.org>
Sun, 15 Aug 2004 04:55:29 +0000 (04:55 +0000)
committerWilliam M. Brack <wbrack@src.gnome.org>
Sun, 15 Aug 2004 04:55:29 +0000 (04:55 +0000)
* libxslt/namespaces.[ch], transform.c, xslt.c, xsltInternals.h:
  fixed handling of #default in namespace-alias for default
  namespace (bug 149659)
* tests/namespaces/tst7.* tst8.*: added regression tests for above

13 files changed:
ChangeLog
libxslt/namespaces.c
libxslt/namespaces.h
libxslt/transform.c
libxslt/xslt.c
libxslt/xsltInternals.h
tests/namespaces/Makefile.am
tests/namespaces/tst7.out [new file with mode: 0644]
tests/namespaces/tst7.xml [new file with mode: 0644]
tests/namespaces/tst7.xsl [new file with mode: 0644]
tests/namespaces/tst8.out [new file with mode: 0644]
tests/namespaces/tst8.xml [new file with mode: 0644]
tests/namespaces/tst8.xsl [new file with mode: 0644]

index 50e0a80..4bef938 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sat Aug 14 21:49:48 PDT 2004 William Brack <wbrack@mmm.comlhk>
+
+       * libxslt/namespaces.[ch], transform.c, xslt.c, xsltInternals.h:
+         fixed handling of #default in namespace-alias for default
+         namespace (bug 149659)
+       * tests/namespaces/tst7.* tst8.*: added regression tests for above
+
 Fri Aug  6 11:05:31 PDT 2004 William Brack <wbrack@mmm.com.hk>
 
        * libexslt/date.c: added date:sum routine supplied by Joel
index f8a62cc..d54edf7 100644 (file)
@@ -64,8 +64,10 @@ void
 xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node) {
     xmlChar *sprefix;
     xmlNsPtr sNs;
+    const xmlChar *shref;
     xmlChar *rprefix;
     xmlNsPtr rNs;
+    const xmlChar *rhref;
 
     sprefix = xsltGetNsProp(node, (const xmlChar *)"stylesheet-prefix",
                           XSLT_NAMESPACE);
@@ -81,37 +83,68 @@ xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node) {
            "namespace-alias: result-prefix attribute missing\n");
        goto error;
     }
+    
     if (xmlStrEqual(sprefix, (const xmlChar *)"#default")) {
+        /*
+        * Do we have a default namespace previously declared?
+        */
        sNs = xmlSearchNs(node->doc, node, NULL);
+       if (sNs == NULL)
+           shref = NULL;       /* No - set NULL */
+       else
+           shref = sNs->href;  /* Yes - set for nsAlias table */
     } else {
        sNs = xmlSearchNs(node->doc, node, sprefix);
+       if ((sNs == NULL) || (sNs->href == NULL)) {
+           xsltTransformError(NULL, style, node,
+               "namespace-alias: prefix %s not bound to any namespace\n",
+                                       sprefix);
+           goto error;
+       } else
+           shref = sNs->href;
     }
-    if ((sNs == NULL) || (sNs->href == NULL)) {
-       xsltTransformError(NULL, style, node,
-           "namespace-alias: prefix %s not bound to any namespace\n",
-                        sprefix);
-       goto error;
-    }
+
+    /*
+     * When "#default" is used for result, if a default namespace has not
+     * been explicitly declared the special value UNDEFINED_DEFAULT_NS is
+     * put into the nsAliases table
+     */
     if (xmlStrEqual(rprefix, (const xmlChar *)"#default")) {
        rNs = xmlSearchNs(node->doc, node, NULL);
+       if (rNs == NULL)
+           rhref = UNDEFINED_DEFAULT_NS;
+       else
+           rhref = rNs->href;
     } else {
        rNs = xmlSearchNs(node->doc, node, rprefix);
+
+        if ((rNs == NULL) || (rNs->href == NULL)) {
+           xsltTransformError(NULL, style, node,
+               "namespace-alias: prefix %s not bound to any namespace\n",
+                                       rprefix);
+           goto error;
+       } else
+           rhref = rNs->href;
     }
-    if ((rNs == NULL) || (rNs->href == NULL)) {
-       xsltTransformError(NULL, style, node,
-           "namespace-alias: prefix %s not bound to any namespace\n",
-                        rprefix);
-       goto error;
-    }
-    if (style->nsAliases == NULL)
-       style->nsAliases = xmlHashCreate(10);
-    if (style->nsAliases == NULL) {
-       xsltTransformError(NULL, style, node,
-           "namespace-alias: cannot create hash table\n");
-       goto error;
+    /*
+     * Special case if #default is used for stylesheet and no default has
+     * been explicitly declared.  We use style->defaultAlias for this
+     */
+    if (shref == NULL) {
+        if (rNs != NULL)
+            style->defaultAlias = rNs->href;
+    } else {
+        if (style->nsAliases == NULL)
+           style->nsAliases = xmlHashCreate(10);
+        if (style->nsAliases == NULL) {
+           xsltTransformError(NULL, style, node,
+               "namespace-alias: cannot create hash table\n");
+           goto error;
+        }
+        xmlHashAddEntry((xmlHashTablePtr) style->nsAliases,
+                   shref, (void *) rhref);
     }
-    xmlHashAddEntry((xmlHashTablePtr) style->nsAliases,
-                   sNs->href, (void *) rNs->href);
 
 error:
     if (sprefix != NULL)
@@ -247,6 +280,15 @@ xsltGetPlainNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur,
        style = xsltNextImport(style);
     }
 
+    if (URI == UNDEFINED_DEFAULT_NS) {
+        xmlNsPtr dflt;
+       dflt = xmlSearchNs(cur->doc, cur, NULL);
+        if (dflt == NULL)
+           return NULL;
+       else
+           URI = dflt->href;
+    }
+
     if (URI == NULL)
        URI = ns->href;
 
@@ -368,7 +410,14 @@ xsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns,
        style = xsltNextImport(style);
     }
 
-    if (URI == NULL)
+    if (URI == UNDEFINED_DEFAULT_NS) {
+        xmlNsPtr dflt;
+       dflt = xmlSearchNs(cur->doc, cur, NULL);
+       if (dflt != NULL)
+           URI = dflt->href;
+       else
+           return NULL;
+    } else if (URI == NULL)
        URI = ns->href;
 
     /*
@@ -456,6 +505,8 @@ xsltCopyNamespaceList(xsltTransformContextPtr ctxt, xmlNodePtr node,
            /* TODO apply cascading */
            URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases,
                                                  cur->href);
+           if (URI == UNDEFINED_DEFAULT_NS)
+               continue;
            if (URI != NULL) {
                q = xmlNewNs(node, URI, cur->prefix);
            } else {
@@ -505,6 +556,8 @@ xsltCopyNamespace(xsltTransformContextPtr ctxt, xmlNodePtr node,
     if (!xmlStrEqual(cur->href, XSLT_NAMESPACE)) {
        URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases,
                                              cur->href);
+       if (URI == UNDEFINED_DEFAULT_NS)
+           return(NULL);
        if (URI != NULL) {
            ret = xmlNewNs(node, URI, cur->prefix);
        } else {
index c92eb1a..acc3aa0 100644 (file)
 extern "C" {
 #endif
 
+/*
+ * Used within nsAliases hashtable when the default namespace is required
+ * but it's not been explicitly defined
+ */
+#define        UNDEFINED_DEFAULT_NS    (const xmlChar *) -1L
+
 XSLTPUBFUN void XSLTCALL
                xsltNamespaceAlias      (xsltStylesheetPtr style,
                                         xmlNodePtr node);
index 35b6e2b..043f009 100644 (file)
@@ -1715,6 +1715,15 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
                      style = xsltNextImport(style);
                    }
 
+                   if (URI == UNDEFINED_DEFAULT_NS) {
+                     xmlNsPtr dflt;
+                     dflt = xmlSearchNs(cur->doc, cur, NULL);
+                     if (dflt == NULL)
+                       continue;
+                     else
+                       URI = dflt->href;
+                   }
+
                    if (URI == NULL) {
                      ret = xmlSearchNs(copy->doc, copy, ns->prefix);
                      if ((ret == NULL) ||
index 2445c76..72b8869 100644 (file)
@@ -1496,6 +1496,11 @@ xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ) {
             * This is an element which will be output as part of the
             * template exectution, precompile AVT if found.
             */
+           if ((cur->ns == NULL) && (style->defaultAlias != NULL) &&
+                       (cur->type == XML_ELEMENT_NODE)) {
+               cur->ns = xmlSearchNsByHref(cur->doc, cur,
+                       style->defaultAlias);
+           }
            if (cur->properties != NULL) {
                xmlAttrPtr attr = cur->properties;
 
index b5d5238..386405c 100644 (file)
@@ -431,6 +431,10 @@ struct _xsltStylesheet {
      * precompiled attribute value templates.
      */
     void *attVTs;
+    /*
+     * if namespace-alias has an alias for the default stylesheet prefix
+     */
+    const xmlChar *defaultAlias;
 };
 
 /*
index ebb9581..4c58bd7 100644 (file)
@@ -11,7 +11,9 @@ EXTRA_DIST = \
     tst3.xml tst3.xsl tst3.out \
     tst4.xml tst4.xsl tst4.out \
     tst5.xml tst5.xsl tst5.out \
-    tst6.xml tst6.xsl tst6.out
+    tst6.xml tst6.xsl tst6.out \
+    tst7.xml tst7.xsl tst7.out \
+    tst8.xml tst8.xsl tst8.out
 
 all:
 
diff --git a/tests/namespaces/tst7.out b/tests/namespaces/tst7.out
new file mode 100644 (file)
index 0000000..b86f605
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>
+                                        A title
+                                </title>
+  </head>
+  <body>
+                                        Some text
+                        </body>
+</html>
diff --git a/tests/namespaces/tst7.xml b/tests/namespaces/tst7.xml
new file mode 100644 (file)
index 0000000..ac9ac8f
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" ?>
+<adoc />
diff --git a/tests/namespaces/tst7.xsl b/tests/namespaces/tst7.xsl
new file mode 100644 (file)
index 0000000..1ce238b
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+        xmlns:html="http://http://www.w3.org/1999/xhtml">
+        <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"
+doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
+doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
+        <xsl:namespace-alias stylesheet-prefix="html" result-prefix="#default" />
+        <xsl:strip-space elements="*" />
+        <xsl:template match="/adoc">
+                <html:html>
+                        <html:head>
+                                <html:title>
+                                        A title
+                                </html:title>
+                        </html:head>
+                        <html:body>
+                                        Some text
+                        </html:body>
+                </html:html>
+        </xsl:template>
+</xsl:stylesheet>
diff --git a/tests/namespaces/tst8.out b/tests/namespaces/tst8.out
new file mode 100644 (file)
index 0000000..5eabde5
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<bb:root xmlns:bb="http://bbrack.org">
+  <element1 xmlns="http://delightful.com.hk">
+    <element2>Content 2</element2>
+  </element1>
+  <bb:element3>Content 3</bb:element3>
+</bb:root>
diff --git a/tests/namespaces/tst8.xml b/tests/namespaces/tst8.xml
new file mode 100644 (file)
index 0000000..ac9ac8f
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" ?>
+<adoc />
diff --git a/tests/namespaces/tst8.xsl b/tests/namespaces/tst8.xsl
new file mode 100644 (file)
index 0000000..52f2caa
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<xsl:stylesheet version="1.0"
+        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       xmlns:bb="http://bbrack.org">
+    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
+    <xsl:namespace-alias
+        stylesheet-prefix="#default" 
+       result-prefix="bb" />
+    <xsl:strip-space elements="*" />
+    <xsl:template match="/adoc">
+        <root>
+           <element1 xmlns="http://delightful.com.hk">
+               <element2>Content 2</element2>
+           </element1>
+           <element3>Content 3</element3>
+       </root>
+    </xsl:template>
+</xsl:stylesheet>