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
How to parse SOAP XML?
提问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 payment
element in default namespace, but in the XML response it is declared as in http://apilistener.envoyservices.com
namespace.
在您的代码中,您正在查询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 envoy
namespace 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 soap
namespace 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/*