Delphi idhttp破字

时间:2015-02-06 03:31:15

标签: xml delphi encoding idhttp

我正在使用IDHTTP处理Delphi XE5和从服务器获取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中,项目符号点如下所示:

  

?过敏反应/过敏反应:可能引起过敏反应,

XML标题如下:

<?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>

看起来我提供了错误的信息。我附加了捕获的xml片段。第一个是使用rest客户端工具从浏览器获取的结果,最后一个是获取xml到idhttp的结果。

Getting XML from browser by using rest client tool.

Getting XML thru idhttp

1 个答案:

答案 0 :(得分:5)

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

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

  3. XML在编码时是自描述的。不要告诉TXMLDocument它应该使用的编码,让XML本身告诉TXMLDocument使用哪种编码。

  4. 试试这个:

    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本身就没有正确编码,或者您在加载到TXMLDocument后没有正确处理/显示XML。你还没有展示过,所以我们只能猜出你的实际问题在哪里,除了我上面提到的。