]> granicus.if.org Git - php/commitdiff
Fixed bug #34276 (setAttributeNS doesn't work with default namespace)
authorRob Richards <rrichards@php.net>
Sun, 28 Aug 2005 16:22:03 +0000 (16:22 +0000)
committerRob Richards <rrichards@php.net>
Sun, 28 Aug 2005 16:22:03 +0000 (16:22 +0000)
Add test

ext/dom/element.c
ext/dom/tests/bug34276.phpt [new file with mode: 0644]

index 26fb297488cdfcac32b88029316f99bdbf3902f4..68e63c061c55cf047c7d0188bfc67e3055414608 100644 (file)
@@ -501,6 +501,42 @@ PHP_FUNCTION(dom_element_get_attribute_ns)
 }
 /* }}} end dom_element_get_attribute_ns */
 
+static xmlNsPtr _dom_new_reconNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
+    xmlNsPtr def;
+    xmlChar prefix[50];
+    int counter = 1;
+
+       if ((tree == NULL) || (ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) {
+               return NULL;
+       }
+
+       /* Code taken from libxml2 (2.6.20) xmlNewReconciliedNs
+        *
+        * Find a close prefix which is not already in use.
+        * Let's strip namespace prefixes longer than 20 chars !
+        */
+       if (ns->prefix == NULL)
+               snprintf((char *) prefix, sizeof(prefix), "default");
+       else
+               snprintf((char *) prefix, sizeof(prefix), "%.20s", (char *)ns->prefix);
+
+       def = xmlSearchNs(doc, tree, prefix);
+       while (def != NULL) {
+               if (counter > 1000) return(NULL);
+               if (ns->prefix == NULL)
+                       snprintf((char *) prefix, sizeof(prefix), "default%d", counter++);
+               else
+                       snprintf((char *) prefix, sizeof(prefix), "%.20s%d", 
+                       (char *)ns->prefix, counter++);
+               def = xmlSearchNs(doc, tree, prefix);
+       }
+
+       /*
+        * OK, now we are ready to create a new one.
+        */
+       def = xmlNewNs(tree, ns->href, prefix);
+       return(def);
+}
 
 /* {{{ proto void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value);
 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS
@@ -550,8 +586,21 @@ PHP_FUNCTION(dom_element_set_attribute_ns)
                                nsptr = dom_get_nsdecl(elemp, localname);
                        } else {
                                nsptr = xmlSearchNsByHref(elemp->doc, elemp, uri);
-                               while (nsptr && nsptr->prefix == NULL) {
-                                       nsptr = nsptr->next;
+                               if (nsptr && nsptr->prefix == NULL) {
+                                       xmlNsPtr tmpnsptr;
+
+                                       tmpnsptr = nsptr->next;
+                                       while (tmpnsptr) {
+                                               if ((tmpnsptr->prefix != NULL) && (tmpnsptr->href != NULL) && 
+                                                       (xmlStrEqual(tmpnsptr->href, (xmlChar *) uri))) {
+                                                       nsptr = tmpnsptr;
+                                                       break;
+                                               }
+                                               tmpnsptr = tmpnsptr->next;
+                                       }
+                                       if (tmpnsptr == NULL) {
+                                               nsptr = _dom_new_reconNs(elemp->doc, elemp, nsptr);
+                                       }
                                }
                        }
 
diff --git a/ext/dom/tests/bug34276.phpt b/ext/dom/tests/bug34276.phpt
new file mode 100644 (file)
index 0000000..e108336
--- /dev/null
@@ -0,0 +1,43 @@
+--TEST--
+Bug # 34276: setAttributeNS and default namespace
+--SKIPIF--
+<?php require_once('skipif.php'); ?>
+--FILE--
+<?php
+$xml = <<<HERE
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<foo xmlns="http://www.example.com/ns/foo"
+     xmlns:fubar="http://www.example.com/ns/fubar" attra="attra" />
+HERE;
+
+function dump($elems) {
+       foreach ($elems as $elem) {
+               var_dump($elem->nodeName);
+               dump($elem->childNodes);
+       }
+}
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$foo = $dom->documentElement;
+var_dump($foo->hasAttributeNS('http://www.example.com/ns/foo', 'attra'));
+var_dump($foo->getAttributeNS('http://www.example.com/ns/foo', 'attra'));
+
+$foo->setAttributeNS('http://www.example.com/ns/foo', 'attra', 'attranew');
+$foo->setAttributeNS('http://www.example.com/ns/fubar', 'attrb', 'attrbnew');
+$foo->setAttributeNS('http://www.example.com/ns/foo', 'attrc', 'attrc');
+
+var_dump($foo->getAttributeNS('http://www.example.com/ns/foo', 'attra'));
+var_dump($foo->getAttributeNS('http://www.example.com/ns/fubar', 'attrb'));
+var_dump($foo->getAttributeNS('http://www.example.com/ns/foo', 'attrc'));
+
+print $dom->saveXML();
+?>
+--EXPECT--
+bool(false)
+string(0) ""
+string(8) "attranew"
+string(8) "attrbnew"
+string(5) "attrc"
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<foo xmlns="http://www.example.com/ns/foo" xmlns:fubar="http://www.example.com/ns/fubar" xmlns:default="http://www.example.com/ns/foo" attra="attra" default:attra="attranew" fubar:attrb="attrbnew" default:attrc="attrc"/>