2009-03-05 6 views
2

Wie kann ich alle Entity-Referenzen im XHTML-Dokument auflösen und in ein einfaches XHTML-Dokument konvertieren, das IE verstehen kann? Das Beispiel XHTML:Wie löst man alle Entity-Referenzen in XML auf und erstellt ein neues XML in C#?

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE html [ 
    <!ENTITY D "&#x2014;"> 
    <!ENTITY o "&#x2018;"> 
    <!ENTITY c "&#x2019;"> 
    <!ENTITY O "&#x201C;"> 
    <!ENTITY C "&#x201D;"> 
]> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    </head> 
    <body> 
     &O; &C; 
    </body> 
</html> 
+0

MSIE kann nicht mit dem vollkommen legalen XHTML umgehen, das Sie zeigen? Dieser Mist ist wirklich kaputt. – bortzmeyer

Antwort

2

Stellt sich heraus, das ist einfach Option in dem XmlTextReader (und XmlValidatingReader) Klasse - "EntityHandling".

So eine einfache Demo des Problems:

System.Xml.XmlTextReader textReader = new System.Xml.XmlTextReader("testin.xml"); 
textReader.EntityHandling = System.Xml.EntityHandling.ExpandEntities; 
System.Xml.XmlDocument outputDoc = new System.Xml.XmlDocument(); 
outputDoc.Load(textReader); 
System.Xml.XmlDocumentType docTypeIfPresent = outputDoc.DocumentType; 
if (docTypeIfPresent != null) 
    outputDoc.RemoveChild(docTypeIfPresent); 
outputDoc.Save("testout.html"); 
textReader.Close(); 

Und wenn Sie nicht lieber das Dokument in den Speicher haben, zu laden, ein Streaming-Äquivalent:

System.Xml.XmlTextReader textReader = new System.Xml.XmlTextReader("testin.xml"); 
textReader.EntityHandling = System.Xml.EntityHandling.ExpandEntities; 
System.Xml.XmlTextWriter textWriter = new System.Xml.XmlTextWriter("testout.html", System.Text.Encoding.UTF8); 
while (textReader.Read()) 
{ 
    if (textReader.NodeType != System.Xml.XmlNodeType.DocumentType) 
     textWriter.WriteNode(textReader, false); 
    else 
     textReader.Skip(); 
} 
textWriter.Close(); 
+0

XmlWriterSettings writerSettings = new XmlWriterSettings(); writerSettings.OmitXmlDeclaration = true; XmlWriter xmlWriter = XmlWriter.Create (htmlFileName, writerSettings); outputDoc.Save (xmlWriter); xmlWriter.Close(); –

+0

Hallo, ich verstehe den Kommentar nicht - lässt OmitXmlDeclaration auch die DTD weg? Hätte es nicht den unerwünschten Nebeneffekt, die XML-Deklaration auch tatsächlich zu entfernen? (was wiederum zu Kodierungsproblemen führen kann) – Tao

+0

ersetzen Sie die Zeile outputDoc.Save ("testout.html"); mit meinem Code, so dass die Xml-Deklaration weggelassen wird, die dazu führen, dass ein einfaches HTML anstelle von XML generiert wird –

0

xmllint kann es tun, und, Da xmllint in C geschrieben ist und freie Software ist, ist es wahrscheinlich relativ einfach, die Art und Weise anzupassen, wie es mit Ihrem C# -Programm gemacht wird. Hier ein Beispiel:

% cat foo.xhtml 
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE html [ 
    <!ENTITY D "&#x2014;"> 
    <!ENTITY o "&#x2018;"> 
    <!ENTITY c "&#x2019;"> 
    <!ENTITY O "&#x201C;"> 
    <!ENTITY C "&#x201D;"> 
]> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    </head> 
    <body> 
     &O; &C; 
    </body> 
</html> 

% xmllint --noent --dropdtd foo.xhtml 
<?xml version="1.0" encoding="utf-8"?> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    </head> 
    <body> 
     [Plain Unicode characters that I prefer to omit because I don't know how SO handles it] 
    </body> 
</html>