Commits

ph...@9ae0c189-cd1f-4510-a509-f4891f5cf20d  committed 5bfe011

Modified Files:
LibXML.xs dom.c dom.h
+ segfault fix in importNode
+ namespace related fixes
+ getAttributeNodeNS
+ domName( node ) is aware about namespaces now

example/libxml.xml
+ documentation updates

  • Participants
  • Parent commits fb2b3e0

Comments (0)

Files changed (4)

         return NULL;
     }
     
+    /* this should be done by libxml2 !? */
+    if (doc->encoding == NULL) {
+        doc->encoding = xmlStrdup("utf-8");
+    }
+    
     return doc;
 }
 
         ret = xmlParseDocument(ctxt);
         
         well_formed = ctxt->wellFormed;
+
+        if (ctxt->myDoc->encoding == NULL) {
+            ctxt->myDoc->encoding = xmlStrdup("utf-8");
+        }
+
         RETVAL = ctxt->myDoc;
         
         xmlFreeParserCtxt(ctxt);
         
         xmlParseDocument(ctxt);
         RETVAL = ctxt->myDoc;
+        if (RETVAL->encoding == NULL) {
+            RETVAL->encoding = xmlStrdup("utf-8");
+        }
         ret = ctxt->wellFormed;
         
         xmlFreeParserCtxt(ctxt);
     OUTPUT:
         RETVAL
 
+ProxyObject *
+createAttributeNS( dom, nsURI, qname, value="" )
+        SV * dom
+        char * nsURI
+        char * qname
+        char * value
+    PREINIT:
+        const char* CLASS = "XML::LibXML::Attr";
+        xmlNodePtr newNode;
+        xmlChar *prefix;
+        xmlChar *lname;
+        xmlNsPtr ns;
+    CODE:
+        lname = xmlSplitQName2(qname, &prefix);
+        if (lname == NULL) {
+            lname = qname;
+        }
+        ns = domNewNs (0 , prefix , nsURI);
+        newNode = (xmlNodePtr)xmlNewNsProp(NULL, ns, lname , value );
+        newNode->doc = (xmlDocPtr)SvIV((SV*)SvRV(dom));
+        if ( newNode->children!=NULL ) {
+            newNode->children->doc = (xmlDocPtr)SvIV((SV*)SvRV(dom));
+        }
+        RETVAL = make_proxy_node(newNode);
+        RETVAL->extra = dom;
+        SvREFCNT_inc(dom);    
+    OUTPUT:
+        RETVAL
+
 void 
 setDocumentElement( dom , proxy )
         SV * dom
         const char * name;
     CODE:
         if( node != NULL ) {
-            name =  node->name;
+            name =  domName( node );
+            RETVAL = newSVpvn( (char *)name, xmlStrlen( name ) );
         }
-        RETVAL = newSVpvn( (char *)name, xmlStrlen( name ) );
+        else {
+            RETVAL = &PL_sv_undef;
+        }
+
     OUTPUT:
         RETVAL
 
     CODE:
         if( node != NULL ) {
             lname =  node->name;
+            RETVAL = newSVpvn( (char *)lname, xmlStrlen( lname ) );
         }
-        RETVAL = newSVpvn( (char *)lname, xmlStrlen( lname ) );
+        else {
+            RETVAL = &PL_sv_undef;
+        }
     OUTPUT:
         RETVAL
 
             && node->ns->prefix != NULL ) {
             prefix =  node->ns->prefix;
             RETVAL = newSVpvn( (char *)prefix, xmlStrlen( prefix ) );
-        } else {
-            RETVAL = NULL;
+        }
+        else {
+            RETVAL = &PL_sv_undef;
         }
     OUTPUT:
         RETVAL
             && node->ns->href != NULL ) {
             nsURI =  node->ns->href;
             RETVAL = newSVpvn( (char *)nsURI, xmlStrlen( nsURI ) );
-        } else {
-            RETVAL = NULL;
+        }
+        else {
+            RETVAL = &PL_sv_undef;
         }
     OUTPUT:
         RETVAL
             RETVAL->extra = elemobj->extra;
             SvREFCNT_inc(elemobj->extra);
         }
+        else {
+            RETVAL = NULL;
+        }
+    OUTPUT:
+        RETVAL
+
+ProxyObject *
+getAttributeNodeNS( elemobj, nsURI, name )
+        ProxyObject* elemobj 
+        char * nsURI
+        char * name
+    PREINIT:
+        const char * CLASS = "XML::LibXML::Attr";
+        xmlNodePtr elem = (xmlNodePtr) elemobj->object;
+        xmlAttrPtr attrnode;
+    CODE:
+        attrnode = domHasNsProp( elem, name, nsURI );
+        if ( attrnode != NULL ) {
+            RETVAL = make_proxy_node((xmlNodePtr)attrnode);
+            RETVAL->extra = elemobj->extra;
+            SvREFCNT_inc(elemobj->extra);
+        }
+        else {
+            RETVAL = NULL;
+        }
     OUTPUT:
         RETVAL
 
                 }
             }
         }
+        else {
+            RETVAL = &PL_sv_undef;
+        }
     OUTPUT:
         RETVAL
 
        */
         doc->encoding = xmlStrdup(enc);
     }
+    else {
+        doc->encoding = xmlStrdup("UTF-8");
+    }
 
     return doc;
 }
 xmlNodePtr
 domRemoveChild( xmlNodePtr self, xmlNodePtr old );
 
+/**
+ * Name: domName
+ * Synopsis: string = domName( node );
+ *
+ * domName returns the full name for the current node.
+ * If the node belongs to a namespace it returns the prefix and 
+ * the local name. otherwise only the local name is returned.
+ **/
+const xmlChar*
+domName(xmlNodePtr node) {
+  xmlChar *qname = NULL; 
+  if ( node ) {
+    if (node->ns != NULL) {
+      if (node->ns->prefix != NULL) {
+        qname = xmlStrdup( node->ns->prefix );
+        qname = xmlStrcat( qname , ":" );
+        qname = xmlStrcat( qname , node->name );
+      } 
+      else {
+        qname = xmlStrdup( node->name );
+      }
+    } 
+    else {
+      qname = xmlStrdup( node->name );
+    }
+  }
+  return qname;
+}
+
+
 xmlNodePtr
 domAppendChild( xmlNodePtr self,
 		xmlNodePtr newChild ){
 
 void
 domSetNodeValue( xmlNodePtr n , xmlChar* val ){
-  xmlDocPtr doc = n->doc;
+  xmlDocPtr doc = NULL;
   
   if ( n == NULL ) 
     return;
+
   if( n->content != NULL ) {
+    /* free old content */
     xmlFree( n->content );
   }
 
-  if ( doc != NULL ){
+  doc = n->doc;
+
+  if ( doc != NULL ) {
     xmlCharEncodingHandlerPtr handler = xmlGetCharEncodingHandler( xmlParseCharEncoding(doc->encoding) );
 
     if ( handler != NULL ){
        }
     }
     else {
+      /* handler error => no output */ 
       n->content = xmlStrdup( "" );
     }
   }
   else {    
+    /* take data as UTF-8 */
     n->content = xmlStrdup( val );
   }
 }
 
 xmlNodePtr
 domImportNode( xmlDocPtr doc, xmlNodePtr node, int move ) {
-  xmlNodePtr return_node;
+  xmlNodePtr return_node = node;
 
   if ( !doc ) {
-    return node;
+    return_node = node;
   }
-
-  if ( node && node->doc != doc ) {
+  else if ( node && node->doc != doc ) {
     if ( move ) {
       return_node = domUnbindNode( node );
     }
     /* tell all children about the new boss */ 
     return_node = domSetOwnerDocument( return_node, doc ); 
   }
-
+ 
   return return_node;
 }
 
 
 /* A.1 DOM specified section */
 
+const xmlChar *
+domName( xmlNodePtr );
+
 xmlNodePtr
 domAppendChild( xmlNodePtr self,
                 xmlNodePtr newChild );

File example/libxml.xml

 <short>DOM Document Class</short>
 <description>
 	The Document Class is the result of a parsing process. But
-	sometimes it is needed, to create a Document from scratch. The
-	provides functions that are conform to the DOM Core naming
-	style.
+	sometimes it is necessary to create a Document from
+	scratch. The DOM Document Class provides functions that are
+	conform to the DOM Core naming style.
 
-    It is suggested, allways to create a node unbound of a document.
-    There is no need of really including the node to the document, but
-    since the node is once bound to a document, it is quite save that
-    all strings have the correct encoding. If an unbound textnode with
-    an iso encoded string is created (e.g. with $CLASS->new()), the
-    <i>toString</i> function may not return the expected result.
-
-    This seems like a limitation as long UTF8 encoding is ashured. If
-    iso encoded strings come into play it is much saver to use the
+    It is suggested that one should always create a node not bound to
+    any document.  There is no need of really including the node to
+    the document, but once the node is bound to a document, it is
+    quite safe that all strings have the correct encoding.  If an
+    unbound textnode with an iso encoded string is created (e.g. with
+    $CLASS->new()), the <i>toString</i> function may not return the
+    expected result.
+  
+    This seems like a limitation as long UTF8 encoding is assured. If
+    iso encoded strings come into play it is much safer to use the
     node creation functions of <b>XML::LibXML::Document</b>. 
 
 <method name="new" 
 </method>
 
 <method name="createElementNS" 
-	synopsis="$element = $dom->createElement( $nsURI, $nodename );">
-    Namespace version of <i>createElement</i>
+	synopsis="$element = $dom->createElementNS( $namespaceURI, $qname );">
+    This function creates a new Element Node bound to the DOM with
+    the name <i>$nodename</i> and placed in the given namespace.
 </method>
 
 <method name="createTextNode" 
 
 <method name="hasAttribute" synopsis="$boolean = $node->hasAttribute( $aname );">
     This funcion tests if the named attribute is set for the node. If
-    the attrbute is specified, TRUE (1) will be returned, otherwise
+    the attribute is specified, TRUE (1) will be returned, otherwise
     the returnvalue is FALSE (0).
 </method>