【发布时间】:2012-04-14 07:08:45
【问题描述】:
我正在从 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:
表示解析后的响应实体主体。
如果响应实体正文不是有效的 XML,则此属性返回已解析的 DOMDocument,以便您可以访问错误。此属性本身不返回 IXMLDOMParseError,但可从 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', szUrl, False, '', '');
http.send(EmptyParam);
Assert(http.Status = 200);
doc := http.responseXml as DOMDocument60;
Assert(doc.parseError.errorCode = 0);
ShowMessage('"'+doc.xml+'"');
end;
我如何使XmlHttpRequest(更重要的是ServerXMLHTTP60)的行为符合记录?
【问题讨论】:
-
Delphi 版本信息是所有涉及 RTL 和标准库的问题的关键。什么版本?
-
我没有使用 Delphi 的任何组件,而是 Delphi 5。
-
相关:stackoverflow.com/questions/8925798/… - 注意 Keepalive 评论。试过了吗?另外,什么 IE 版本和 MS XML 版本,因为这些在这些情况下也很重要。我相信 MS XML 的 HTTP 方法使用 WinInet,它有一些有趣的错误,并且当你更新 IE 时它会更新。
-
@WarrenP 我尝试了超时;它不会改变结果(也不应该,因为我得到了有效的响应)。 ie9,msxml 6.0。如果您复制粘贴最终的简化 8 行版本,您会得到相同的行为吗?
-
我认为这与您使用 DOMDocument60 而不是
http.responseText有关。
标签: xml delphi xmlhttprequest delphi-5 serverxmlhttp