delphi - 如何在 Delphi 中使用 TXMLDocument 将 Ansi 转换为 UTF 8

标签 delphi unicode utf-8 delphi-6 txmldocument

可以在 Delphi 6 中将 XML 转换为 UTF-8 编码吗?
目前这就是我正在做的事情:

  • 使用 AnsiString 填充 TXMLDocument
  • 最后使用 WideStringVariable = AnsiToUtf8(Doc.XML.Text); 将数据转换为 UTF-8;
  • 使用 TFileStream 并在文件开头添加 BOM for UTF8WideStringVariable 的值保存到文件。

代码:

Procedure SaveAsUTF8( const Name:String; Data: TStrings );

const
  cUTF8 = $BFBBEF;
var
  W_TXT: WideString;
  fs: TFileStream;
  wBOM: Integer;
begin
  if TRIM(Data.Text) <> '' then begin    
    W_TXT:= AnsiToUTF8(Data.Text);
    fs:= Tfilestream.create( Name, fmCreate );
    try
      wBOM := cUTF8;
      fs.WriteBUffer( wBOM, sizeof(wBOM)-1);
      fs.WriteBuffer( W_TXT[1], Length(W_TXT)*Sizeof( W_TXT[1] ));
    finally
      fs.free
    end;
  end;
end;

如果我在 Notepad++ 或其他检测编码的编辑器中打开该文件,它会显示带有 BOM 的 UTF-8。但是,文本似乎没有正确编码。

出了什么问题,如何解决?

更新:XML 属性:

XMLDoc.Version := '1.0';
XMLDoc.Encoding := 'UTF-8';
XMLDoc.StandAlone := 'yes';

最佳答案

您可以使用标准 SaveToFile 保存文件方法 TXMLDocument变量:http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/XMLDoc_TXMLDocument_SaveToFile.html

无论文件是否为 UTF8,您都必须使用本地工具(例如前面提到的 Notepad++ 或十六进制编辑器或其他任何工具)进行检查。

<小时/>

如果你坚持使用中间字符串和文件流,你应该使用正确的变量。 AnsiToUTF8返回UTF8String类型,这就是要使用的类型。 编译 `WideStringVar := AnsiStringSource' 将发出编译器警告并且

这是一个适当的警告。谷歌搜索“Delphi WideString” - 或阅读相关主题的 Delphi 手册 - 显示WideString又名 Microsoft OLE BSTR以 UTF-16 格式保存数据。 http://delphi.about.com/od/beginners/l/aa071800a.htm 因此分配UTF16 string <= 8-bit source必然会转换数据并因此转储 WideString数据无法转储UTF-8定义为 WideString 的文本

Procedure SaveAsUTF8( const Name:String; Data: TStrings );
const
  cUTF8: array [1..3] of byte = ($EF,$BB,$BF)
var
  W_TXT: UTF8String;
  fs: TFileStream;
  Trimmed: AnsiString;
begin
  Trimmed := TRIM(Data.Text);
  if Trimmed <> '' then begin    
    W_TXT:= AnsiToUTF8(Trimmed);
    fs:= TFileStream.Create( Name, fmCreate );
    try
      fs.WriteBuffer( cUTF8[1], sizeof(cUTF8) );
      fs.WriteBuffer( W_TXT[1], Length(W_TXT)*Sizeof( W_TXT[1] ));
    finally
      fs.free
    end;
  end;
end;

顺便说一句,如果源数据为空,您的这段代码甚至不会创建空文件。它看起来相当可疑,尽管您可以决定这是否是程序其余部分的错误。

<小时/>

将接收到的文件或流正确“上传”到网络是另一个问题(在像 SO 这样的问答网站上作为单独的问题提出),与测试 HTTP 的一致性有关。作为前言,您可以阅读 WWW server reports error after POST Request by Internet Direct components in Delphi 中的一些提示。

关于delphi - 如何在 Delphi 中使用 TXMLDocument 将 Ansi 转换为 UTF 8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17722933/

相关文章:

android - 如何将 strings.xml 翻译成东方语言?

Delphi 将 StringGrid 中的数据插入数据库表

delphi - 从 ListView 切换到 VirtualStringTree

mysql - Primefaces ajax 字符集

regex - 为什么 Perl v5.22 没有找到所有的句子边界?

c++ - 在字 rune 字中使用 unicode 字符

java - 如何在 Java 应用程序上编写 UTF-8 字符?

delphi - 函数返回类的派生

delphi - 具有自定义 uri 架构的桌面应用程序, token 请求时为 "Missing scheme"

android - python sl4a unicode (Android)