Anonymous avatar Anonymous committed 0582535

the last commit on perl-libxml-mm was broken. the bug is fixed with
this release.

Modified Files:
Changes
+ version notes

LibXML.pm LibXML.xs
- encode* decode* functions moved to XML::LibXML::Common
- node type constants moved to XML::LibXML::Common
+ prepared error handling for global use

dom.c
+ started error handling

perl-libxml-mm.c perl-libxml-mm.h
+ performance updates for nodeC2Sv() and nodeSv2C()
this requires a tiny extension of the ProxyNode structure, but
reduces the number of string parses significantly

this patch does not affect any *real* memory management. the only
thing added is the external encoding id of a document.

t/02parse.t t/03doc.t t/04node.t t/06elements.t t/07dtd.t
t/10ns.t t/19encoding.t
+ use XML::LibXML::Common to make tests work.

Comments (0)

Files changed (12)

 manpage!
 
 1.53
+   - catalog interface
+   - toFH() fixed
    - enabled SGML parsing
    - fixed namespace setting in XPath functions:
      the namespaces of the document element will always be added now
             $skipDTD $skipXMLDeclaration $setTagCompression
             $MatchCB $ReadCB $OpenCB $CloseCB );
 use Carp;
+
+use XML::LibXML::Common qw(:encoding :libxml :w3c);
 use XML::LibXML::NodeList;
 use IO::Handle; # for FH reads called as methods
 
 
 bootstrap XML::LibXML $VERSION;
 
-@EXPORT = qw( XML_ELEMENT_NODE
-              XML_ATTRIBUTE_NODE
-              XML_TEXT_NODE
-              XML_CDATA_SECTION_NODE
-              XML_ENTITY_REF_NODE
-              XML_ENTITY_NODE
-              XML_PI_NODE
-              XML_COMMENT_NODE
-              XML_DOCUMENT_NODE
-              XML_DOCUMENT_TYPE_NODE
-              XML_DOCUMENT_FRAG_NODE
-              XML_NOTATION_NODE
-              XML_HTML_DOCUMENT_NODE
-              XML_DTD_NODE
-              XML_ELEMENT_DECL
-              XML_ATTRIBUTE_DECL
-              XML_ENTITY_DECL
-              XML_NAMESPACE_DECL
-              XML_XINCLUDE_START
-              XML_XINCLUDE_END
-              encodeToUTF8
-              decodeFromUTF8
-            );
-
-@EXPORT_OK = qw(
-                ELEMENT_NODE
-                ATTRIBUTE_NODE
-                TEXT_NODE
-                CDATA_SECTION_NODE
-                ENTITY_REFERENCE_NODE
-                ENTITY_NODE
-                PROCESSING_INSTRUCTION_NODE
-                COMMENT_NODE
-                DOCUMENT_NODE
-                DOCUMENT_TYPE_NODE
-                DOCUMENT_FRAGMENT_NODE
-                NOTATION_NODE
-                HTML_DOCUMENT_NODE
-                DTD_NODE
-                ELEMENT_DECLARATION
-                ATTRIBUTE_DECLARATION
-                ENTITY_DECLARATION
-                NAMESPACE_DECLARATION
-                NAMESPACE_DECLARATION
-                XINCLUDE_END
-                XINCLUDE_START
-               );
-
-%EXPORT_TAGS = (
-                all => [@EXPORT, @EXPORT_OK],
-                w3c_typenames => [qw(
-                                     ELEMENT_NODE
-                                     ATTRIBUTE_NODE
-                                     TEXT_NODE
-                                     CDATA_SECTION_NODE
-                                     ENTITY_REFERENCE_NODE
-                                     ENTITY_NODE
-                                     PROCESSING_INSTRUCTION_NODE
-                                     COMMENT_NODE
-                                     DOCUMENT_NODE
-                                     DOCUMENT_TYPE_NODE
-                                     DOCUMENT_FRAGMENT_NODE
-                                     NOTATION_NODE
-                                     HTML_DOCUMENT_NODE
-                                     DTD_NODE
-                                     ELEMENT_DECLARATION
-                                     ATTRIBUTE_DECLARATION
-                                     ENTITY_DECLARATION
-                                     NAMESPACE_DECLARATION
-                                     NAMESPACE_DECLARATION
-                                     XINCLUDE_END
-                                     XINCLUDE_START
-                                    )],
-                encoding => [qw(
-                                encodeToUTF8
-                                decodeFromUTF8
-                               )],
-               );
-
 sub new {
     my $class = shift;
     my %options = @_;
     }
 }
 
+# catalog interfaces
+sub default_catalog {
+    my $self = shift;
+    my $catalog = shift;
+    if ( ref( $catalog ) != "XML::LibXML::Catalog" ) {
+        croak "structure is not a catalog";
+    }
+    return $self->_default_catalog( $catalog );
+}
+
+# this will go to xs!
+sub load_catalog {
+    my $self     = shift;
+    my $filename = shift;
+
+    return undef;
+}
+
+sub use_catalog {
+    my $self = shift; # parser
+    my $catalog = shift;
+    if ( ref $self ) {
+        if ( ref( $catalog ) != "XML::LibXML::Catalog" ) {
+            croak "structure is not a catalog";
+        }
+        return 1;
+    }
+    return undef;
+}
 
 1;
 
 
 static SV * LibXML_error    = NULL;
 
+#define LibXML_init_error() LibXML_error = NEWSV(0, 512); \
+                            sv_setpvn(LibXML_error, "", 0);
+
+#define LibXML_croak_error() if ( SvCUR( LibXML_error ) > 0 ) { \
+                                 croak(SvPV(LibXML_error, len)); \
+                             } 
+
 /* this should keep the default */
 static xmlExternalEntityLoader LibXML_old_ext_ent_loader = NULL;
 
     SV** item    = NULL;
     SV*  item2   = NULL;
 
-    xmlSetGenericErrorFunc(PerlIO_stderr(), 
-                           (xmlGenericErrorFunc)LibXML_error_handler);
-
     if ( self != NULL ) {
         /* first fetch the values from the hash */
         HV* real_obj = (HV *)SvRV(self);
         SV * RETVAL  = NULL; /* dummy for the stupid macro */
 
+        LibXML_init_error();
+
         item = hv_fetch( real_obj, "XML_LIBXML_VALIDATION", 21, 0 );
         if ( item != NULL && SvTRUE(*item) ) {  
             xmlDoValidityCheckingDefaultValue = 1;
     xmlLoadExtDtdDefaultValue = 5;
     xmlPedanticParserDefaultValue = 0;
     xmlDoValidityCheckingDefaultValue = 0;
-    xmlSetGenericErrorFunc(NULL, NULL);
     xmlSetExternalEntityLoader( (xmlExternalEntityLoader)LibXML_old_ext_ent_loader );
 
 }
 /*        xmlSetExternalEntityLoader( LibXML_old_ext_ent_loader ); */
 /*        LibXML_old_ext_ent_loader = NULL; */
 /*    } */
-/*    xsltSetGenericDebugFunc(NULL, NULL); */
 
 }
 
     char buffer[1024];
     int read_length;
     int ret = -1;
+    int encoding = 0;
     char current_dir[512];
     
     if (directory == NULL) {
     CODE:
         xmlCleanupParser();
 
-int
-XML_ELEMENT_NODE()
-    ALIAS: 
-        XML::LibXML::ELEMENT_NODE = 1
-    CODE:
-        RETVAL = 1;
-    OUTPUT:
-        RETVAL
-        
-int
-XML_ATTRIBUTE_NODE()
-    ALIAS: 
-        XML::LibXML::ATTRIBUTE_NODE = 1
-    CODE:
-        RETVAL = 2;
-    OUTPUT:
-        RETVAL
-
-
-int
-XML_TEXT_NODE()
-    ALIAS: 
-        XML::LibXML::TEXT_NODE = 1
-    CODE:
-        RETVAL = 3;
-    OUTPUT:
-        RETVAL
-
-int
-XML_CDATA_SECTION_NODE()
-    ALIAS: 
-        XML::LibXML::CDATA_SECTION_NODE = 1
-    CODE:
-        RETVAL = 4;
-    OUTPUT:
-        RETVAL
-
-int
-XML_ENTITY_REF_NODE()
-    ALIAS: 
-        XML::LibXML::ENTITY_REFERENCE_NODE = 1
-    CODE:
-        RETVAL = 5;
-    OUTPUT:
-        RETVAL
-
-int
-XML_ENTITY_NODE()
-    ALIAS: 
-        XML::LibXML::ENTITY_NODE = 1
-    CODE:
-        RETVAL = 6;
-    OUTPUT:
-        RETVAL
-
-int
-XML_PI_NODE()
-    ALIAS: 
-        XML::LibXML::PROCESSING_INSTRUCTION_NODE = 1
-    CODE:
-        RETVAL = 7;
-    OUTPUT:
-        RETVAL
-
-int
-XML_COMMENT_NODE()
-    ALIAS: 
-        XML::LibXML::COMMENT_NODE = 1
-    CODE:
-        RETVAL = 8;
-    OUTPUT:
-        RETVAL
-
-int
-XML_DOCUMENT_NODE()
-    ALIAS: 
-        XML::LibXML::DOCUMENT_NODE = 1
-    CODE:
-        RETVAL = 9;
-    OUTPUT:
-        RETVAL
-
-int
-XML_DOCUMENT_TYPE_NODE()
-    ALIAS: 
-        XML::LibXML::DOCUMENT_TYPE_NODE = 1
-    CODE:
-        RETVAL = 10;
-    OUTPUT:
-        RETVAL
-
-int
-XML_DOCUMENT_FRAG_NODE()
-    ALIAS: 
-        XML::LibXML::DOCUMENT_FRAGMENT_NODE = 1
-    CODE:
-        RETVAL = 11;
-    OUTPUT:
-        RETVAL
-
-int
-XML_NOTATION_NODE()
-    ALIAS: 
-        XML::LibXML::NOTATION_NODE = 1
-    CODE:
-        RETVAL = 12;
-    OUTPUT:
-        RETVAL
-
-int
-XML_HTML_DOCUMENT_NODE()
-    ALIAS: 
-        XML::LibXML::HTML_DOCUMENT_NODE = 1
-    CODE:
-        RETVAL = 13;
-    OUTPUT:
-        RETVAL
-
-int
-XML_DTD_NODE()
-    ALIAS:
-        XML::LibXML::DTD_NODE = 1
-    CODE:
-        RETVAL = 14;
-    OUTPUT:
-        RETVAL
-
-int
-XML_ELEMENT_DECL()
-    ALIAS: 
-        XML::LibXML::ELEMENT_DECLARATION = 1
-    CODE:
-        RETVAL = 15;
-    OUTPUT:
-        RETVAL
-
-int
-XML_ATTRIBUTE_DECL()
-    ALIAS: 
-        XML::LibXML::ATTRIBUTE_DECLARATION = 1
-    CODE:
-        RETVAL = 16;
-    OUTPUT:
-        RETVAL
-
-int
-XML_ENTITY_DECL()
-    ALIAS: 
-        XML::LibXML::ENTITY_DECLARATION = 1
-    CODE:
-        RETVAL = 17;
-    OUTPUT:
-        RETVAL
-
-int
-XML_NAMESPACE_DECL()
-    ALIAS: 
-        XML::LibXML::NAMESPACE_DECLARATION = 1
-    CODE:
-        RETVAL = 18;
-    OUTPUT:
-        RETVAL
-
-int
-XML_XINCLUDE_START()
-    ALIAS: 
-        XML::LibXML::XINCLUDE_START = 1
-    CODE:
-        RETVAL = 19;
-    OUTPUT:
-        RETVAL
-
-int
-XML_XINCLUDE_END()
-    ALIAS: 
-        XML::LibXML::XINCLUDE_END = 1
-    CODE:
-        RETVAL = 20;
-    OUTPUT:
-        RETVAL
-
 char *
 get_last_error(CLASS)
         SV * CLASS 
         }
         ctxt->directory = directory;
 
-        # warn( "context created\n");
+        xs_warn( "context created\n");
 
         ctxt->_private = (void*)self;
         
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-        
-        # warn( "context initialized \n");        
+        xs_warn( "context initialized \n");        
         ret = xmlParseDocument(ctxt);
 
-        # warn( "document parsed \n");
+        xs_warn( "document parsed \n");
 
         ctxt->directory = NULL;
 
         sv_2mortal(LibXML_error);
         
         if ( real_dom == NULL ) {
-            if ( SvCUR( LibXML_error ) > 0 ) {
-                croak(SvPV(LibXML_error, len));
-            }
+            LibXML_croak_error();
             XSRETURN_UNDEF;
         }
 
             croak(SvPV(LibXML_error, len));
         }
         else if (xmlDoValidityCheckingDefaultValue
-                 && SvCUR(LibXML_error) > 0
                  && (real_dom->intSubset || real_dom->extSubset) ) {
-            croak(SvPV(LibXML_error, len));
+            LibXML_croak_error();
+        }
+
+        item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 );
+
+        if ( item != NULL && SvTRUE(*item) ) {  
+            RETVAL = PmmNodeToGdomeSv( (xmlNodePtr)real_dom );
         }
         else {
-            item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 );
-
-            if ( item != NULL && SvTRUE(*item) ) {  
-                RETVAL = PmmNodeToGdomeSv( (xmlNodePtr)real_dom );
-            }
-            else {
-                RETVAL = PmmNodeToSv((xmlNodePtr)real_dom, NULL);
-            }
-        }        
+           RETVAL = PmmNodeToSv((xmlNodePtr)real_dom, NULL);
+        }
+
         LibXML_cleanup_callbacks();
         LibXML_cleanup_parser(); 
     OUTPUT:
         SV** item    = NULL;
         int recover = 0;
     CODE:
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-
         LibXML_init_parser(self);
         real_dom = LibXML_parse_stream(self, fh, directory);
         
         recover = ( item != NULL && SvTRUE( *item ) ) ? 1 : 0;
 
         if (real_dom == NULL) {
-            if ( SvCUR( LibXML_error ) > 0 ) {
-                croak(SvPV(LibXML_error, len));
-            }
+            LibXML_croak_error();
             XSRETURN_UNDEF;
         }
         else if (xmlDoValidityCheckingDefaultValue
-                 && SvCUR(LibXML_error) > 0
                  && (real_dom->intSubset || real_dom->extSubset) 
                  && recover == 0 ) {
-            croak(SvPV(LibXML_error, len));
+            LibXML_croak_error();
+        }
+
+        item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 );
+
+        if ( item != NULL && SvTRUE(*item) ) {  
+            RETVAL = PmmNodeToGdomeSv( (xmlNodePtr)real_dom );
         }
         else {
-            item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 );
-
-            if ( item != NULL && SvTRUE(*item) ) {  
-                RETVAL = PmmNodeToGdomeSv( (xmlNodePtr)real_dom );
-            }
-            else {
-                RETVAL = PmmNodeToSv((xmlNodePtr)real_dom, NULL);
-            }
-        }
+            RETVAL = PmmNodeToSv((xmlNodePtr)real_dom, NULL);
+        }
+
         LibXML_cleanup_callbacks();
         LibXML_cleanup_parser();
     OUTPUT:
         SV * fh
         char * directory
     PREINIT:
-    CODE:  warn $@;
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-
+    CODE:  
         LibXML_init_parser(self);
         LibXML_parse_sax_stream(self, fh, directory);
         
         }
         ctxt->_private = (void*)self;
         
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-
         xmlParseDocument(ctxt);
 
         well_formed = ctxt->wellFormed;
         sv_2mortal(LibXML_error);
         
         if ( real_dom == NULL ) {
-            if ( SvCUR( LibXML_error ) > 0 ) {
-                croak(SvPV(LibXML_error, len));
-            }
+            LibXML_croak_error();
             XSRETURN_UNDEF;
         }
 
         ctxt->sax = PSaxGetHandler();
         PmmSAXInitContext( ctxt, self );
         
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-
         xmlParseDocument(ctxt);
 
         xmlFree(ctxt->sax);
         if (len == 0) {
             croak("Empty string");
         }
-        
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-        
+                
         LibXML_init_parser(self);
         real_dom = htmlParseDoc((xmlChar*)ptr, NULL);
         LibXML_cleanup_callbacks();
         sv_2mortal(LibXML_error);
         
         if (!real_dom) {
-            if ( SvCUR( LibXML_error ) > 0 ) {
-                croak(SvPV(LibXML_error, len));
-            }
+            LibXML_croak_error();
             XSRETURN_UNDEF;
         }
         else {
         xmlDocPtr real_dom;
         HV* real_obj = (HV *)SvRV(self);
         SV** item    = NULL;
-    CODE:
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-        
+    CODE:        
         LibXML_init_parser(self);
         real_dom = LibXML_parse_html_stream(self, fh);
         LibXML_cleanup_callbacks();
         
         sv_2mortal(LibXML_error);
         
-        if (!real_dom || ((*SvPV(LibXML_error, len)) != '\0')) {
-            RETVAL = &PL_sv_undef;    
-            croak(SvPV(LibXML_error, len));
+        LibXML_croak_error();
+
+        if (real_dom == NULL ) {
+            croak("something went wrong");
         }
         else {
             STRLEN n_a;
         HV* real_obj = (HV *)SvRV(self);
         SV** item    = NULL;
     CODE:
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-        
         LibXML_init_parser(self);
         real_dom = htmlParseFile((char*)filename, NULL);
         LibXML_cleanup_callbacks();
         LibXML_cleanup_parser();
 
         sv_2mortal(LibXML_error);
-        
+
+        LibXML_croak_error();        
+
         if (!real_dom) {
-            if ( SvCUR( LibXML_error ) > 0 ) {
-                croak(SvPV(LibXML_error, len));
-            }
-            XSRETURN_UNDEF;
+            croak( "no document parsed!" );
+        }
+
+        item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 );
+
+        if ( item != NULL && SvTRUE(*item) ) {  
+            RETVAL = PmmNodeToGdomeSv( (xmlNodePtr)real_dom );
         }
         else {
-            item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 );
-
-            if ( item != NULL && SvTRUE(*item) ) {  
-                RETVAL = PmmNodeToGdomeSv( (xmlNodePtr)real_dom );
-            }
-            else {
-                RETVAL = PmmNodeToSv((xmlNodePtr)real_dom, NULL);
-            }
+            RETVAL = PmmNodeToSv((xmlNodePtr)real_dom, NULL);
         }
     OUTPUT:
         RETVAL
         xmlDocPtr real_dom;
         HV* real_obj = (HV *)SvRV(self);
         SV** item    = NULL;
+        STRLEN n_a;
+        SV * newURI;
     CODE:
         LibXML_error = NEWSV(0, 512);
         sv_setpvn(LibXML_error, "", 0);
         LibXML_cleanup_parser();
         
         sv_2mortal(LibXML_error);
+
+        LibXML_croak_error();
         
-        if (!real_dom || ((*SvPV(LibXML_error, len)) != '\0')) {
-            RETVAL = &PL_sv_undef;    
-            croak(SvPV(LibXML_error, len));
+        if (real_dom == NULL) {
+            croak("no document parsed!");
+        }
+
+        newURI = newSVpvf("unknown-%12.12d", real_dom);
+        real_dom->URL = xmlStrdup((const xmlChar*)SvPV(newURI, n_a));
+        SvREFCNT_dec(newURI);
+        item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 );
+
+        if ( item != NULL && SvTRUE(*item) ) {  
+            RETVAL = PmmNodeToGdomeSv( (xmlNodePtr)real_dom );
         }
         else {
-            STRLEN n_a;
-            SV * newURI = newSVpvf("unknown-%12.12d", real_dom);
-            real_dom->URL = xmlStrdup((const xmlChar*)SvPV(newURI, n_a));
-            SvREFCNT_dec(newURI);
-            item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 );
-
-            if ( item != NULL && SvTRUE(*item) ) {  
-                RETVAL = PmmNodeToGdomeSv( (xmlNodePtr)real_dom );
-            }
-            else {
-                RETVAL = PmmNodeToSv((xmlNodePtr)real_dom, NULL);
-            }
+            RETVAL = PmmNodeToSv((xmlNodePtr)real_dom, NULL);
         }
     OUTPUT:
         RETVAL
         xmlDocPtr real_dom;
         HV* real_obj = (HV *)SvRV(self);
         SV** item    = NULL;
+        STRLEN n_a;
+        SV * newURI;
     CODE:
         ptr = SvPV(string, len);
         if (len == 0) {
             croak("Empty string");
         }
         
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-        
         LibXML_init_parser(self);
         real_dom = (xmlDocPtr) docbParseDoc((xmlChar*)ptr,
                                             Sv2C(encoding, NULL));
         LibXML_cleanup_parser();        
 
         sv_2mortal(LibXML_error);
+
+        LibXML_croak_error();
         
         if (!real_dom) {
-            if ( SvCUR( LibXML_error ) > 0 ) {
-                croak(SvPV(LibXML_error, len));
-            }
+            croak("no document parsed!");
             XSRETURN_UNDEF;
         }
+
+        newURI = newSVpvf("unknown-%12.12d", real_dom);
+        real_dom->URL = xmlStrdup((const xmlChar*)SvPV(newURI, n_a));
+        SvREFCNT_dec(newURI);
+
+        item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 );            
+        if ( item != NULL && SvTRUE(*item) ) {  
+            RETVAL = PmmNodeToGdomeSv( (xmlNodePtr)real_dom );
+        }
         else {
-            STRLEN n_a;
-            SV * newURI = newSVpvf("unknown-%12.12d", real_dom);
-            real_dom->URL = xmlStrdup((const xmlChar*)SvPV(newURI, n_a));
-            SvREFCNT_dec(newURI);
-
-            item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 );            
-            if ( item != NULL && SvTRUE(*item) ) {  
-                RETVAL = PmmNodeToGdomeSv( (xmlNodePtr)real_dom );
-            }
-            else {
-                RETVAL = PmmNodeToSv((xmlNodePtr)real_dom, NULL);
-            }
+            RETVAL = PmmNodeToSv((xmlNodePtr)real_dom, NULL);
         }
     OUTPUT:
         RETVAL
         HV* real_obj = (HV *)SvRV(self);
         SV** item    = NULL;
     CODE:
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-        
         LibXML_init_parser(self);
         real_dom = (xmlDocPtr) docbParseFile(filename,
                                              Sv2C(encoding, NULL));
 
         sv_2mortal(LibXML_error);
         
+        LibXML_croak_error();
+
         if (!real_dom) {
-            if ( SvCUR( LibXML_error ) > 0 ) {
-                croak(SvPV(LibXML_error, len));
-            }
+            croak( "no document parsed!" );
             XSRETURN_UNDEF;
         }
         else {
 
         ctxt->sax = PSaxGetHandler();
         PmmSAXInitContext( ctxt, self );
-        
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
 
         docbParseDocument(ctxt);
 
         if ( chunk != NULL ) {
             item = hv_fetch( real_obj, "XML_LIBXML_RECOVER", 18, 0 );
             recover = ( item != NULL && SvTRUE(*item) ) ? 1 : 0;
-           
-            LibXML_error = sv_2mortal(newSVpv("", 0));
 
             LibXML_init_parser(self);
             rv = domReadWellBalancedString( NULL, chunk, recover );
             LibXML_cleanup_callbacks();
             LibXML_cleanup_parser();    
 
+            sv_2mortal(LibXML_error);
+            LibXML_croak_error();
+
             if ( rv != NULL ) {
                 /* now we append the nodelist to a document
                    fragment which is unbound to a Document!!!! */
                 }
             }
             else {
-                xs_warn( "bad chunk" );
-                croak(SvPV(LibXML_error, len));
-                XSRETURN_UNDEF;
+                croak("bad chunk");
             }
             /* free the chunk we created */
             xmlFree( chunk );
             PmmSAXInitContext( ctxt, self );         
             ctxt->sax = PSaxGetHandler();
 
-            LibXML_error = sv_2mortal(newSVpv("", 0));
-
             LibXML_init_parser(self);
             handler = PSaxGetHandler();
 
             LibXML_cleanup_parser();    
             xmlFree( chunk );
 
+
             if ( retCode == -1 ) {
-                croak(SvPV(LibXML_error, len)); 
+                LibXML_croak_error();
             }
         }
 
         if ( real_dom == NULL ) {
             croak("No document to process!");
         }
-        LibXML_error = sv_2mortal(newSVpv("", 0));
-
         LibXML_init_parser(self);
         RETVAL = xmlXIncludeProcess(real_dom);        
         LibXML_cleanup_callbacks();
         LibXML_cleanup_parser();
-
-        LibXML_ERROR_MSG = SvPV(LibXML_error, len );
     
         if ( len > 0 ){
-                croak(LibXML_ERROR_MSG);
-                XSRETURN_UNDEF;            
+            LibXML_croak_error();
+            XSRETURN_UNDEF;            
         }
         else {
             RETVAL = 1;
         RETVAL
 
 SV*
-encodeToUTF8( encoding, string )
-        const char * encoding
-        SV * string
-    PREINIT:
-        xmlChar * realstring;
-        xmlChar * tstr;
-    CODE:
-        xs_warn( "encoding start" );
-        realstring = Sv2C(string,(xmlChar*) encoding);
-        if ( realstring != NULL ) {
-            RETVAL = C2Sv(realstring, NULL);
-            xmlFree( realstring );
-#ifdef HAVE_UTF8
-            SvUTF8_on(RETVAL);
-#endif
-        }
-        else {
-            XSRETURN_UNDEF;
-        }
-        xs_warn( "encoding done" );
-    OUTPUT:
-        RETVAL
-
-SV*
-decodeFromUTF8( encoding, string ) 
-        const char * encoding
-        SV* string
-    PREINIT:
-        xmlChar * tstr;
-        xmlChar * realstring;
-    CODE: 
-        xs_warn( "decoding start" );
-#ifdef HAVE_UTF8
-        if ( SvUTF8(string) ) {
-#endif
-            realstring = Sv2C(string,(const xmlChar*)"UTF8" );
-            if ( realstring != NULL ) {
-                tstr =  (xmlChar*)PmmDecodeString( (const char*)encoding,
-                                                   (const xmlChar*)realstring );
-                if ( tstr != NULL ) {
-                    RETVAL = C2Sv((const xmlChar*)tstr,(const xmlChar*)encoding);
-                    xmlFree( tstr );
-                }
-                else {
-                    XSRETURN_UNDEF;
-                }
-                xmlFree( realstring ); 
-            }
-            else {
-                XSRETURN_UNDEF;
-            }
-#ifdef HAVE_UTF8
-        }
-        else {
-            XSRETURN_UNDEF;
-        }
-#endif
-        xs_warn( "decoding done" );
-    OUTPUT:
-        RETVAL
-
-SV*
 _start_push( self, with_sax=0 ) 
         SV * self
         int with_sax
         xmlParserCtxtPtr ctxt = NULL;
     CODE:
         /* create empty context */
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-
         if ( with_sax == 1 ) {
             ctxt = xmlCreatePushParserCtxt( PSaxGetHandler(),
                                             NULL,
             XSRETURN_UNDEF;
         }
 
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-
         LibXML_init_parser(self);
         xmlParseChunk(ctxt, chunk, len, 0);
 
     CODE:
         PmmNODE( SvPROXYNODE( pctxt ) ) = NULL;
 
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-
         LibXML_init_parser(self);
         xmlParseChunk(ctxt, "", 0, 1); /* finish the parse */
         LibXML_cleanup_callbacks();
 
         if ( ctxt->node != NULL && restore == 0 ) {
             xmlFreeParserCtxt(ctxt);
-            croak( "document is not wellformed" );
+            LibXML_croak_error();
         }
 
         doc = ctxt->myDoc;
     CODE:
         PmmNODE( SvPROXYNODE( pctxt ) ) = NULL;
 
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-
         LibXML_init_parser(self);
         xmlParseChunk(ctxt, "", 0, 1); /* finish the parse */
         LibXML_cleanup_callbacks();
                 xmlUnlinkNode( (xmlNodePtr)intSubset );
         }
 
+        LibXML_init_error();
+
         if ( format <= 0 ) {
-            # warn( "use no formated toString!" );
+            xs_warn( "use no formated toString!" );
             xmlDocDumpMemory(real_dom, &result, &len);
         }
         else {
             int t_indent_var = xmlIndentTreeOutput;
-            # warn( "use formated toString!" );
+            xs_warn( "use formated toString!" );
             xmlIndentTreeOutput = 1;
             xmlDocDumpFormatMemory( real_dom, &result, &len, format ); 
             xmlIndentTreeOutput = t_indent_var;
 
         xmlSaveNoEmptyTags = oldTagFlag;
 
+        sv_2mortal( LibXML_error );
+        LibXML_croak_error();
+
     	if (result == NULL) {
-	        # warn("Failed to convert doc to string");           
+	        xs_warn("Failed to convert doc to string");           
             XSRETURN_UNDEF;
     	} else {
-            # warn("%s, %d\n",result, len);
+            /* warn("%s, %d\n",result, len); */
             RETVAL = C2Sv( result, real_dom->encoding );
             xmlFree(result);
         }
             xmlIndentTreeOutput = 1;
         }
 
+        LibXML_init_error();
+
         RETVAL = xmlSaveFormatFileTo( buffer, 
                                       doc,
                                       encoding,
     
         xmlIndentTreeOutput = t_indent_var;
         xmlSaveNoEmptyTags = oldTagFlag;
+        sv_2mortal( LibXML_error );
+        LibXML_croak_error();
     OUTPUT:
         RETVAL    
 
             xmlSaveNoEmptyTags = SvTRUE(internalFlag);
         }
 
+        LibXML_init_error();
+
         if ( format <= 0 ) {
             xs_warn( "use no formated toFile!" );
             RETVAL = xmlSaveFile( filename, (xmlDocPtr)PmmSvNode(self) );
         }
 
         xmlSaveNoEmptyTags = oldTagFlag;   
+
+        sv_2mortal( LibXML_error );
+        LibXML_croak_error();
+
         if ( RETVAL > 0 ) 
             RETVAL = 1;
         else 
         int len=0;
     CODE:
         real_dom = (xmlDocPtr)PmmNODE(SvPROXYNODE(self));
-        # warn( "use no formated toString!" );
+        xs_warn( "use no formated toString!" );
+
+        LibXML_init_error();
         htmlDocDumpMemory(real_dom, &result, &len);
 
+        sv_2mortal( LibXML_error );
+        LibXML_croak_error();
+
     	if (result == NULL) {
             XSRETURN_UNDEF;
       	} else {
-            # warn("%s, %d\n",result, len);
+            /* warn("%s, %d\n",result, len); */
             RETVAL = newSVpvn((char *)result, (STRLEN)len);
             xmlFree(result);
         }
         xmlNodePtr newNode;
         xmlDocPtr real_doc;
         xmlChar * elname = NULL;
-        ProxyNodePtr docfrag = NULL;
     CODE:
         STRLEN len;
         real_doc = (xmlDocPtr)PmmSvNode(dom);
-        docfrag = PmmNewFragment( real_doc );
        
         elname = nodeSv2C( name , (xmlNodePtr) real_doc );
         if ( elname != NULL || xmlStrlen(elname) > 0 ) {
             xmlFree(elname);
             if ( newNode != NULL ) {        
                 newNode->doc = real_doc;
-                domAppendChild( PmmNODE(docfrag), newNode );
                 xs_warn( newNode->name );
-                RETVAL = PmmNodeToSv(newNode,docfrag);
+                RETVAL = PmmNodeToSv(newNode,NULL);
             }
             else {
                 xs_warn( "no node created!" );
         const xmlChar * pchar  = NULL;
         xmlNsPtr ns            = NULL;
         xmlDocPtr doc          = NULL;
-        ProxyNodePtr docfrag   = NULL;
         xmlNodePtr newNode     = NULL;
     CODE:
         doc = (xmlDocPtr)PmmSvNode( pdoc );
 
         xmlSetNs(newNode, ns);
 
-        docfrag = PmmNewFragment( doc );
-        domAppendChild( PmmNODE(docfrag), newNode );
-        RETVAL = PmmNodeToSv(newNode, docfrag);
+        RETVAL = PmmNodeToSv(newNode,NULL);
     
         if ( prefix != NULL ) {
             xmlFree(prefix);
         xmlNodePtr newNode;
         xmlDocPtr real_doc;
         xmlChar * elname = NULL;
-        ProxyNodePtr docfrag = NULL;
     CODE:
         STRLEN len;
         real_doc = (xmlDocPtr)PmmSvNode(doc);
-        docfrag = PmmNewFragment( real_doc );
        
         elname = nodeSv2C( content , (xmlNodePtr) real_doc );
         if ( elname != NULL || xmlStrlen(elname) > 0 ) {
             xmlFree(elname);
             if ( newNode != NULL ) {        
                 newNode->doc = real_doc;
-                domAppendChild( PmmNODE(docfrag), newNode );
-                xs_warn( newNode->name );
-                RETVAL = PmmNodeToSv(newNode,docfrag);
+                RETVAL = PmmNodeToSv(newNode,NULL);
             }
             else {
                 xs_warn( "no node created!" );
         xmlNodePtr newNode;
         xmlDocPtr real_doc;
         xmlChar * elname = NULL;
-        ProxyNodePtr docfrag = NULL;
     CODE:
         STRLEN len;
         real_doc = (xmlDocPtr)PmmSvNode(doc);
-        docfrag = PmmNewFragment( real_doc );
        
         elname = nodeSv2C( content , (xmlNodePtr) real_doc );
         if ( elname != NULL || xmlStrlen(elname) > 0 ) {
             xmlFree(elname);
             if ( newNode != NULL ) {        
                 newNode->doc = real_doc;
-                domAppendChild( PmmNODE(docfrag), newNode );
-                xs_warn( newNode->name );
-                RETVAL = PmmNodeToSv(newNode,docfrag);
+                RETVAL = PmmNodeToSv(newNode,NULL);
             }
             else {
                 xs_warn( "no node created!" );
         xmlNodePtr newNode;
         xmlDocPtr real_doc;
         xmlChar * elname = NULL;
-        ProxyNodePtr docfrag = NULL;
     CODE:
         real_doc = (xmlDocPtr)PmmSvNode(doc);
-        docfrag = PmmNewFragment( real_doc );
        
         elname = nodeSv2C( content , (xmlNodePtr) real_doc );
         if ( elname != NULL || xmlStrlen(elname) > 0 ) {
             xmlFree(elname);
             if ( newNode != NULL ) {        
                 newNode->doc = real_doc;
-                domAppendChild( PmmNODE(docfrag), newNode );
-                xs_warn( newNode->name );
-                RETVAL = PmmNodeToSv(newNode,docfrag);
+                RETVAL = PmmNodeToSv( newNode, NULL );
             }
             else {
                 xs_warn( "no node created!" );
         xmlNodePtr newNode;
         xmlDocPtr doc = (xmlDocPtr)PmmSvNode(pdoc);
         xmlChar * name = Sv2C( pname, NULL );
-        ProxyNodePtr docfrag = NULL;        
     CODE:
         if ( name == NULL ) {
             XSRETURN_UNDEF;
         if ( newNode == NULL ) {
             XSRETURN_UNDEF;
         }
-        docfrag = PmmNewFragment( doc );
-        domAppendChild( PmmNODE(docfrag), newNode );
-        RETVAL = PmmNodeToSv( newNode, docfrag );
+        RETVAL = PmmNodeToSv( newNode, NULL );
     OUTPUT:
         RETVAL
 
         v = nodeSv2C(value, (xmlNodePtr)doc);
         PI = xmlNewPI(n,v);      
         PI->doc = doc;
-        RETVAL = PmmNodeToSv(PI, SvPROXYNODE(self));
+        /* RETVAL = PmmNodeToSv(PI, SvPROXYNODE(self)); */
+        RETVAL = PmmNodeToSv(PI, NULL);
         xmlFree(v);
         xmlFree(n);
     OUTPUT:
     CODE:
         xs_warn( "GET OWNERDOC\n" );
         if( self != NULL
-            && self->doc != NULL
-            && PmmSvOwner(elem) != NULL ){
+            && self->doc != NULL ){
             RETVAL = PmmNodeToSv((xmlNodePtr)(self->doc), NULL);
         }
         else {
         SV* newChild
         SV* oldChild
     PREINIT:
-        ProxyNodePtr docfrag;
         xmlNodePtr pNode, nNode, oNode;
         xmlNodePtr ret;
     CODE:
             }
             else {
                 /* create document fragment */
-                docfrag = PmmNewFragment( pNode->doc );
-                domAppendChild( PmmNODE(docfrag), ret );
-
                 RETVAL = PmmNodeToSv(ret, NULL);
                 if ( nNode->_private != NULL ) {
                     PmmFixOwner( SvPROXYNODE(newChild),
                                  PmmOWNERPO(SvPROXYNODE(paren)) );
                 }
-                PmmFixOwner( SvPROXYNODE(RETVAL),
-                             docfrag );
+                PmmFixOwner( SvPROXYNODE(RETVAL), NULL );
             }
         }
     OUTPUT:
         }
         ret = xmlReplaceNode( node, other );
         if ( ret ) {
-            ProxyNodePtr docfrag = PmmNewFragment( node->doc );
-            domAppendChild( PmmNODE(docfrag), ret );
-            RETVAL = PmmNodeToSv(ret,docfrag);
+            RETVAL = PmmNodeToSv(ret,NULL);
             if ( other->_private != NULL ) {
                 PmmFixOwner( SvPROXYNODE(newNode),
                              PmmOWNERPO(SvPROXYNODE(self)));
             }
-            PmmFixOwner( SvPROXYNODE(RETVAL), docfrag );
+            PmmFixOwner( SvPROXYNODE(RETVAL), NULL );
         }
         else {
             XSRETURN_UNDEF;
         SV* child
     PREINIT:
         xmlNodePtr paren, ret;
-        ProxyNodePtr docfrag;
     CODE:
         if ( pparen == NULL
              || pparen == &PL_sv_undef
                 XSRETURN_UNDEF;
             }
             else {
-                docfrag = PmmNewFragment(paren->doc );
-                domAppendChild( PmmNODE(docfrag), ret );
-                RETVAL = PmmNodeToSv(ret,docfrag);
-                PmmFixOwner( SvPROXYNODE(RETVAL), docfrag );
+                RETVAL = PmmNodeToSv(ret,NULL);
+                PmmFixOwner( SvPROXYNODE(RETVAL), NULL );
             }
         }
     OUTPUT:
     CODE:
         if ( elem->type != XML_DOCUMENT_NODE
              || elem->type != XML_DOCUMENT_FRAG_NODE ) {
-            if ( elem->type != XML_ATTRIBUTE_NODE ) {
-                if ( elem->doc != NULL ) 
-                    dfProxy = PmmNewFragment(elem->doc);
-                else 
-                    dfProxy = PmmNewFragment(NULL);
-            }
             xmlUnlinkNode( elem );
-            if ( elem->type != XML_ATTRIBUTE_NODE ) {
-                domAppendChild( PmmNODE(dfProxy), elem );
-            }
-            PmmFixOwner( SvPROXYNODE(proxyelem), dfProxy );
+            PmmFixOwner( SvPROXYNODE(proxyelem), NULL );
         }
 
 SV*
     PREINIT:
         xmlNodePtr ret, node;
         xmlDocPtr doc;
-        ProxyNodePtr docfrag = NULL;
     CODE:
         node = PmmSvNode( self );
         ret = PmmCloneNode( node, deep );
             if ( doc != NULL ) {
                 xmlSetTreeDoc(ret, doc);
             }
-
+            
             # make namespaces available
             ret->ns = node->ns;
 
-            xmlReconciliateNs(ret->doc, ret);     
-
-            docfrag = PmmNewFragment( ret->doc );
-            domAppendChild( PmmNODE(docfrag), ret );            
-            
-            RETVAL = PmmNodeToSv(ret, docfrag);
+            /* xmlReconciliateNs(ret->doc, ret); */
+
+            RETVAL = PmmNodeToSv(ret, NULL);
         }   
     OUTPUT:
         RETVAL
             xmlFree( ret );
         }
         else {
-	        # warn("Failed to convert doc to string");           
+	        xs_warn("Failed to convert doc to string");           
             XSRETURN_UNDEF;
         }
     OUTPUT:
             domNodeNormalize( PmmOWNER(SvPROXYNODE(pnode)) );
         }
 
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-        xmlSetGenericErrorFunc(PerlIO_stderr(), 
-                               (xmlGenericErrorFunc)LibXML_error_handler);
+        LibXML_init_error();
 
         found = domXPathFind( node, xpath );
         xmlFree( xpath );
 
-        xmlSetGenericErrorFunc(NULL, NULL);
-        
         sv_2mortal( LibXML_error );
-
-        if ( SvCUR( LibXML_error ) > 0 ) {
-            croak(SvPV(LibXML_error, len));
-        }
+        LibXML_croak_error();
 
         if (found) {
             switch (found->type) {
             xmlXPathFreeObject(found);
         }
         else {
-            if ( SvCUR( LibXML_error ) > 0 ) {
-                croak(SvPV(LibXML_error, len));
-            }
+            LibXML_croak_error();
         }
 
 void
             domNodeNormalize( PmmOWNER(SvPROXYNODE(pnode)) );
         }
 
-        LibXML_error = NEWSV(0, 512);
-        sv_setpvn(LibXML_error, "", 0);
-        xmlSetGenericErrorFunc(PerlIO_stderr(), 
-                               (xmlGenericErrorFunc)LibXML_error_handler);
+        LibXML_init_error();
 
         nodelist = domXPathSelect( node, xpath );
         xmlFree(xpath);
-        xmlSetGenericErrorFunc(NULL, NULL);
 
         sv_2mortal( LibXML_error );
-
-        if ( SvCUR( LibXML_error ) > 0 ) {
-            croak(SvPV(LibXML_error, len));
-        }
+        LibXML_croak_error();
 
         if ( nodelist ) {
             if ( nodelist->nodeNr > 0 ) {
             xmlXPathFreeNodeSet( nodelist );
         }
         else {
-            if ( SvCUR( LibXML_error ) > 0 ) {
-                croak(SvPV(LibXML_error, len));
-            }
+            LibXML_croak_error();
         }
 
 void
         xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
         char * new_string;
     CODE:
-        LibXML_error = sv_2mortal(newSVpv("", 0));
+        LibXML_init_error();
         if (items > 2) {
             encoding_sv = ST(2);
             if (items > 3) {
         /* NOTE: For some reason freeing this InputBuffer causes a segfault! */
         /* xmlFreeParserInputBuffer(buffer); */
         xmlFree(new_string);
-        if (res != NULL) {
-            RETVAL = PmmNodeToSv((xmlNodePtr)res, NULL);
-        }
-        else {
-            croak("couldn't parse DTD: %s", SvPV(LibXML_error, n_a));
-        }
+
+        sv_2mortal( LibXML_error );
+        LibXML_croak_error();
+
+        if (res == NULL) {
+            croak("no DTD parsed!");
+        }
+        RETVAL = PmmNodeToSv((xmlNodePtr)res, NULL);
     OUTPUT:
         RETVAL
 /* $Id$ */
 #include <libxml/tree.h>
 #include <libxml/encoding.h>
+#include <libxml/xmlerror.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/parser.h>
 #include <libxml/xmlIO.h>
 domIsParent( xmlNodePtr cur, xmlNodePtr ref ) {
     xmlNodePtr helper = NULL;
 
-    if ( cur == NULL || ref == NULL ) 
+    if ( cur == NULL
+         || ref == NULL
+         || cur->doc != ref->doc
+         || ref->children == NULL
+         || cur->parent == (xmlNodePtr)cur->doc
+         || cur->parent == NULL ) {
         return 0;
+    }
 
-    if( cur->doc != ref->doc)
-        return 0;
-
-    if( ref->type == XML_DOCUMENT_NODE )
+    if( ref->type == XML_DOCUMENT_NODE ) {
         return 1;
+    }
 
     helper= cur;
-    while ( helper && (xmlDocPtr) helper != ref->doc ) {
-        if( helper == ref )
+    while ( helper && (xmlDocPtr) helper != cur->doc ) {
+        if( helper == ref ) {
             return 1;
+        }
         helper = helper->parent;
     }
 
 int
 domTestHierarchy(xmlNodePtr cur, xmlNodePtr ref) 
 {
-    if ( !ref || !cur )
+    if ( !ref || !cur || cur->type == XML_ATTRIBUTE_NODE ) {
         return 0;
-    
+    }
+
     switch ( ref->type ){
     case XML_ATTRIBUTE_NODE:
     case XML_DOCUMENT_NODE:
         return 0;
         break;
-    case XML_DOCUMENT_FRAG_NODE:
-	if ( ref->children == NULL )
-            return 0;
-	break;
     default:
         break;
     }
     
-    if ( cur->type == XML_ATTRIBUTE_NODE )
+    if ( domIsParent( cur, ref ) ) {
         return 0;
-
-    if ( domIsParent( cur, ref ) )
-	return 0;
+    }
 
     return 1;
 }
         case XML_ELEMENT_NODE:
         case XML_ENTITY_NODE:
         case XML_ENTITY_REF_NODE:
-	case XML_TEXT_NODE:
-	case XML_CDATA_SECTION_NODE:
-	case XML_NAMESPACE_DECL:
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_NAMESPACE_DECL:
             return 0;
             break;
         default:
 
 void
 domUnlinkNode( xmlNodePtr node ) {
-    if ( node == NULL ) {
+    if ( node == NULL
+         || ( node->prev      == NULL
+              && node->next   == NULL
+              && node->parent == NULL ) ) {
         return;
     }
 
     if ( !(domTestHierarchy(self, newChild)
            && domTestDocument(self, newChild))){
         xs_warn("HIERARCHIY_REQUEST_ERR\n"); 
+        xmlGenericError(xmlGenericErrorContext,"HIERARCHIY_REQUEST_ERR\n");
         return NULL;
     }
 
     }
     else {
         xs_warn("WRONG_DOCUMENT_ERR - non conform implementation\n"); 
+        /* xmlGenericError(xmlGenericErrorContext,"WRONG_DOCUMENT_ERR\n"); */
         newChild= domImportNode( self->doc, newChild, 1 );
     }
  
     if ( self->children != NULL ) {
-        xs_warn("unlink node!\n");
         domAddNodeToList( newChild, self->last, NULL );
     }
     else if (newChild->type == XML_DOCUMENT_FRAG_NODE ) {
         newChild->parent= self;
     }
  
-    xmlReconciliateNs(self->doc, newChild);     
+    // xmlReconciliateNs(self->doc, newChild);     
 
     return newChild;
 }
     if ( !(domTestHierarchy(self, new)
            && domTestDocument(self, new))){
         xs_warn("HIERARCHIY_REQUEST_ERR\n"); 
+        xmlGenericError(xmlGenericErrorContext,"HIERARCHIY_REQUEST_ERR\n");
         return NULL;
     }
     
        || (  newChild->type     == XML_DOCUMENT_FRAG_NODE 
           && newChild->children == NULL ) ) {
         /* NOT_FOUND_ERR */
+        xmlGenericError(xmlGenericErrorContext,"NOT_FOUND_ERR\n");
         return NULL;
     }
 
     if ( !(domTestHierarchy( self, newChild )
            && domTestDocument( self, newChild ))) {
+        xmlGenericError(xmlGenericErrorContext,"HIERARCHIY_REQUEST_ERR\n");
         return NULL;
     }
 
     }
     
     domAddNodeToList(newChild, refChild->prev, refChild);
-    xmlReconciliateNs(self->doc, newChild);     
+    // xmlReconciliateNs(self->doc, newChild);     
 
     return newChild;
 }
     if ( refChild->parent != self
        || (  newChild->type     == XML_DOCUMENT_FRAG_NODE 
           && newChild->children == NULL ) ) {
-        /* NOT_FOUND_ERR */
+        xmlGenericError(xmlGenericErrorContext,"NOT_FOUND_ERR\n");
         return NULL;
     }
 
     if ( !(domTestHierarchy( self, newChild )
            && domTestDocument( self, newChild ))) {
+        xmlGenericError(xmlGenericErrorContext,"HIERARCHIY_REQUEST_ERR\n");
         return NULL;
     }
 
     }
 
     domAddNodeToList(newChild, refChild, refChild->next);
-    xmlReconciliateNs(self->doc, newChild);     
+    // xmlReconciliateNs(self->doc, newChild);     
 
     return newChild;
 }
          * wrong node type
          * new node is parent of itself
          */
+        xmlGenericError(xmlGenericErrorContext,"HIERARCHIY_REQUEST_ERR\n");
         return NULL;
     }
         
         domAddNodeToList( newNode, prev,  next );
     }
 
-    xmlReconciliateNs(newNode->doc, newNode); 
+    // xmlReconciliateNs(newNode->doc, newNode); 
 
     return oldNode;
 }
          *   - same attribute names
          *   - and the attribute carrying that namespace
          *         or
-         
-         SJT: This following condition is wrong IMHO; I reported it as a bug on libxml2
-         
-         *         no namespace on the attribute and the element carrying it
+         *   - no namespace on the attribute and the element carrying it
          */
         if ((xmlStrEqual(prop->name, name)) &&
             (/* ((prop->ns == NULL) && (node->ns != NULL) &&
  * @owner: libxml defines only the document, but not the node owner
  *         (in case of document fragments, they are not the same!)
  * @count: this is the internal reference count!
+ * @encoding: this value is missing in libxml2's doc structure
  *
  * Since XML::LibXML will not know, is a certain node is already
  * defined in the perl layer, it can't shurely tell when a node can be
     xmlNodePtr node;
     xmlNodePtr owner;
     int count;
+    int encoding; 
 };
 
 /* helper type for the proxy structure */
 #define PmmOWNER(node)       node->owner
 #define PmmOWNERPO(node)     ((node && PmmOWNER(node)) ? (ProxyNodePtr)PmmOWNER(node)->_private : node)
 
+#define PmmENCODING(node)    node->encoding
+#define PmmNodeEncoding(node) ((ProxyNodePtr)(node->_private))->encoding
+
 /* creates a new proxy node from a given node. this function is aware
  * about the fact that a node may already has a proxy structure.
  */
 
         retval = NEWSV(0,0);
         sv_setref_pv( retval, CLASS, (void*)dfProxy );
-        PmmREFCNT_inc(dfProxy);            
+        PmmREFCNT_inc(dfProxy); 
+
+        switch ( node->type ) {
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+        case XML_DOCB_DOCUMENT_NODE:
+            dfProxy->encoding = (int)xmlParseCharEncoding( ((xmlDocPtr)node)->encoding );
+            break;
+        default:
+            break;
+        }
     }
     else {
         xs_warn( "no node found!" );
     xmlBufferPtr in = NULL, out = NULL;
 
     if ( charset == 1 ) {
-        xs_warn("use UTF8 for encoding ...");
+        /* warn("use UTF8 for encoding ... %s ", string); */
         return xmlStrdup( string );
     }
 
         xmlDocPtr real_doc = refnode->doc;
         if ( real_doc && real_doc->encoding != NULL ) {
 
-            xmlChar * decoded = PmmFastDecodeString( (int)real_doc->charset ,
+            xmlChar * decoded = PmmFastDecodeString( PmmNodeEncoding(real_doc) ,
                                                      (const xmlChar *)string,
                                                      (const xmlChar*)real_doc->encoding);
             len = xmlStrlen( decoded );
                     if ( real_dom->encoding != NULL ) {        
 #endif
                         xs_warn( "domEncodeString!" );
-                        ts= PmmFastEncodeString( real_dom->charset,
+                        ts= PmmFastEncodeString( PmmNodeEncoding(real_dom),
                                                  string,
                                                  (const xmlChar*)real_dom->encoding );
                         xs_warn( "done!" );
     xmlNodePtr node;
     xmlNodePtr owner;
     int count;
+    int encoding;
 };
 
 /* helper type for the proxy structure */
 #define PmmNODE(xnode)       xnode->node
 #define PmmOWNER(node)       node->owner
 #define PmmOWNERPO(node)     ((node && PmmOWNER(node)) ? (ProxyNodePtr)PmmOWNER(node)->_private : node)
-
+#define PmmENCODING(node)    node->encoding
 
 ProxyNodePtr
 PmmNewNode(xmlNodePtr node);
 
 BEGIN { plan tests => 42 };
 use XML::LibXML;
+use XML::LibXML::Common qw(:libxml);
 
 ##
 # test values
 use Test;
 use strict;
 
-BEGIN { plan tests => 67 };
+BEGIN { plan tests => 78 };
 use XML::LibXML;
+use XML::LibXML::Common qw(:libxml);
 
 {
     print "# 1. Document Attributes\n";
 }
 
 {
-    print "# 4. Document Storing\n";
+    print "# 4. Document Storeing\n";
+    my $parser = XML::LibXML->new;
+    my $doc = $parser->parse_string("<foo>bar</foo>");  
+
+    ok( $doc );
+
+    print "# 4.1 to file handle\n";
+    {
+        require IO::File;
+        my $fh = new IO::File;
+        if ( $fh->open( "> example/testrun.xml" ) ) {
+            $doc->toFH( $fh );
+            $fh->close;
+            ok(1);
+            # now parse the file to check, if succeeded
+            my $tdoc = $parser->parse_file( "example/testrun.xml" );
+            ok( $tdoc );
+            ok( $tdoc->documentElement );
+            ok( $tdoc->documentElement->nodeName, "foo" );
+            ok( $tdoc->documentElement->textContent, "bar" );
+            unlink "example/testrun.xml" ;
+        }
+    }
+
+    print "# 4.2 to named file\n";
+    {
+        $doc->toFile( "example/testrun.xml" );
+        ok(1);
+        # now parse the file to check, if succeeded
+        my $tdoc = $parser->parse_file( "example/testrun.xml" );
+        ok( $tdoc );
+        ok( $tdoc->documentElement );
+        ok( $tdoc->documentElement->nodeName, "foo" );
+        ok( $tdoc->documentElement->textContent, "bar" );
+        unlink "example/testrun.xml" ;        
+    }
 }
 
 BEGIN { plan tests => 121 };
 use XML::LibXML;
+use XML::LibXML::Common qw(:libxml);
 
 my $xmlstring = q{<foo>bar<foobar/><bar foo="foobar"/><!--foo--><![CDATA[&foo bar]]></foo>};
 
 
 BEGIN { plan tests => 20 };
 use XML::LibXML;
+use XML::LibXML::Common qw(:libxml);
 
 {
     my $doc = XML::LibXML::Document->new;
 use Test;
 BEGIN { plan tests=>16; }
 use XML::LibXML;
+use XML::LibXML::Common qw(:libxml);
 
 my $parser = XML::LibXML->new();
 
 use Test;
 
 BEGIN { 
-    my $tests        = 2;
-    my $basics       = 1;
+    my $tests        = 0;
+    my $basics       = 0;
     my $magic        = 6;    
 
     $tests += $basics;  
 }
 
 END { ok(0) unless $loaded }
-
+use XML::LibXML::Common;
 use XML::LibXML;
 $loaded = 1;
 ok(1);
 <t�st>t�st</t�st>
 };
 
-print "# simple encoding interface\n";
-
-ok( decodeFromUTF8( 'UTF-8' ,
-                     encodeToUTF8('UTF-8', $tstr_utf8 ) ),
-    $tstr_utf8 );
-
-ok( decodeFromUTF8( 'iso-8859-1' ,
-                     encodeToUTF8('iso-8859-1', $tstr_iso_latin1 ) ),
-    $tstr_iso_latin1 );
-
 if ( $] < 5.006 ) {
     warn "\nskip magic encoding tests on this platform\n";
     exit(0);
     my $dom_latin1 = XML::LibXML::Document->new('1.0', 'iso-8859-1');
     my $elemlat1   = $dom_latin1->createElement( $tstr_iso_latin1 );
 
-    ok( decodeFromUTF8( 'iso-8859-1' ,
-                        $elemlat1->nodeName()),
-        $tstr_iso_latin1 );
-
     $dom_latin1->setDocumentElement( $elemlat1 );
     
     ok( decodeFromUTF8( 'iso-8859-1' ,$elemlat1->toString()),
     my $domstrjp = q{<?xml version="1.0" encoding="EUC-JP"?>
 <������������>������������</������������>
 };
-
-    ok( decodeFromUTF8( 'EUC-JP' , encodeToUTF8('EUC-JP', $tstr_euc_jp ) ),
-        $tstr_euc_jp );
     
 
     if ( $] >= 5.006 ) {
 <�����>�����</�����>
 };
     
-    ok( decodeFromUTF8( 'KIO8-R' , 
-                         encodeToUTF8('KIO8-R', $tstr_kio8r ) ),
-        $tstr_kio8r );    
 
     if ( $] >= 5.006 ) {
         my ($dom_kio8, $elemkio8);
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.