Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将SOAP响应转换为PHP数组?_Php_Xml_Soap_Soap Client - Fatal编程技术网

如何将SOAP响应转换为PHP数组?

如何将SOAP响应转换为PHP数组?,php,xml,soap,soap-client,Php,Xml,Soap,Soap Client,我无法在php中将SOAP响应转换为数组 这是密码 $response = $client->__doRequest($xmlRequest,$location,$action,1); 下面是SOAP响应 <soap:envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schema

我无法在php中将SOAP响应转换为数组

这是密码

 $response = $client->__doRequest($xmlRequest,$location,$action,1);
下面是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>
    &lt;Fareportal&gt;&lt;FpSearch_AirLowFaresRS&gt;&lt;CntKey&gt;1777f5a7-7824-46ce-a0f8-33d5e6e96816&lt;/CntKey&gt;&lt;Currency CurrencyCode="USD"/&gt;&lt;OriginDestinationOptions&gt;&lt;OutBoundOptions&gt;&lt;OutBoundOption segmentid="9W7008V21Feb14"&gt;&lt;FlightSegment etc....
    </searchflightavailability33result>
</searchflightavailability33response>
</soap:body>
</soap:envelope>;

机票PortalFPSearch_AirLowFaresRSCntKey1777f5a7-7824-46ce-a0f8-33d5e6e96816/CntKeyCurrency CurrencyCode=“USD”/OriginationOptions OutboundOptions OutboundOption segmentid=“9W7008V21Feb14”航班段等。。。。
;
我使用以下方法转换为数组,但得到的是空输出

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));
1.echo';print_r($client__getLastResponse());
2.回音“;打印($response->信封->正文->SearchFlightAvailability 33response);
3.回音“;打印($client->SearchFlightAvailability 33($response));
4.simplexml\u load\u字符串($response,NULL,NULL,“http://schemas.xmlsoap.org/soap/envelope/");  
5.1“回声”;打印($client->SearchFlightAvailability 33($response));

请告诉我。

最后我发现解决方案是

我们可以通过以下方式从SOAP获得响应体

例1:

$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $response);
$xml = new SimpleXMLElement($response);
$body = $xml->xpath('//SBody')[0];
$array = json_decode(json_encode((array)$body), TRUE); 
print_r($array);
例2:

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
                        )

                )

        )

)

Php解析对数组的SOAP响应

$plainXML = mungXML( trim($soapXML) );
$arrayResult = json_decode(json_encode(SimpleXML_Load_String($plainXML, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

print_r($arrayResult);


// 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
        = '$1'          // BACKREFERENCE TO GROUP 1
        . '_'           // LITERAL UNDERSCORE IN PLACE OF GROUP 2
        ;
        // PERFORM THE REPLACEMENT
        $xml =  preg_replace($rgx, $rep, $xml);
    }

    return $xml;

} // End :: mungXML()
$xml=file\u get\u contents($response);
//SimpleXML似乎对响应标记中的冒号“:”有问题,所以请将它们去掉
$xml=preg_replace(“/(]*>)/”,“$1$2$3〃,$xml);
$xml=simplexml\u load\u字符串($xml);
$json=json_encode($xml);
$responseArray=json_decode($json,true);

以下SOAP响应结构可以使用前面的方法组合在一个数组中轻松转换。仅使用函数“simplexml\u load\u string”删除冒号:“在某些情况下,它返回null

SOAP响应

    $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;

我找到了解析对数组的SOAP响应的完美解决方案:

$plainXML=mungXML(trim($soapXML));
$arrayResult=json_decode(json_编码(SimpleXML_加载_字符串($plainXML,'SimpleXMLElement',LIBXML_NOCDATA)),true);
打印(arrayResult);
//函数来提取XML,这样我们就不必处理名称空间
函数mungXML($xml)
{
$obj=SimpleXML\u Load\u字符串($xml);
如果($obj==FALSE),则返回$xml;
//获取名称空间(如果有)
$nss=$obj->getnamespace(TRUE);
if(空($nss))返回$xml;
//将ns:更改为ns_
$nsm=阵列密钥($nss);
foreach($nsm作为$key)
{
//用于MUNG XML的正则表达式
$rgx
='#'//正则表达式分隔符
.('//组模式1

.\我使用DOMDocument获得了一个值


@gtrujillos的第二个答案对我来说很有用,但有一些改动,因为json字符串需要更多的格式化代码,xPath需要这样“//S:Body”。这是最终解决我问题的代码。我使用了相同的SOAP响应示例以及获取和返回SOAP响应的代码,我发现了:

PHP转换

//获取Soap响应
标题(“内容类型:text/xml\r\n”);
ob_start();
$capturedData=fopen('php://input","rb",;
$content=fread($capturedData,5000);
fclose($capturedata);
ob_end_clean();
//获取SimpleXMLElement对象
$xml=新的simplexmlement($content);
$body=$xml->xpath('//S:body')[0];
//转换为json
$json=json_encode((数组)$body);
//格式化JSON
$json=str_replace(数组(“\n”、“\r”、“?”、“,$json”);
$json=preg_replace('/([{,]+)(\s*)([^“]+?)\s*:/”,“$1”$3:”,$json);
$Json=preg_replace('/(,)\s*}$/','}',$Json);
//获取阵列
$array=json_decode($json,true);
//无论你需要对阵列做什么。。。
//返回Soap响应
$returnedMsg=true;//这取决于您需要返回什么
印刷品
“.$returnedMsg。”
';

SOAP可以仅作为XML读取,但您应该考虑名称空间。这对于PHPs DOM并不困难。在您的示例中,SOAP使用名称空间作为内部节点和
{http://FpwebBox.Fareportal.com/Gateway.asmx}searchflightavailability33result
元素包含另一个XML文档作为文本内容

$xml=evaluate('string(//fpw:searchflightavailability33result');
var_dump($结果);
//将结果字符串作为XML加载
$innerDocument=新的DOMDocument();
$innerDocument->loadXML($result);
$innerXpath=新的DOMXpath($innerDocument);
//从中读取数据
var_dump($innerXpath->evaluate('string(//CntKey)');

为什么不使用php SoapClient类(或者更好的是ZendSoap组件)?我第一次使用SOAP类时只使用了$client->\uu getLastResponse(),$client->SearchFlightAvailability33Response();但没有返回任何内容。正确的用法是:$yourData=$client->SearchFlightAvailability33();您好,我尝试了您给出的建议,但只得到了错误。请尝试{$response=$client->\uu doRequest($xmlRequest,$location,$action,1);//$response=$client->SearchFlightAvailability33($xmlRequest);//response=$client->\uu getlastress();//$result=$client->SearchFlightAvailability33($xmlRequest);echo'';print_r($client->SearchFlightAvailability33($res));}catch(异常$e){echo'';print_r($e->getMesage());}@lilobase,有时,人们被迫使用“不正确的”方法,因为API开发人员不遵循标准实践。我只是遇到了这个问题,必须扩展SoapClient类才能发送我自己的自定义XML。这不是“错误”当然,这不是正常的方式。如果xml响应中存在soapfault,那么它就不起作用了。如果您有任何想法,请告诉我。这是一个比预期答案更优雅的解决方案,而且效果非常好。谢谢。我唯一的指针是,如果您想要整个请求,而不仅仅是正文,请不要使用:
$xml->xpath(
只需执行:
json\u encode($xml)
如果您确实使用
$xml->xpath(
请记住使用发送给您身体的任何键,我的是
soapBody
而不是
sbbody$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $response);
$xml = new SimpleXMLElement($response);
$body = $xml->xpath('//SBody')[0];
$array = json_decode(json_encode((array)$body), TRUE); 
print_r($array);
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
                        )

                )

        )

)
$plainXML = mungXML( trim($soapXML) );
$arrayResult = json_decode(json_encode(SimpleXML_Load_String($plainXML, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

print_r($arrayResult);


// 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
        = '$1'          // BACKREFERENCE TO GROUP 1
        . '_'           // LITERAL UNDERSCORE IN PLACE OF GROUP 2
        ;
        // PERFORM THE REPLACEMENT
        $xml =  preg_replace($rgx, $rep, $xml);
    }

    return $xml;

} // End :: mungXML()
    $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;
//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*:/','$1"$3":',$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>';
$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>
    &lt;Fareportal&gt;&lt;FpSearch_AirLowFaresRS&gt;&lt;CntKey&gt;1777f5a7-7824-46ce-a0f8-33d5e6e96816&lt;/CntKey&gt;&lt;Currency CurrencyCode="USD"/&gt;&lt;/FpSearch_AirLowFaresRS&gt;&lt;/Fareportal&gt;
    </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)'));