Anonymous avatar Anonymous committed 203a61e

Modified Files:
LibXML.xs perl-libxml-mm.c
[fix] clone node bug with namespaces

t/04node.t
test the cloning of namespaces.

Comments (0)

Files changed (3)

                 xmlSetTreeDoc(ret, doc);
             }
             
-            # make namespaces available
-            ret->ns = self->ns;
             docfrag = PmmNewFragment( doc );
             xmlAddChild( PmmNODE(docfrag), ret );
             RETVAL = PmmNodeToSv(ret, docfrag);
         }
 
 SV *
-getNamespace( pnode )
-        SV * pnode
+getNamespace( node )
+        xmlNodePtr node
     ALIAS:  
         localNamespace = 1
         localNS        = 2
     PREINIT:
-        xmlNodePtr node;
         xmlNsPtr ns = NULL;
         xmlNsPtr newns = NULL;
         const char * class = "XML::LibXML::Namespace";
-    INIT:
-        node = PmmSvNode(pnode);
-        if ( node == NULL ) {
-            croak( "lost node" );
-        }
     CODE:
         ns = node->ns;
         if ( ns != NULL ) {
+            warn( "node has namespace! %s", ns->prefix );
             newns = xmlCopyNamespace(ns);
             if ( newns != NULL ) {
                 RETVAL = NEWSV(0,0);
                                       );
             }
         }
+        else {
+            warn( "node has no namespace!" );
+            XSRETURN_UNDEF;
+        }
     OUTPUT:
         RETVAL
         
         case XML_DOCUMENT_NODE:
         case XML_HTML_DOCUMENT_NODE:
         case XML_DOCB_DOCUMENT_NODE:
-            dfProxy->encoding = (int)xmlParseCharEncoding( (const char*)((xmlDocPtr)node)->encoding );
+            if ( ((xmlDocPtr)node)->encoding != NULL ) {
+                dfProxy->encoding = (int)xmlParseCharEncoding( (const char*)((xmlDocPtr)node)->encoding );
+            }
             break;
         default:
             break;
     if ( node != NULL ) {
         switch ( node->type ) {
         case XML_ELEMENT_NODE:
+            retval = xmlCopyNode( node, recursive );
+            xmlReconciliateNs(retval->doc, retval);
+            break;
 		case XML_TEXT_NODE:
 		case XML_CDATA_SECTION_NODE:
 		case XML_ENTITY_REF_NODE:
             break;
 		case XML_ATTRIBUTE_NODE:
             retval = (xmlNodePtr) xmlCopyProp( NULL, (xmlAttrPtr) node );
+            xmlReconciliateNs(retval->doc, retval);
             break;
         case XML_DOCUMENT_NODE:
 		case XML_HTML_DOCUMENT_NODE:
         coder =xmlFindCharEncodingHandler( (const char *)encoding );
     }
     else {
-        xs_warn("no encoding found\n");
+        xs_warn("no encoding found \n");
     }
 
     if ( coder != NULL ) {
 
 use Test;
 
-BEGIN { plan tests => 122 };
+BEGIN { plan tests => 125 };
 use XML::LibXML;
 use XML::LibXML::Common qw(:libxml);
 
             ok( scalar(@cn), 1);
             ok( $cn[0]->nodeName, "bar" );
             ok( !$cn[0]->isSameNode( $c1node ) );
+
+            print "# clone namespaced elements\n";
+            my $nsnode = $doc->createElementNS( "foo", "foo:bar" );
+
+            my $cnsnode = $nsnode->cloneNode(0);
+            ok( $cnsnode->nodeName, "bar" );
+            ok( $cnsnode->localNS(), undef );
+
+            print "# clone namespaced elements (recursive)\n";
+            my $c2nsnode = $nsnode->cloneNode(1);
+            ok( $c2nsnode->toString(), $nsnode->toString() );
         }
 
         print "# 1.3 Node Value\n";
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.