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

qncylg1j  于 2023-01-16  发布在  PHP
关注(0)|答案(8)|浏览(137)

我无法在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>;

我使用了以下方法转换为Array,但得到的输出为空。

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

请给我点建议。

fhity93d

fhity93d1#

使用前面方法的组合,可以轻松地将以下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
                        )

                )

        )

)
xkrw2x1b

xkrw2x1b2#

我找到了一个完美的解决方案来解析数组的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()

它将为您提供一个完美的SOAPXML数据数组。

zz2j4svz

zz2j4svz3#

最后我找到了解决办法
我们可以通过以下方式从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;
ergxz8rk

ergxz8rk4#

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

q1qsirdb5#

我用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;
flseospp

flseospp6#

@gtrujillos的第二个答案对我来说很有效,但做了一些修改,因为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>';
khbbv19g

khbbv19g7#

SOAP可以作为XML来阅读,但是你应该考虑名称空间。这对于PHPs 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>
    &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)'));
r6hnlfcb

r6hnlfcb8#

在我的例子中,我使用了$body = $xml-〉xpath('//soapBody')[0];

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

相关问题