2010-05-03 16 views
9

Tengo código heredado (no lo escribí) que siempre incluía el atributo de codificación, pero recomprándolo a D2010, TXMLDocument ya no incluye la codificación. Debido a que los datos XML tienen caracteres acentuados en etiquetas y datos, TXMLDocument.LoadFromFile simplemente arroja EDOMParseErros diciendo que se encuentra un carácter no válido en el archivo. código relevante:¿Cómo hacer que TXMLDocument (con la implementación de MSXML) siempre incluya el atributo de codificación?

Doc := TXMLDocument.Create(nil); 
    try 
    Doc.Active := True; 
    Doc.Encoding := XMLEncoding; 
    RootNode := Doc.CreateElement('Test', ''); 
    Doc.DocumentElement := RootNode; 
    <snip> 
    //Result := Doc.XMl.Text; 
    Doc.SaveToXML(Result); // Both lines gives the same result 

En las versiones anteriores de Delphi, se genera la siguiente línea:

<?xml version="1.0" encoding="ISO-8859-1"?> 

En D2010, esto se genera:

<?xml version="1.0"?> 

Si cambio manualmente la línea, todo funciona como siempre funcionó en los últimos años.

ACTUALIZACIÓN: XMLEncoding es una constante y se define como sigue

XMLEncoding = 'ISO-8859-1'; 

Respuesta

4
var 
    XMLStream: TStringStream; 
begin 
    Doc := TXMLDocument.Create(nil); 
    try 
    Doc.Active := True; 
    Doc.Encoding := XMLEncoding; 
    RootNode := Doc.CreateElement('Test', ''); 
    Doc.DocumentElement := RootNode; 
    <snip> 
    XMLStream := TStringStream.Create; 
    Doc.SaveToStream(XMLStream); 
    Result := XmlStream.DataString; 
    XMLStream.Free; 

Dado que la respuesta de Ken y el enlace al artículo de MSXML, decidí investigar la propiedad XML y método SaveToXML. Ambos usan la propiedad XML de la implementación MSXMLDOM, que en el artículo se dice que no trae la codificación cuando se lee directamente (en la sección "Crear documentos XML nuevos con MSXML" justo después del uso del método CreateProcessInstruction).

ACTUALIZACIÓN:

me encontré con que los caracteres acentuados se quedan truncados en el XML resultante. Cuando el procesador de ese XML comenzó a arrojar errores extraños, vimos que los caracteres se están convirtiendo a la constante de caracteres numéricos (# 13 es la constante de caracteres numéricos para el retorno del carro). Entonces, utilicé un TStringStream para obtenerlo FINALMENTE a la derecha.

6

Usted querrá ver IXMLDocument.CreateProcessingStruction. Yo uso OmniXML, pero es sintaxis es similar y debería empezar:

var 
    FDoc: IXMLDocument; 
    PI: IXMLProcessingInstruction; 
begin 
    FDoc := OmniXML.CreateXMLDoc(); 
    PI := FDoc.CreateProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"'); 
    FDoc.AppendChild(PI); 
end; 
+0

Eso es exactamente lo que Microsoft recomienda también para MSXML: http://msdn.microsoft.com/en-us/library/aa468560.aspx. Sin embargo, la cosa al principio del documento no es técnicamente una instrucción de procesamiento. Es una * declaración XML *; la cadena "xml" no está realmente permitida para el nombre de una instrucción de procesamiento, por lo que parece que el método 'CreateProcessingInstruction' cumple una función doble. –

+0

@Rob: Probablemente es por eso que me tomó un tiempo hace un par de años resolverlo (no tenía el enlace de MSDN que me proporcionó en ese momento). Sin embargo, en realidad podría considerarse una instrucción de procesamiento, ¿no es así, si le está diciendo al analizador cómo interpretar el contenido? "Esto es XML, y está en este conjunto de caracteres, eso hará que sea más fácil de descifrar". –

Cuestiones relacionadas