我有一个基于wsdl的小型php soap服务器,它为DLNA请求提供服务。服务器代码看起来像成千上万的其他代码:
$srv = new SoapServer( "wsdl/upnp_av.wsdl" );
$srv->setClass( "ContentDirectory" );
$srv->handle();
而且起作用了。对于过程,它成功地返回SOAP响应:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:schemas-upnp-org:service:ContentDirectory:1">
<SOAP-ENV:Body>
<ns1:GetSearchCapabilitiesResponse>
<SearchCaps>*</SearchCaps>
</ns1:GetSearchCapabilitiesResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
这是绝对正确的xml语法。但我的大部分DLNA设备都不会接受这个答案(但东芝电视的效果很好)。因此,我从其他DLNA服务器上获取了Wireshark并跟踪了xml,并发现所有这些服务器都稍微返回了另一个xml,其名称空间定义在ns1体内,而不是在信封中。这是正确的示例行,所有设备都能很好地接受:
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:GetSearchCapabilitiesResponse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
<SearchCaps>*</SearchCaps>
</u:GetSearchCapabilitiesResponse>
</s:Body>
</s:Envelope>
因此,"ContentDirectory“xmlns刚从头移动到一个块。这两个xml在语法上都是正确的。
有些人也面临着同样的问题:
Problem with WSDL change soap prefixes in php Soap Response Namespace issue SoapServer maps functions incorectly when the wsdl messages have the same part name PHP Soap Server response formatting
经过2天的研究,我想出了解决办法,将绑定从文档更改为rpc方法:
<soap:binding style="document" --> <soap:binding style="rpc"
但是当我这样做的时候,php脚本只是在zend内部崩溃,所以我在access.log中有一行提到了发生了500个错误,但是它没有在error.log中显示--文件保持为空(当然,其他500个错误都很好地传递给了error.log )。
由于WSDL文件太大,我已经上传了WSDL文件:http://pastebin.com/ZNG4DqAn。
还有别的什么,我可以试着解决这个问题吗?
请记住,TV完全正确地处理了这个xml语法,而且一切都运行得很好,但是android手机可能会使用其他需要名称空间的xml解析器吗?现在,我已经准备好执行preg_replaces()操作,将该死的xmlns移到正确的位置:),但我认为这不是Jedie :)的路径。)
我的环境: PHP 5.4.20,Apache2.2,Windows 2012
发布于 2015-07-09 15:53:45
最后,我不会成为绝地,我做了人工替换,这是可行的。
function replace_xmlns( $soapXml )
{
$marker1 = "xmlns:ns1=";
$marker2 = "<ns1:";
$startpos = strpos( $soapXml, $marker1 );
$endpos = strpos( $soapXml, "\"", $startpos + 14 );
$namespace = substr( $soapXml, $startpos, $endpos - $startpos + 1 );
$soapXml = str_replace( $namespace, "", $soapXml );
$m2start = mb_strpos( $soapXml, $marker2 );
$m2end = mb_strpos( $soapXml, '>', $m2start );
$soapXml = substr_replace( $soapXml, " " . $namespace, $m2end, 0 );
return $soapXml;
}
https://stackoverflow.com/questions/31296296
复制相似问题