2014-11-14 25 views
2

我使用的是从Microsoft XML类型库生成MSXML2_TLB.pas调用一个非常简单的Web服务支持的字符集,所以我并不需要完整的XML包装,只是这样做:MSXML:XMLHTTP无法从头

var 
    r:XMLHTTP; 
begin 
    r:=CoXMLHTTP.Create; 
    r.open('POST',WebServiceURL,false,'',''); 
    r.setRequestHeader('Content-Type','application/xml'); 
    r.send('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" '+ 
    'xmlns:ns="http://somebigcorporation.com/api/ws1/">'+ 
    '<soapenv:Body>'+ 
    //snip: irrelevant to the question 
    '</soapenv:Body></soapenv:Envelope>'); 

    if r.status<>200 then raise Exception.Create(r.statusText); 
    Result:=(r.responseXML as DOMDocument).documentElement.firstChild.firstChild.selectSingleNode('importantData'); 
end; 

webservice很好地响应状态200和Content-Type: text/xml; charset=iso-8859-1

在某些情况下,documentElement为零(并且上面的代码会引发访问冲突)。显然responseXML存在,但只提供parseError对象(它在the docs中如此表示),而parseError.reason在这些情况下为An invalid character was found in text content.

为什么解析器没有从响应头中获取'charset'值?有没有办法告诉XMLHTTP实例使用响应头中的字符集值?

更新:我不知道这是否是重要的,但响应也不会<?xml开始,即使它确实我也没办法,请求/修改它,所以它会有一个encoding="iso-8859-1"属性。

+0

你说*响应也不是以<?xml *开头,那么甚至是有效的XML?或者你的意思是序言不包含编码?如果是后者,恐怕你运气不好,*为了可靠处理,使用UTF-8或UTF-16以外的字符编码的XML文档必须在XML声明中包含一个编码声明。*(['Source '](http://msdn.microsoft.com/en-us/library/ms757065(v = vs.85).aspx)) – TLama 2014-11-14 15:54:26

+0

发布它作为答案,所以我可以接受它。 – 2014-11-14 16:00:51

+0

@StijnSanders,你可以使用'r.responseText'(修改它,因为你希望包含char-set声明)并将其加载到一个新的XMLDOC中,而不是直接使用'responseXML'对象。 – kobik 2014-11-15 09:46:17

回答

0

我认为你需要在请求中设置字符集,所以结果是正确的。

r.setRequestHeader('Content-Type', 'application/xml; charset=ISO-8859-1'); 
+0

结果_is_正确。请求也被正确处理,我将请求主体编码留给XMLHTTP对象。我怀疑设置请求内容类型会影响响应内容类型。这是XMLHTTP显然误解了响应的编码问题。 – 2014-11-14 15:44:21

+1

@StijnSanders,这不是你的问题的核心,但无论如何你应该*指定你的请求'Content-Type'。网络服务*可能会预期(并处理)这一点。例如,如果您指定的内容类型为UTF8的请求,则可能会惊讶地发现服务器对UTF8的响应也是如此。例如ASMX .net网络服务就是如此。 – kobik 2014-11-15 11:59:58