I am extracting some XML from a government website :
http://www.bankofcanada.ca/stats/assets/rates_rss/noon/en_all.xml
I use the following rather simple code:
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);
i will not display the whole returned body, but it returns a valid xml in responseText :
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>
Good, great, there is xml. I know this is true because ... well, just look at that. But I also know that it is valid by analyzing it:
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);
The original IXmlHttpRequest contains the responseXml property. From MSDN:
Represents the body of a parsed object.
If the body of the response object is not valid XML, this property returns the DOMDocument that was parsed so that you can access the error. This property does not return IXMLDOMParseError itself, but it is available from DOMDocument.
In my case, the responseXml property exists, as it should:
Assert(http.responseXml <> nil);
And there is no responseText parsing error:
doc := http.responseXml as DOMDocument60; Assert(doc.parseError.errorCode = 0);
as it should be, since xml is valid.
Also, when I look at the http.responseXml document http.responseXml , it is empty:
Memo1.Lines.Add('============responseXml'); Memo1.Lines.Add(doc.xml);
Is is IXMLHttpRequest (and IXMLServerHttpRequest) returns an empty XML document when:
- there is xml
- xml is valid
- missing parsing error
In long form:
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;
How do XmlHttpRequest (and more importantly ServerXMLHTTP60 ) behave as documented?