Commits

Anonymous committed 9bd11ce

Modified Files:
Tag: mm_fix
LibXML.pm LibXML.xs
+ documentation
+ new serialization flags
setTagCompression
skipDTD
skipXMLDeclaration

Comments (0)

Files changed (2)

     $doc->_setDocumentElement($element);
 }
 
+sub toString {
+    my $self = shift;
+    my $flag = shift;
+
+    my $retval = "";
+
+    if ( defined $XML::LibXML::skipXMLDeclaration
+         and $XML::LibXML::skipXMLDeclaration == 1 ) {
+        foreach ( $self->childNodes ){
+            next if defined $XML::LibXML::skipDTD
+                    and $XML::LibXML::skipDTD == 1
+                    and $_->nodeType == XML::LibXML::XML_DTD_NODE();
+
+            $retval .= $_->toString;
+        }
+    }
+    elsif ( defined $XML::LibXML::skipDTD
+         and $XML::LibXML::skipDTD == 1 ) {
+        # no chance to get the XML Decl from libxml2
+        $retval = '<?xml version="' . $self->version .'"';
+        my $standalone = $self->standalone;
+        my $encoding = $self->encoding;
+
+        $retval .= ' encoding="' . $encoding . '"' if defined $encoding;
+        $retval .= ' standalone="' .($standalone ? "yes" : "no" ). '"'
+          if defined $standalone && $standalone >= 0;
+        $retval .= "?>\n";
+        foreach ( $self->childNodes ){
+            next if $_->nodeType == XML::LibXML::XML_DTD_NODE();
+            $retval .= $_->toString(1);
+        }
+        $retval .= "\n";
+    }
+    else {
+        $retval =  $self->_toString($flag);
+    }
+    return $retval;
+}
+
 1;
 
 package XML::LibXML::DocumentFragment;
 If expand_xincludes is set to 1, the method is only required to process
 XIncludes appended to the DOM after its original parsing.
 
+=head1 SERIALIZATION
+
+The oposite of parsing is serialization. In XML::LibXML this can be
+done by using the functions toString(), toFile() and toFH(). All
+serialization functions understand the flag setTagCompression. if this
+Flag is set to 1 empty tags are displayed as <foo></foo>
+rather than <foo/>.
+
+toString() additionally checks two other flags:
+
+skipDTD and skipXMLDeclaration
+
+If skipDTD is specified and any DTD node is found in the document this
+will not be serialized.
+
+If skipXMLDeclaration is set to 1 the documents xml declaration is not
+serialized. This flag will cause the document to be serialized as UTF8
+even if the document has an other encoding specified.
+
+XML::LibXML does not define these flags itself, therefore they have to
+specify them manually by the caller:
+
+ local $XML::LibXML::skipXMLDeclaration = 1;
+ local $XML::LibXML::skipDTD = 1;
+ local $XML::LibXML::setTagCompression = 1;
+
+will cause the serializer to avoid the XML declaration for a document,
+skip the DTD if found, and expand empty tags.
+
+*NOTE* $XML::LibXML::skipXMLDeclaration and $XML::LibXML::skipDTD are
+only recognized by the Documents toString() function.
+
+Additionally it is possible to serialize single nodes by using
+toString() for the node. Since a node has no DTD and no XML
+Declaration the related flags will take no effect. Nevertheless
+setTagCompression is supported.
+
 =head1 XML::LibXML::Document
 
 The objects returned above have a few methods available to them:
 Process any xinclude tags in the file. (currently using B<only> libxml2's
 default callbacks)
 
+
 =head1 XML::LibXML::Dtd
 
 This module allows you to parse and return a DTD object. It has one method
 MODULE = XML::LibXML         PACKAGE = XML::LibXML::Document
 
 SV *
-toString(self, format=0)
+_toString(self, format=0)
         SV * self
         int format
     PREINIT:
         xmlDocPtr real_dom;
         xmlChar *result=NULL;
         int len=0;
+        SV* internalFlag = NULL;
+        int oldTagFlag = xmlSaveNoEmptyTags;
     CODE:
         real_dom = (xmlDocPtr)PmmNODE(SvPROXYNODE(self));
+        internalFlag = get_sv("XML::LibXML::setTagCompression", 0);
+        if( internalFlag ) {
+            xmlSaveNoEmptyTags = SvTRUE(internalFlag);
+        }
+
         if ( format <= 0 ) {
             # warn( "use no formated toString!" );
             xmlDocDumpMemory(real_dom, &result, &len);
             xmlIndentTreeOutput = t_indent_var;
         }
 
+        xmlSaveNoEmptyTags = oldTagFlag;
+
     	if (result == NULL) {
 	        # warn("Failed to convert doc to string");           
             XSRETURN_UNDEF;
         xmlOutputBufferPtr buffer;
         const xmlChar * encoding = NULL;
         xmlCharEncodingHandlerPtr handler = NULL;
+        SV* internalFlag = NULL;
+        int oldTagFlag = xmlSaveNoEmptyTags;
     CODE:
+        internalFlag = get_sv("XML::LibXML::setTagCompression", 0);
+        if( internalFlag ) {
+            xmlSaveNoEmptyTags = SvTRUE(internalFlag);
+        }
+
         xmlRegisterDefaultOutputCallbacks();
         encoding = ((xmlDocPtr) PmmSvNode(self))->encoding;
         if ( encoding != NULL ) {
                                      (xmlDocPtr)PmmSvNode(self),
                                      encoding,
                                      format);
-
+        xmlSaveNoEmptyTags = oldTagFlag;
         xmlOutputBufferClose( buffer );
     OUTPUT:
         RETVAL    
 toFile( self, filename )
         SV * self
         char * filename
+    PREINIT:
+        SV* internalFlag = NULL;
+        int oldTagFlag = xmlSaveNoEmptyTags;
     CODE:
-        RETVAL = xmlSaveFile( filename, (xmlDocPtr)PmmSvNode(self) );   
+        internalFlag = get_sv("XML::LibXML::setTagCompression", 0);
+        if( internalFlag ) {
+            xmlSaveNoEmptyTags = SvTRUE(internalFlag);
+        }
+
+        RETVAL = xmlSaveFile( filename, (xmlDocPtr)PmmSvNode(self) );
+
+        xmlSaveNoEmptyTags = oldTagFlag;   
         if ( RETVAL > 0 ) 
             RETVAL = 1;
         else 
     PREINIT:
         xmlBufferPtr buffer;
         char *ret = NULL;
+        SV* internalFlag = NULL;
+        int oldTagFlag = xmlSaveNoEmptyTags;
     CODE:
+        internalFlag = get_sv("XML::LibXML::setTagCompression", 0);
+
+        if ( internalFlag ) {
+            xmlSaveNoEmptyTags = SvTRUE(internalFlag);
+        }
         buffer = xmlBufferCreate();
         xmlNodeDump( buffer,
                      PmmNODE(SvPROXYNODE(self))->doc,
         }
         
         xmlBufferFree( buffer );
+        xmlSaveNoEmptyTags = oldTagFlag;
 
         if ( ret != NULL ) {
-            if ( SvTRUE(useDomEncoding) ) {
+            if ( useDomEncoding!= &PL_sv_undef && SvTRUE(useDomEncoding) ) {
                 RETVAL = nodeC2Sv(ret, PmmNODE(SvPROXYNODE(self))) ;
             }
             else {