可以在Delphi 6中将XML转换为UTF-8编码吗?
目前我正在做的事情:
WideStringVariable = AnsiToUtf8(Doc.XML.Text);
WideStringVariable
将TFileStream
的值保存到文件,并在文件开始时添加BOM for UTF8
。CODE:
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';
答案 0 :(得分:3)
您可以使用标准SaveToFile
方法在TXMLDocument
变量上保存文件:http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/XMLDoc_TXMLDocument_SaveToFile.html
无论文件是否为UTF8,您都必须使用上述Notepad ++或Hex Editor等本地工具进行检查。
如果您坚持使用中间字符串和文件流,则应使用正确的变量。 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;
顺便说一下,如果源数据为空,那么你的这段代码就不会创建空文件。它看起来很可疑,但你可以决定是否是一个错误,而不是你的程序的其余部分。
将接收到的文件或流正确“上传”到网络上是另一个问题(将作为单独的问题放在像Q这样的Q&amp; A网站上),与测试与HTTP的一致性有关。作为前言,您可以在WWW server reports error after POST Request by Internet Direct components in Delphi
读取一些提示答案 1 :(得分:2)
为了在文档中使用正确的编码,您应该使用XML文档中的Encoding属性进行设置,如下所示:
myXMLDocument.Encoding := 'UTF-8';
我希望这会有所帮助。
答案 2 :(得分:2)
您只需要调用文档的SaveToFile
方法:
XMLDoc.SaveToFile(FileName);
由于您已经指定了编码,因此该组件将使用该编码。
这不包括BOM,但这通常是您想要的XML文件。该文件的内容将指定编码。
关于您的SaveAsUTF8
方法,不需要它,但很容易修复。这对你来说可能是有益的。
问题是,当您分配到WideString
变量时,您将转换为UTF-16。您应该将UTF-8文本放入AnsiString
变量中。将名为W_TXT
的变量类型更改为AnsiString
就足够了。
该功能可能如下所示:
Procedure SaveAsUTF8(const Name: string; Data: TStrings);
const
UTF8BOM: array [0..2] of AnsiChar = #$EF#$BB#$BF;
var
utf8: AnsiString;
fs: TFileStream;
begin
utf8 := AnsiToUTF8(Data.Text);
fs:= Tfilestream.create(Name, fmCreate);
try
fs.WriteBuffer(UTF8BOM, SizeOf(UTF8BOM));
fs.WriteBuffer(Pointer(utf8)^, Length(utf8));
finally
fs.free;
end;
end;
答案 3 :(得分:1)
另一种解决方案:
procedure SaveAsUTF8(const Name: string; Data: TStrings);
var
fs: TFileStream;
vStreamWriter: TStreamWriter;
begin
fs := TFileStream.Create(Name, fmCreate);
try
vStreamWriter := TStreamWriter.Create(fs, TEncoding.UTF8);
try
vStreamWriter.Write(Data.Text);
finally
vStreamWriter.Free;
end;
finally
fs.free;
end;
end;