php 如何解析 SOAP XML?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4194489/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 12:15:24  来源:igfitidea点击:

How to parse SOAP XML?

phpxmlsoap

提问by Anton

SOAP XML:

SOAP XML:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <PaymentNotification xmlns="http://apilistener.envoyservices.com">
      <payment>
        <uniqueReference>ESDEUR11039872</uniqueReference>      
        <epacsReference>74348dc0-cbf0-df11-b725-001ec9e61285</epacsReference>
        <postingDate>2010-11-15T15:19:45</postingDate>
        <bankCurrency>EUR</bankCurrency>
        <bankAmount>1.00</bankAmount>
        <appliedCurrency>EUR</appliedCurrency>
        <appliedAmount>1.00</appliedAmount>
        <countryCode>ES</countryCode>
        <bankInformation>Sean Wood</bankInformation>
  <merchantReference>ESDEUR11039872</merchantReference>
   </payment>
    </PaymentNotification>
  </soap:Body>
</soap:Envelope>

How to get 'payment' element?

如何获得“付款”元素?

I try to parse (PHP)

我尝试解析(PHP)

$xml = simplexml_load_string($soap_response);
$xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
foreach ($xml->xpath('//payment') as $item)
{
    print_r($item);
}

Result is empty :( Any ideas how to parse it correct?

结果为空 :( 任何想法如何正确解析它?

回答by Aran

One of the simplest ways to handle namespace prefixes is simply to strip them from the XML response before passing it through to simplexml such as below:

处理命名空间前缀的最简单方法之一就是在将它们传递给 simplexml 之前将它们从 XML 响应中剥离,如下所示:

$your_xml_response = '<Your XML here>';
$clean_xml = str_ireplace(['SOAP-ENV:', 'SOAP:'], '', $your_xml_response);
$xml = simplexml_load_string($clean_xml);

This would return the following:

这将返回以下内容:

SimpleXMLElement Object
(
    [Body] => SimpleXMLElement Object
        (
            [PaymentNotification] => SimpleXMLElement Object
                (
                    [payment] => SimpleXMLElement Object
                        (
                            [uniqueReference] => ESDEUR11039872
                            [epacsReference] => 74348dc0-cbf0-df11-b725-001ec9e61285
                            [postingDate] => 2010-11-15T15:19:45
                            [bankCurrency] => EUR
                            [bankAmount] => 1.00
                            [appliedCurrency] => EUR
                            [appliedAmount] => 1.00
                            [countryCode] => ES
                            [bankInformation] => Sean Wood
                            [merchantReference] => ESDEUR11039872
                        )

                )

        )

)

回答by Ivan

PHP version > 5.0 has a nice SoapClient integrated. Which doesn't require to parse response xml. Here's a quick example

PHP 版本 > 5.0 集成了一个很好的 SoapClient。不需要解析响应xml。这是一个快速示例

$client = new SoapClient("http://path.to/wsdl?WSDL");
$res = $client->SoapFunction(array('param1'=>'value','param2'=>'value'));
echo $res->PaymentNotification->payment;

回答by Neeme Praks

In your code you are querying for the paymentelement in default namespace, but in the XML response it is declared as in http://apilistener.envoyservices.comnamespace.

在您的代码中,您正在查询payment默认命名空间中的元素,但在 XML 响应中,它被声明为在http://apilistener.envoyservices.com命名空间中。

So, you are missing a namespace declaration:

因此,您缺少命名空间声明

$xml->registerXPathNamespace('envoy', 'http://apilistener.envoyservices.com');

Now you can use the envoynamespace prefix in your xpath query:

现在您可以envoy在 xpath 查询中使用命名空间前缀:

xpath('//envoy:payment')

The full code would be:

完整的代码是:

$xml = simplexml_load_string($soap_response);
$xml->registerXPathNamespace('envoy', 'http://apilistener.envoyservices.com');
foreach ($xml->xpath('//envoy:payment') as $item)
{
    print_r($item);
}

Note: I removed the soapnamespace declaration as you do not seem to be using it (it is only useful if you would use the namespace prefix in you xpath queries).

注意:我删除了soap命名空间声明,因为您似乎没有使用它(只有在 xpath 查询中使用命名空间前缀时才有用)。

回答by B?o Nam

$xml = '<?xml version="1.0" encoding="utf-8"?>
                <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
                  <soap:Body>
                    <PaymentNotification xmlns="http://apilistener.envoyservices.com">
                      <payment>
                        <uniqueReference>ESDEUR11039872</uniqueReference>
                        <epacsReference>74348dc0-cbf0-df11-b725-001ec9e61285</epacsReference>
                        <postingDate>2010-11-15T15:19:45</postingDate>
                        <bankCurrency>EUR</bankCurrency>
                        <bankAmount>1.00</bankAmount>
                        <appliedCurrency>EUR</appliedCurrency>
                        <appliedAmount>1.00</appliedAmount>
                        <countryCode>ES</countryCode>
                        <bankInformation>Sean Wood</bankInformation>
                  <merchantReference>ESDEUR11039872</merchantReference>
                   </payment>
                    </PaymentNotification>
                  </soap:Body>
                </soap:Envelope>';
        $doc = new DOMDocument();
        $doc->loadXML($xml);
        echo $doc->getElementsByTagName('postingDate')->item(0)->nodeValue;
        die;

Result is:

结果是:

2010-11-15T15:19:45

回答by UTKARSH SINGHAL

First, we need to filter the XML so as to parse that into an object

首先,我们需要过滤 XML 以便将其解析为一个对象

$response = strtr($xml_string, ['</soap:' => '</', '<soap:' => '<']);
$output = json_decode(json_encode(simplexml_load_string($response)));
var_dump($output->Body->PaymentNotification->payment);

回答by David Kurniawan

First, we need to filter the XML so as to parse that change objects become array

首先,我们需要过滤 XML 以便解析更改对象成为数组

//catch xml
$xmlElement = file_get_contents ('php://input');
//change become array
$Data = (array)simplexml_load_string($xmlElement);
//and see
print_r($Data);

回答by omarjebari

This is also quite nice if you subsequently need to resolve any objects into arrays: $array = json_decode(json_encode($responseXmlObject), true);

如果您随后需要将任何对象解析为数组,这也非常好: $array = json_decode(json_encode($responseXmlObject), true);

回答by almightyBob

why don't u try using an absolute xPath

为什么不尝试使用绝对 xPath

//soap:Envelope[1]/soap:Body[1]/PaymentNotification[1]/payment

or since u know that it is a payment and payment doesn't have any attributes just select directly from payment

或者因为你知道它是一种付款并且付款没有任何属性,所以直接从付款中选择

//soap:Envelope[1]/soap:Body[1]/PaymentNotification[1]/payment/*