当responseText包含有效的Xml时,IXMLHttpRequest.responseXml为空,没有解析错误

前端之家收集整理的这篇文章主要介绍了当responseText包含有效的Xml时,IXMLHttpRequest.responseXml为空,没有解析错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我从 a government web-site获取一些XML:
http://www.bankofcanada.ca/stats/assets/rates_RSS/noon/en_all.xml

我正在使用以下相当简单的代码

var
   szUrl: string;
   http: IXMLHTTPRequest;
begin
   szUrl := 'http://www.bankofcanada.ca/stats/assets/rates_RSS/noon/en_all.xml';

   http := CoXMLHTTP60.Create;
   http.open('GET',szUrl,False,'','');
   http.send(EmptyParam);

   Assert(http.Status = 200);

   Memo1.Lines.Add('HTTP/1.1 '+IntToStr(http.status)+' '+http.statusText);
   Memo1.Lines.Add(http.getAllResponseHeaders);
   Memo1.Lines.Add(http.responseText);

我不会显示返回的所有正文,但它会在responseText中返回有效的xml:

HTTP/1.1 200 OK
Cache-Control: max-age=5
Connection: keep-alive
Connection: Transfer-Encoding
Date: Fri,30 Mar 2012 14:50:50 GMT
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Expires: Fri,30 Mar 2012 14:50:55 GMT
Server: Apache/2.2.16 (Unix) PHP/5.3.3 mod_ssl/2.2.16 OpenSSL/1.0.0d mod_perl/2.0.4 Perl/v5.12.0
X-Powered-By: PHP/5.3.3


<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-Syntax-ns#"
    xmlns="http://purl.org/RSS/1.0/"
    xmlns:cb="http://www.cbwiki.net/wiki/index.PHP/Specification_1.1"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:dcterms="http://purl.org/dc/terms/"
    xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.w3c.org/1999/02/22-rdf-Syntax-ns#rdf.xsd">
    <channel rdf:about="http://www.bankofcanada.ca/stats/assets/rates_RSS/noon/en_ALL.xml">
        <title xml:lang="en">Bank of Canada: Noon Foreign Exchange Rates</title>
        <link>http://www.bankofcanada.ca/rates/exchange/noon-rates-5-day/</link>

好的,很好,那里有有效的xml.我知道这是有效的,因为……好好看看它.但我也知道通过解析它是有效的:

var
   ...
   szXml: WideString;
   doc: DOMDocument60;
begin
   ...
   szXml := http.responseText;

   doc.loadXML(szXml);
   Assert(doc.parseError.errorCode = 0);

   Memo1.Lines.Add('============parsed xml');
   Memo1.Lines.Add(doc.xml);

原始IXmlHttpRequest包含responseXml财产.来自MSDN:

Represents the parsed response entity body.

If the response entity body is not valid XML,this property returns DOMDocument that was parsed so that you can access the error. This property does not return IXMLDOMParseError itself,but it is accessible from DOMDocument.

在我的情况下,responseXml属性存在,因为它应该:

Assert(http.responseXml <> nil);

并且没有responseText的解析错误

doc := http.responseXml as DOMDocument60;
Assert(doc.parseError.errorCode = 0);

应该有,因为xml是有效的.

除了当我查看http.responseXml文档对象时,它是空的:

Memo1.Lines.Add('============responseXml');
   Memo1.Lines.Add(doc.xml);

是时IXMLHttpRequest(和IXMLServerHttpRequest)返回一个空的XML文档,时间为:

>有xml
> xml有效
>没有解析错误

长形式:

uses
    msxml2_tlb;

procedure TForm1.Button1Click(Sender: TObject);
var
    szUrl: string;
    http: IXMLHTTPRequest;
    doc: DOMDocument60;
begin
    szUrl := 'http://www.bankofcanada.ca/stats/assets/rates_RSS/noon/en_all.xml';

    http := CoXMLHTTP60.Create; //or CoServerXmlHttpRequest.Create
    http.open('GET','');
    http.send(EmptyParam);

    Assert(http.Status = 200);

    doc := http.responseXml as DOMDocument60;
    Assert(doc.parseError.errorCode = 0);

    ShowMessage('"'+doc.xml+'"');
end;

我如何使XmlHttpRequest(更重要的是ServerXMLHTTP60)表现得像记录的那样?

我发现了这个问题

我用Fiddler将http响应保存到文本文件中.之后我可以修改响应文件,并指示fiddler提供我手工制作的替代品,而不是去原始的网站.

经过3个小时的摆弄,我设法在原始的http响应标头中追踪问题:

HTTP/1.1 200 OK
Cache-Control: max-age=5
Connection: keep-alive
Connection: Transfer-Encoding
Date: Fri,30 Mar 2012 14:50:55 GMT
Server: Apache/2.2.16 (Unix) PHP/5.3.3 mod_ssl/2.2.16 OpenSSL/1.0.0d mod_perl/2.0.4 Perl/v5.12.0
X-Powered-By: PHP/5.3.3

应该:

HTTP/1.1 200 OK
Cache-Control: max-age=5
Connection: keep-alive
Connection: Transfer-Encoding
Date: Fri,30 Mar 2012 14:50:50 GMT
Transfer-Encoding: chunked
Content-Type: text/xml; charset=UTF-8
Expires: Fri,30 Mar 2012 14:50:55 GMT
Server: Apache/2.2.16 (Unix) PHP/5.3.3 mod_ssl/2.2.16 OpenSSL/1.0.0d mod_perl/2.0.4 Perl/v5.12.0
X-Powered-By: PHP/5.3.3

一旦我发现问题,我就能找回the documentation that explain the behavior

The supported MIME types for MSXML 6.0 are:

  • text/xml
  • application/xml
  • or anything that ends with “+xml“,for example “application/RSS+xml

我正在提取RSS源实际上是Resource Definition Format (RDF) feed,其中内容类型应该是:

application/rdf+xml

他们的用途:

text/html

这么多级别都是错的.

所以我所经历的行为是设计的;虽然令人沮丧 – 因为没有简单的方法来知道responseXml是否“有效”.

>将分配responseXml对象>将分配parseError对象> parseError.ErrorCode为零> responseXml.documentElement将为nil

猜你在找的XML相关文章