我通过php向外部Web服务进行SOAP调用。我终于有了它的工作。最后一步是解析SOAP服务的响应。
当我这样做时:
echo '{"reference": "'.$client->__getLastResponse().'", "success":"true"}';
我希望得到并且我看到HTML网页响应:
{"reference": "000002R5281191606961", "success":"true"}
然而,当我查看开发人员工具源/预览时,我看到了:
{"reference": "<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetPaynetReferenceResponse xmlns="http://www.paynet.com.mx/"><GetPaynetReferenceResult><RespCode>0</RespCode><RespDesc /><PaynetReference>00002R5281191606961</PaynetReference></GetPaynetReferenceResult></GetPaynetReferenceResponse></soap:Body></soap:Envelope>", "success":"true"}
我需要的变量就是大量的XML内容!我怎样才能拉出所需的变量,并将其作为json返回?
如果有帮助,请点击这里:
$wsdl = 'http://201.147.99.51//PaynetCE/WSPaynetReference.asmx?WSDL';
$trace = true;
$exceptions = false;
$client = new SoapClient($wsdl, array('trace' => $trace, 'exceptions' => $exceptions));
$response = $client->__soapCall("GetPaynetReference", array($data));
echo"<pre>";
print_r($client);
echo"</pre>";
echo"<pre>";
print_r($client->__last_response);
echo"</pre>";
这一切似乎都有效,我在html / php页面中得到以下输出:
SoapClient Object
(
[trace] => 1
[_exceptions] =>
[_soap_version] => 1
[sdl] => Resource id #2
[__last_request] =>
3c090569-1044-48a8-9bc3-de3c8db22a80Recarga tu saldo Elepago.NUMCLIENTE528119160696
[httpsocket] => Resource id #3
[_use_proxy] => 0
[httpurl] => Resource id #4
[__last_request_headers] => POST /PaynetCE/WSPaynetReference.asmx HTTP/1.1
Host: 201.147.99.51
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.4.4
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://www.paynet.com.mx/GetPaynetReference"
Content-Length: 626
[__last_response_headers] => HTTP/1.1 200 OK
Date: Wed, 07 May 2014 23:57:45 GMT
Server: Microsoft-IIS/6.0
X-UA-Compatible: IE=EmulateIE7
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 478
[__last_response] => 000002R5281122606961
)
000002R5281122606961
__last_response是我需要的代码。我试图将其作为JSON发送。
当我在页面的预览/来源查看开发人员工具时,我得到了这个:
<pre>SoapClient Object
(
[trace] => 1
[_exceptions] =>
[_soap_version] => 1
[sdl] => Resource id #2
[__last_request] => <?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.paynet.com.mx/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><ns1:GetPaynetReference><ns1:issuerCod>3c090569-1044-48a8-9bc3-de3c8db22a80</ns1:issuerCod><ns1:description>Recarga tu saldo Elepago.</ns1:description><ns1:params><ns1:Parameter><ns1:Name>NUMCLIENTE</ns1:Name><ns1:Value xsi:type="xsd:string">528119160696</ns1:Value></ns1:Parameter></ns1:params></ns1:GetPaynetReference></SOAP-ENV:Body></SOAP-ENV:Envelope>
[httpsocket] => Resource id #3
[_use_proxy] => 0
[httpurl] => Resource id #4
[__last_request_headers] => POST /PaynetCE/WSPaynetReference.asmx HTTP/1.1
Host: 201.147.99.51
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.4.4
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://www.paynet.com.mx/GetPaynetReference"
Content-Length: 626
[__last_response_headers] => HTTP/1.1 200 OK
Date: Wed, 07 May 2014 23:57:45 GMT
Server: Microsoft-IIS/6.0
X-UA-Compatible: IE=EmulateIE7
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 478
[__last_response] => <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetPaynetReferenceResponse xmlns="http://www.paynet.com.mx/"><GetPaynetReferenceResult><RespCode>0</RespCode><RespDesc /><PaynetReference>00002R5281191606961</PaynetReference></GetPaynetReferenceResult></GetPaynetReferenceResponse></soap:Body></soap:Envelope>
)
</pre><pre><?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetPaynetReferenceResponse xmlns="http://www.paynet.com.mx/"><GetPaynetReferenceResult><RespCode>0</RespCode><RespDesc /><PaynetReference>00002R5281191606961</PaynetReference></GetPaynetReferenceResult></GetPaynetReferenceResponse></soap:Body></soap:Envelope></pre>
答案 0 :(得分:2)
使用SimpleXMLElement::xpath
方法和以下路径......
/soap:Envelope/soap:Body/a:GetPaynetReferenceResponse/a:GetPaynetReferenceResult/a:PaynetReference/text()
使用SimpleXMLElement::registerXPathNamespace
注册以下名称空间前缀后:
Prefix Namespace
------ ---------
xsi http://www.w3.org/2001/XMLSchema-instance
xsd http://www.w3.org/2001/XMLSchema
soap http://schemas.xmlsoap.org/soap/envelope/
xml http://www.w3.org/XML/1998/namespace
a http://www.paynet.com.mx/
采用这种方法,转换......
echo '{"reference": "'.$client->__getLastResponse().'", "success":"true"}';
......如下:
$xml = new SimpleXMLElement($client->__getLastResponse());
$xml->registerXPathNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$xml->registerXPathNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
$xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('xml', 'http://www.w3.org/XML/1998/namespace');
$xml->registerXPathNamespace('a', 'http://www.paynet.com.mx/');
$xpath = '/soap:Envelope/soap:Body/a:GetPaynetReferenceResponse/a:GetPaynetReferenceResult/a:PaynetReference/text()';
$result = $xml->xpath($xpath);
if ($result != FALSE && count($result) > 0) {
echo '{"reference": "' . $result[0] . '", "success":"true"}';
} else {
// TODO: Whatever....
}
修改强>
为了清楚地了解我如何检查这个解决方案,这里是我所描绘的PoC,而不能使用$client->__getLastResponse()
本身:
<html>
<head><title>PoC Page</title></head>
<body>
<?php
// FORNOW - Use $lastResponse since I can't really use $client->__getLastResponse() for a PoC.
$lastResponse = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetPaynetReferenceResponse xmlns="http://www.paynet.com.mx/"><GetPaynetReferenceResult><RespCode>0</RespCode><RespDesc /><PaynetReference>00002R5281191606961</PaynetReference></GetPaynetReferenceResult></GetPaynetReferenceResponse></soap:Body></soap:Envelope>';
$xml = new SimpleXMLElement($lastResponse);
//$xml = new SimpleXMLElement($client->__getLastResponse());
$xml->registerXPathNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$xml->registerXPathNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
$xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('xml', 'http://www.w3.org/XML/1998/namespace');
$xml->registerXPathNamespace('a', 'http://www.paynet.com.mx/');
$xpath = '/soap:Envelope/soap:Body/a:GetPaynetReferenceResponse/a:GetPaynetReferenceResult/a:PaynetReference/text()';
$result = $xml->xpath($xpath);
if ($result != FALSE && count($result) > 0) {
echo '{"reference": "' . $result[0] . '", "success":"true"}';
} else {
// TODO: Whatever....
}
?>
</body>
</html>
答案 1 :(得分:0)
感谢J0e3gan的回答!工作完美。我还发现这种替代方案效果很好。基本上创建一个新的DOM,然后抓住标签内部的内容。
$doc = new DOMDocument('1.0', 'utf-8');
$doc->loadXML( $soapResponse );
$XMLresults = $doc->getElementsByTagName("SearchFlightAvailability33Response");
$output = $XMLresults->item(0)->nodeValue;