web-dev-qa-db-ja.com

SOAP response to PHP Array?

SOAP PHPの配列への応答を変換できません。

ここにコードがあります

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

次の方法で配列に変換しましたが、空の出力が得られます。

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

アドバイスしてください。

16
raheem.unr

最後に、私は解決策が見つかった

SOAP以下の方法で応答の本文を取得できます

例1:

$xml = new SimpleXMLElement($soapResponse);
foreach($xml->xpath('//soap:body') as $header) {
    $output = $header->registerXPathNamespace('default', 'http://FpwebBox.Fareportal.com/Gateway.asmx');    
}

例2:

$doc = new DOMDocument('1.0', 'utf-8');
    $doc->loadXML( $soapResponse );
    $XMLresults     = $doc->getElementsByTagName("SearchFlightAvailability33Response");
    $output = $XMLresults->item(0)->nodeValue;
13
raheem.unr

次のSOAP応答構造は、前のメソッドの組み合わせを使用して配列内で簡単に変換できます。コロン「:」を削除する「simplexml_load_string」関数のみを使用すると、nullが返される場合がありました。

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変換:

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

                )

        )

)
32
gts

解析するための完璧なソリューションが見つかりましたSOAP配列への応答:

$plainXML = mungXML($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
        = '$1'          // 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);

これにより、SOAP XMLデータの完全な配列が得られます。

13
Irshad Khan

Php parse 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+):([^>]*>)/”, “$1$2$3″, $xml);
$xml = simplexml_load_string($xml);
$json = json_encode($xml);
$responseArray = json_decode($json,true);
9
Amuk Saxena

@gtrujillosからの2番目の答えは私にとってはうまくいきましたが、json文字列にはもっと多くのフォーマットコードが必要であり、xPathはこのように「// S:Body」である必要があるため、多少の変更がありましたこれが最終的に私の問題を解決するコードです。私は同じSOAP応答の例と、SOAP応答を取得および返すためのコードを見つけました here

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*:/','$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>';

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;
1
user2977753