如何将 SOAP 响应转换为 PHP 数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21777075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert SOAP response to PHP Array?
提问by raheem.unr
I am unable to convert SOAP response to Array in php.
我无法在 php 中将 SOAP 响应转换为数组。
here is the code
这是代码
$response = $client->__doRequest($xmlRequest,$location,$action,1);
here is the SOAP response.
这是 SOAP 响应。
<soap:envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:body>
<searchflightavailability33response xmlns="http://FpwebBox.Fareportal.com/Gateway.asmx">
<searchflightavailability33result>
<Fareportal><FpSearch_AirLowFaresRS><CntKey>1777f5a7-7824-46ce-a0f8-33d5e6e96816</CntKey><Currency CurrencyCode="USD"/><OriginDestinationOptions><OutBoundOptions><OutBoundOption segmentid="9W7008V21Feb14"><FlightSegment etc....
</searchflightavailability33result>
</searchflightavailability33response>
</soap:body>
</soap:envelope>;
i used the following ways to convert to Array,but i am getting empty output.
我使用以下方法转换为数组,但输出为空。
1.echo '<pre>';print_r($client__getLastResponse());
2.echo '<pre>';print_r($response->envelope->body->searchflightavailability33response);
3.echo '<pre>';print_r($client->SearchFlightAvailability33($response));
4.simplexml_load_string($response,NULL,NULL,"http://schemas.xmlsoap.org/soap/envelope/");
5.echo '<pre>';print_r($client->SearchFlightAvailability33($response));
please advice me.
请给我建议。
采纳答案by raheem.unr
finally i found the solution is
最后我发现解决方案是
we can get body of the response from SOAP the following ways
我们可以通过以下方式从 SOAP 获取响应正文
example1:
示例1:
$xml = new SimpleXMLElement($soapResponse);
foreach($xml->xpath('//soap:body') as $header) {
$output = $header->registerXPathNamespace('default', 'http://FpwebBox.Fareportal.com/Gateway.asmx');
}
example2:
例子2:
$doc = new DOMDocument('1.0', 'utf-8');
$doc->loadXML( $soapResponse );
$XMLresults = $doc->getElementsByTagName("SearchFlightAvailability33Response");
$output = $XMLresults->item(0)->nodeValue;
回答by gtrujillos
The following SOAP response structure can be easily converted in an array using a combination of the previous methods. Using only the the function "simplexml_load_string" removing the colon ":" it returned null in some cases.
使用前面的方法的组合,可以轻松地将以下 SOAP 响应结构转换为数组。仅使用函数“simplexml_load_string”删除冒号“:”,在某些情况下它返回 null。
SOAP Response
SOAP 响应
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:transaccionResponse
xmlns:ns2="http://ws.iatai.com/">
<respuestaTransaccion>
<idTransaccion>94567</idTransaccion>
<referencia>3958</referencia>
<idEstado>3</idEstado>
<nombreEstado>Declinada</nombreEstado>
<codigoRespuesta>202</codigoRespuesta>
<valor>93815.0</valor>
<iva>86815.0</iva>
<baseDevolucion>0.0</baseDevolucion>
<isoMoneda>COP</isoMoneda>
<fechaProcesamiento>24-07-2015 12:18:40 PM</fechaProcesamiento>
<mensaje>REJECT</mensaje>
<tarjetaRespuesta>
<idFranquicia>1</idFranquicia>
<nombreFranquicia>VISA</nombreFranquicia>
<numeroBin>411111</numeroBin>
<numeroProducto>1111</numeroProducto>
</tarjetaRespuesta>
<procesadorRespuesta>
<idProcesador>3</idProcesador>
</procesadorRespuesta>
</respuestaTransaccion>
</ns2:transaccionResponse>
</S:Body>
</S:Envelope>
PHP conversion:
PHP转换:
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "", $response);
$xml = new SimpleXMLElement($response);
$body = $xml->xpath('//SBody')[0];
$array = json_decode(json_encode((array)$body), TRUE);
print_r($array);
Result:
结果:
Array
(
[ns2transaccionResponse] => Array
(
[respuestaTransaccion] => Array
(
[idTransaccion] => 94567
[referencia] => 3958
[idEstado] => 3
[nombreEstado] => Declinada
[codigoRespuesta] => 202
[valor] => 93815.0
[iva] => 86815.0
[baseDevolucion] => 0.0
[isoMoneda] => COP
[fechaProcesamiento] => 24-07-2015 12:18:40 PM
[mensaje] => REJECT
[tarjetaRespuesta] => Array
(
[idFranquicia] => 1
[nombreFranquicia] => VISA
[numeroBin] => 411111
[numeroProducto] => 1111
)
[procesadorRespuesta] => Array
(
[idProcesador] => 3
)
)
)
)
回答by Irshad Khan
I found a perfect solution to parse SOAP response to an Array:
我找到了一个完美的解决方案来解析一个数组的 SOAP 响应:
$plainXML = mungXML( trim($soapXML) );
$arrayResult = json_decode(json_encode(SimpleXML_Load_String($plainXML, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
// FUNCTION TO MUNG THE XML SO WE DO NOT HAVE TO DEAL WITH NAMESPACE
function mungXML($xml)
{
$obj = SimpleXML_Load_String($xml);
if ($obj === FALSE) return $xml;
// GET NAMESPACES, IF ANY
$nss = $obj->getNamespaces(TRUE);
if (empty($nss)) return $xml;
// CHANGE ns: INTO ns_
$nsm = array_keys($nss);
foreach ($nsm as $key)
{
// A REGULAR EXPRESSION TO MUNG THE XML
$rgx
= '#' // REGEX DELIMITER
. '(' // GROUP PATTERN 1
. '\<' // LOCATE A LEFT WICKET
. '/?' // MAYBE FOLLOWED BY A SLASH
. preg_quote($key) // THE NAMESPACE
. ')' // END GROUP PATTERN
. '(' // GROUP PATTERN 2
. ':{1}' // A COLON (EXACTLY ONE)
. ')' // END GROUP PATTERN
. '#' // REGEX DELIMITER
;
// INSERT THE UNDERSCORE INTO THE TAG NAME
$rep
= '' // BACKREFERENCE TO GROUP 1
. '_' // LITERAL UNDERSCORE IN PLACE OF GROUP 2
;
// PERFORM THE REPLACEMENT
$xml = preg_replace($rgx, $rep, $xml);
}
return $xml;
}
print_r($arrayResult);
It will give you a perfect array of SOAP XML Data.
它将为您提供一组完美的 SOAP XML 数据。
回答by Amuk Saxena
Php parse SOAP response to an array
Php 解析 SOAP 响应到一个数组
$xml = file_get_contents($response);
// SimpleXML seems to have problems with the colon ":" in the <xxx:yyy> response tags, so take them out
$xml = preg_replace(“/(<\/?)(\w+):([^>]*>)/”, “″, $xml);
$xml = simplexml_load_string($xml);
$json = json_encode($xml);
$responseArray = json_decode($json,true);
回答by user2977753
I got a single value using DOMDocument.
我使用 DOMDocument 得到了一个值。
$soap_response = $client->__getLastResponse();
$dom_result = new DOMDocument;
if (!$dom_result->loadXML($soap_response))
throw new Exception(_('Error parsing response'), 11);
$my_val = $dom_result->getElementsByTagName('my_node')->item(0)->nodeValue;
回答by Aleli Sanchez Mendez
The second answer from @gtrujillos worked for me but with some changes, because the json string needs more formatting code in my case and the xPath needs to be in this way "//S:Body". This is the code that finally solve my problem. I toke the same SOAP Response example and the code for getting and returning a Soap response I found it here:
@gtrujillos 的第二个答案对我有用,但有一些变化,因为在我的情况下 json 字符串需要更多的格式化代码,而 xPath 需要以这种方式“//S:Body”。这是最终解决我的问题的代码。我使用了相同的 SOAP 响应示例以及用于获取和返回我在此处找到的 Soap 响应的代码:
PHP convertion
PHP转换
//getting the Soap Response
header("Content-Type: text/xml\r\n");
ob_start();
$capturedData = fopen('php://input', 'rb');
$content = fread($capturedData, 5000);
fclose($capturedData);
ob_end_clean();
//getting the SimpleXMLElement object
$xml = new SimpleXMLElement($content);
$body = $xml->xpath('//S:Body')[0];
//transform to json
$json = json_encode((array)$body);
//Formatting the JSON
$json = str_replace(array("\n","\r","?"),"",$Json);
$json = preg_replace('/([{,]+)(\s*)([^"]+?)\s*:/','"":',$json);
$Json = preg_replace('/(,)\s*}$/','}',$json);
//Getting the array
$array=json_decode($Json,true);
//whatever yo need to do with the array ...
//Return a Soap Response
$returnedMsg=true;//this will depend of what do you need to return
print '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<notifications xmlns="http://soap.sforce.com/2005/09/outbound">
<Ack>' . $returnedMsg . '</Ack>
</notifications>
</soapenv:Body>
</soapenv:Envelope>';
回答by ThW
SOAP can be read as just XML but you should take the namespaces into consideration. This is not difficult with PHPs DOM. In your example the SOAP uses a namespace for the inner nodes and the {http://FpwebBox.Fareportal.com/Gateway.asmx}searchflightavailability33resultelement contains another XML document as text content.
SOAP 可以仅作为 XML 读取,但您应该考虑名称空间。这对于 PHP DOM 来说并不困难。在您的示例中,SOAP 为内部节点使用命名空间,并且该{http://FpwebBox.Fareportal.com/Gateway.asmx}searchflightavailability33result元素包含另一个 XML 文档作为文本内容。
$xml = <<<'XML'
<soap:envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:body>
<searchflightavailability33response xmlns="http://FpwebBox.Fareportal.com/Gateway.asmx">
<searchflightavailability33result>
<Fareportal><FpSearch_AirLowFaresRS><CntKey>1777f5a7-7824-46ce-a0f8-33d5e6e96816</CntKey><Currency CurrencyCode="USD"/></FpSearch_AirLowFaresRS></Fareportal>
</searchflightavailability33result>
</searchflightavailability33response>
</soap:body>
</soap:envelope>
XML;
// define a constant for the namespace URI
const XMLNS_FPW = 'http://FpwebBox.Fareportal.com/Gateway.asmx';
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
// register a prefix for the namespace
$xpath->registerNamespace('fpw', XMLNS_FPW);
// read the result element text content
$result = $xpath->evaluate('string(//fpw:searchflightavailability33result)');
var_dump($result);
// load the result string as XML
$innerDocument = new DOMDocument();
$innerDocument->loadXML($result);
$innerXpath = new DOMXpath($innerDocument);
// read data from it
var_dump($innerXpath->evaluate('string(//CntKey)'));

