采取以下情况:
procedure Test;
var
Response : String;
begin
Response := IdHttp.Post(MyUrL, AStream);
DoSomethingWith(Response);
end;
现在网络服务器以 UTF-8 格式返回我的数据。
假设它返回一些包含该字符的 UTF-8 XMLé。
如果我使用变量 Response 它不包含这个字符,但它是 UTF-8 变体(#C3#A9),所以 Indy 没有解码?
现在我知道如何解决这个问题:
procedure Test;
var
Response : String;
begin
Response := UTF8ToString(IdHttp.Post(MyUrL, AStream));
DoSomethingWith(Response);
end;
此解决方案的一个警告:Delphi 发出警告 W1058(隐式字符串转换,可能导致从“string”到“RawByteString”的数据丢失)
我的问题:这是处理这个问题的正确方法吗?或者我可以指示 TIdHTTP 为我转换为 UnicodeString 吗?
如果您使用的是 Indy 10 的最新版本,则重载版本TIdHTTP.Post()
返回一个String
does将数据解码为 Unicode,但是用于解码的实际字符集取决于 HTTP 的媒体类型Content-Type
响应头指定:
如果媒体类型是application/xml
, application/xml-external-parsed-entity
, application/xml-dtd
,或者不是一个text/...
类型但结尾为+xml
,然后指定的字符集encoding
使用 XML 序言的属性。如果未指定字符集,则使用 UTF-8。
否则,如果Content-Type
响应头指定一个字符集,然后使用它。
-
否则,如果媒体类型是text/...
输入,然后:
A。如果媒体类型是text/xml
, text/xml-external-parsed-entity
,或以+xml
, then us-ascii
用来。
b.否则ISO-8859-1
用来。
否则,使用 Indy 的默认编码(默认为 ASCII)。
没有看到实际的 HTTPContent-Type
header,很难知道你的情况属于哪种情况。听起来它落入 #2 或 #3b,这将说明按原样返回 UTF-8 字节值,如果ISO-8859-1
或正在使用类似的字符集。
UTF8ToString()
需要 UTF-8 编码RawByteString
作为输入,但您传递的是 UTF-16 编码UnicodeString
反而。在这种情况下,RTL 将执行 UTF16->Ansi 转换,并使用默认的 Ansi 字符集进行转换。这就是您收到编译器警告的原因,因为此类转换可能会丢失数据。
XML 实际上是一种二进制数据格式,受字符集编码的约束。 XML 解析器需要知道 XML 的编码是什么,并能够相应地解析原始编码字节。这就是为什么 XML 有一个显式的encoding
属性位于 XML 序言中。然而,当TIdHTTP
下载 XML 作为String
,虽然它会自动将其解码为 Unicode,但它does not但相应地更新 XML 的序言。
真正的解决方案是不要将 XML 下载为String
首先。将其下载为TStream
反而 (TMemoryStream
是一个更好的选择TStringStream
)这样你的 XML 解析器就可以访问原始字节、原始字符集声明等。你可以传递TStream
to the TXMLDocument.LoadFromStream()
方法,例如。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)