1. Shlomi Fish
  2. perl-XML-LibXML

Commits

Daniel Frett  committed 5b6ce77

updated the namespace search logic for _setAttributeNS.

This update fixes another corner case that resulted in an attribute being set in the wrong namespace.

  • Participants
  • Parent commits 731ea03
  • Branches default

Comments (0)

Files changed (2)

File LibXML.xs

View file
         xmlNsPtr ns         = NULL;
         xmlChar * localname = NULL;
         xmlChar * prefix    = NULL;
+        xmlNsPtr * all_ns   = NULL;
+        int i;
     INIT:
         name  = nodeSv2C( attr_name, self );
 
             xs_warn( "found uri" );
 
             ns = xmlSearchNsByHref( self->doc, self, nsURI );
+
+            /*
+             * check for any prefixed namespaces occluded by a default namespace
+             * because xmlSearchNsByHref will return default namespaces unless
+             * you are searching on an attribute node, which may not exist yet
+             */
+            if ( ns && !ns->prefix )
+            {
+                all_ns = xmlGetNsList(self->doc, self);
+                if ( all_ns )
+                {
+                    i = 0;
+                    ns = all_ns[i];
+                    while ( ns )
+                    {
+                        if ( ns->prefix && xmlStrEqual(ns->href, nsURI) )
+                        {
+                            break;
+                        }
+                        ns = all_ns[i++];
+                    }
+                    xmlFree(all_ns);
+                }
+            }
+
             if ( !ns ) {
                 /* create new ns */
-                 if ( prefix && xmlStrlen( prefix ) ) {
-                    ns = xmlNewNs(self, nsURI , prefix );
-                 }
-                 else {
-                    ns = NULL;
-                 }
-            }
-            else if ( !ns->prefix ) {
                 if ( prefix && xmlStrlen( prefix ) ) {
-                    ns = xmlSearchNs(self->doc, self, prefix);
-
-                    if ( ns ) {
-                        if ( !xmlStrEqual(ns->href, nsURI) ) {
-                            ns = NULL;
-                        }
-                    }
-                    else {
-                        ns = xmlNewNs(self, nsURI , prefix );
-                    }
-                }
-                else if ( ns->next && ns->next->prefix ) {
-                    ns = ns->next;
+                    ns = xmlNewNs(self, nsURI , prefix);
                 }
                 else {
                     ns = NULL;

File t/48_rt55000.t

View file
 
 =cut
 
-use Test::More tests => 3;
+use Test::More tests => 6;
 
 use XML::LibXML;
 
 my $doc = $parser->parse_string($xml_string);
 my $root = $doc->documentElement();
 $root->setAttributeNS("uri", "prefix:attribute", "text");
+$root->setAttributeNS("uri", "second", "text");
 
 my $string = $doc->toString(1);
 
 like ($string, qr/\bprefix:attribute="text"/,
     "Placed in the right namespace");
 
+# TEST
+unlike ($string, qr/[^\w:]second="text"/,
+    "Not placed as an unprefixed attribute");
+
+# TEST
+unlike ($string, qr/\bwrong:second="text"/,
+    "Not placed in the wrong namespace");
+
+# TEST
+like ($string, qr/\bprefix:second="text"/,
+    "Placed in the right namespace");
+