potresti provare a non usare i CDATA, in questo caso devi precisargli una grammatica (probabilmente non devi ridefinire tutti i tag di xhtml ma almeno gli amp, altrimenti avrai un errore)
Codice PHP:
      header("Content-type: text/xml"); 

    echo "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";

//    echo "<!DOCTYPE data SYSTEM \"xxx.dtd\"";
// oppure in linea

    
echo "\n<!DOCTYPE data [";

    echo 
"\n    <!ELEMENT data ( ...)>";
....
    echo 
"\n    <!ATTLIST ..... CDATA #IMPLIED>";

    echo 
"\n    <!ENTITY egrave \"&amp;egrave;\">";
    echo 
"\n    <!ENTITY eacuta \"&amp;eacuta;\">";
    echo 
"\n    <!ENTITY agrave \"&amp;agrave;\">";
    echo 
"\n    <!ENTITY igrave \"&amp;igrave;\">";
    echo 
"\n    <!ENTITY ugrave \"&amp;ugrave;\">";
    echo 
"\n    <!ENTITY ograve \"&amp;ograve;\">";
    echo 
"\n    <!ENTITY euro \"&amp;euro;\">";
    echo 
"\n    <!ENTITY reg \"&amp;reg;\">";

    echo 
"\n]>";
io normalmente tuttavia racchiudo tutto in CDATA per levarmi ogni problema, e mi funziona.

in questo caso lato server sarà (sempre in php)


Codice PHP:
        echo "<data >";
    
        echo 
"    <![CDATA[";

// il tuo codice xhtml


    
echo "    ]]>";

    echo 
"</data>"
lato client lo leggo così
codice:
	var obj_corpo = xml.getElementsByTagName("data");
	if (obj_corpo.length > 0) {
              ....
		var childs = obj_corpo[0].childNodes;
		var str = "";

		for (var i = 0; i < childs.length; i++) 
			str += printXML (childs[i], 1);

        	(il tuo div di inserimento).innerHTML = str;
                .....
	
        }
la funzione printXML è una lettora ricorsiva del tuo html (che deve quindi essere valido)

codice:
// stampa l'xml ricorsivamente
// curEl = il noto attuale
// depth = profondità, alla prima chiamata è 1
    
function printXML (curEl, depth)
{
    
	var loc_print="";
  
	var tab = "";
    
	if (curEl) {
    
		var tagName = curEl.tagName;
		
		if (tagName) {
			tag = tab + "<" + curEl.tagName ;
			var attr = curEl.attributes;
			
			for (var i = 0; i < attr.length; i++) {
				var nome = attr[i].nodeName;
				var valore = curEl.getAttribute(nome);
				tag += " " + nome + "=\"" + valore + "\"";
			}
			
			tag += ">";
		}  
		else
			tag = tab + curEl.nodeValue;
    
		loc_print += tag;

		var curElChild = curEl.childNodes;
    
		for (var i = 0; i < curElChild.length; i++) {
	        // attraversamento ricorsivo dei figli
        		loc_print += printXML(curElChild[i], depth+1);
		}
 
	}
  
	// chiude il tag
	if (tagName) {
	        loc_print += tab + "</" + tagName + ">";
	}
  
	return loc_print;
}
spero che ti possa essere utile
ciao
sergio