<?php

    
/**
     * Cleans and formates a XML document by removing/cleaning unnecessary whitespace
     * (line breaks, tabs, etc.) and indenting all tags correctly.
     * 
     * @author Till Kr├╝ss <till at pralinenschachtel dot de>
     * 
     * @param string $string XML which should be cleaned and formatted
     * @return string cleaned XML string
     */
    
function clean_xml($string) {

        
// fetch all CDATA sections
        
preg_match_all('~<!\[CDATA\[.*?\]\]>~s'$string$cdata_sections);

        
// clean every CDATA section
        
foreach ($cdata_sections as $section) {
            
$cleaned_section preg_replace('~\r|\n~ms'''$section); // remove line breaks
            
$string str_replace($section$cleaned_section$string);
        }

        
// replace \r\n with \n
        
$string preg_replace('~\r\n~ms'"\n"$string);

        
// replace \r with \n
        
$string preg_replace('~\r~ms'"\n"$string);

        
// remove whitespace from the beginnig
        
$string preg_replace('~^\s+~s'''$string);

        
// remove whitespace from the end
        
$string preg_replace('~\s+$~s'''$string);

        
// remove whitespace from the beginning of each line
        
$string preg_replace('~^\s+~m'''$string);

        
// remove whitespace from the end of each line
        
$string preg_replace('~\s+$~m'''$string);

        
// removes empty lines
        
$string preg_replace('~\n\s*(?=\n)~ms'''$string);

        
// removes line breaks inside normal text
        
$string preg_replace('~([^>\s])(\s\s+|\n)([^<\s])~m''$1 $3'$string);

        
// correct indention
        
$indent 0;
        
$string explode("\n"$string);
        foreach (
$string as &$line) {
            
$correction intval(substr($line02) == '</'); // correct indention, if line starts with closing tag
            
$line str_repeat("\t"$indent $correction).$line;
            
$indent += substr_count($line'<'); // indent every tag
            
$indent -= substr_count($line'<!'); // subtract CDATA sections
            
$indent -= substr_count($line'<?'); // subtract processing instructions
            
$indent -= substr_count($line'/>'); // subtract self closing tags
            
$indent -= substr_count($line'</') * 2// subtract closing tags
        
}
        
$string implode("\n"$string);

        return 
$string;

    }

?>