如何使TXMLDocument(使用MSXML实现)始终包含编码属性?

Fab*_*ujo 9 xml delphi encoding txmldocument delphi-2010

我有遗留代码(我没写它)总是包含编码属性,但重新编译到D2010,TXMLDocument不再包含编码.由于XML数据在标记和数据上都有重音字符,因此TXMLDocument.LoadFromFile只会抛出EDOMParseErros,表示在文件中找到了无效字符.相关代码:

   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
Run Code Online (Sandbox Code Playgroud)

在旧版本的Delphi中,生成以下行:

<?xml version="1.0" encoding="ISO-8859-1"?>
Run Code Online (Sandbox Code Playgroud)

在D2010上,生成:

<?xml version="1.0"?>
Run Code Online (Sandbox Code Playgroud)

如果我手动更改线路,所有工作都像过去几年一直工作.

更新:XMLEncoding是一个常量,定义如下

  XMLEncoding = 'ISO-8859-1';
Run Code Online (Sandbox Code Playgroud)

Ken*_*ite 6

你会想看到IXMLDocument.CreateProcessingStruction.我使用OmniXML,但它的语法类似,应该让你开始:

var
  FDoc: IXMLDocument;
  PI:  IXMLProcessingInstruction;
begin
  FDoc := OmniXML.CreateXMLDoc();
  PI := FDoc.CreateProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"');
  FDoc.AppendChild(PI);
end;
Run Code Online (Sandbox Code Playgroud)


Fab*_*ujo 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;
Run Code Online (Sandbox Code Playgroud)

由于 Ken 的回答和 MSXML 文章的链接,我决定研究 XML 属性和 SaveToXML 方法。两者都使用 MSXMLDOM 实现的 XML 属性 - 在文章中据说直接读取时不带编码(在使用 CreateProcessInstruction 方法之后的“使用 MSXML 创建新的 XML 文档”部分中)。

更新:

我发现重音字符在生成的 XML 中被截断。当该 XML 的处理器开始抛出奇怪的错误时,我们看到字符正在转换为数字字符常量(#13 是用于回车的数字字符常量)。因此,我使用 TStringStream 使其最终正确。