9

我有始终包含编码属性的旧代码(我没有编写),但是将其重新编译到 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

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

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

在 D2010 上,生成:

<?xml version="1.0"?>

如果我手动更改线路,所有工作都像过去几年一样正常工作。

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

  XMLEncoding = 'ISO-8859-1';
4

2 回答 2

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;
于 2010-05-03T20:08:54.030 回答
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;

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

更新:

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

于 2010-05-04T18:37:41.113 回答