Delphi idhttp 损坏的字符

Delphi idhttp broken characters

我正在研究 Delphi XE5 并使用 IDHTTP 从服务器获取 XML。获取 XML 工作正常,但有一些损坏的字符。字符是“•”(圆点)。其他都还好,就是要点坏了。

我创建了如下 IDHTTP:

idhttps := TIdHTTP.Create();
idhttps.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
idhttps.IOHandler.DefStringEncoding := IndyTextEncoding(TEncoding.UTF8);
idhttps.HandleRedirects := True;
idhttps.ConnectTimeout := 5000;
idhttps.Request.USERNAME := 'USERNAME';
idhttps.Request.PASSWORD := 'PASSWORD';
idhttps.Request.BasicAuthentication := True;
idhttps.Request.Accept := 'text/xml';

然后得到 xml 如下所示:

SS := TStringStream.Create('', TEncoding.UTF8);

try
  self.GetIdHTTPForLexicomp.Get(URL, SS);
  XMLDoc := TXMLDocument.Create(nil);
  XMLDoc.LoadFromStream(SS, TXMLEncodingType.xetUTF_8Like);
finally
  SS.Free;
end;

在XML中,项目符号点显示如下:

? Anaphylaxis/hypersensitivity: May cause hypersensitivity reactions,

XML header 如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

我应该检查什么?

更新:我添加了 XML 片段。它需要一个用于样式的 XSL 文件,但在这种情况下,我认为这不是问题。 “?”是坏字符。

<?xml version="1.0" standalone="yes"?>
<ns2:monogragh>
  <monograghFields>
    <field fieldId="234837" fieldTypeCode="war" created="2005-04-07T17:28:33Z" modified="2014-10-02T11:32:57Z" sectionId="0">
      <fieldName>Warnings/Precautions</fieldName>
      <content>
        <div id="war" class="block">
          <p style="text-indent:-2em;margin-left:2em;text-align:justify;">
            <b>
              <i>Concerns related to adverse effects:</i>
            </b>
          </p>
          <p style="text-indent:-2em;margin-left:4em;text-align:justify;">
            ? Anaphylaxis/hypersensitivity: May cause hypersensitivity reactions, including anaphylaxis; use with caution in patients with anaphylactic disorders.
          </p>
        </div>
      </content>
    </field>
  </monograghFields>
</ns2:monogragh>

看来我给了mis-information。我附上了捕获的 xml 片段。第一个是使用 rest 客户端工具从浏览器获取的结果,最后一个是通过 idhttp 获取 xml 的结果。

  1. 使用TIdHTTP时不要设置IOHandler.DefStringEncoding属性。让 TIdHTTP 以自己的方式处理编码。

  2. TStream接收XML是正确的选择。但是,特别是使用 TStringStream 并不是一个好的选择,因为它绑定到您在构造函数中指定的 TEncoding。如果 XML 未在 TEncoding 实现的相同字符集中编码,则 XML 将无法正确解码。请改用 TMemoryStreamTBytesStream,以按原样保留原始 XML 字节。

  3. XML 在编码方面是自我描述的。不要告诉 TXMLDocument 它应该使用的编码,让 XML 自己告诉 TXMLDocument 使用哪种编码。

试试这个:

idhttps := TIdHTTP.Create();
idhttps.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(idhttps);
idhttps.HandleRedirects := True;
idhttps.ConnectTimeout := 5000;
idhttps.Request.USERNAME := 'USERNAME';
idhttps.Request.PASSWORD := 'PASSWORD';
idhttps.Request.BasicAuthentication := True;
idhttps.Request.Accept := 'text/xml';

MS := TMemoryStream.Create;
try
  idhttps.Get(URL, MS);
  MS.Position := 0;
  XMLDoc := TXMLDocument.Create(nil); // XMLDoc must be IXMLDocument, or a memory leak occurs
  XMLDoc.LoadFromStream(MS);
finally
  MS.Free;
end;

现在,TXMLDocument 应该解析服务器实际发送的原始字节,事先没有 TIdHTTP 或 RTL 的任何解释。

如果您仍然遇到同样的问题,那么要么是 XML 本身没有正确编码,要么是 processing/displaying 在 XML 编码之后没有正确编码已加载到 TXMLDocument。你还没有显示,所以我们只能猜测你的实际问题出在哪里,除了我上面提到的。