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>
如何获得'付款'元素?
我尝试解析(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);
}
结果为空:( 任何想法如何正确解析?
答案 0 :(得分:77)
处理名称空间前缀的最简单方法之一就是将它们从XML响应中删除,然后再将其传递给simplexml,如下所示:
$your_xml_response = '<Your XML here>';
$clean_xml = str_ireplace(['SOAP-ENV:', 'SOAP:'], '', $your_xml_response);
$xml = simplexml_load_string($clean_xml);
这将返回以下内容:
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
)
)
)
)
答案 1 :(得分:45)
PHP版本&gt; 5.0有一个很好的SoapClient集成。这不需要解析响应xml。这是一个简单的例子
$client = new SoapClient("http://path.to/wsdl?WSDL");
$res = $client->SoapFunction(array('param1'=>'value','param2'=>'value'));
echo $res->PaymentNotification->payment;
答案 2 :(得分:22)
在您的代码中,您要查询默认命名空间中的payment
元素,但在XML响应中,它被声明为http://apilistener.envoyservices.com
命名空间。
所以,你缺少名称空间声明:
$xml->registerXPathNamespace('envoy', 'http://apilistener.envoyservices.com');
现在,您可以在xpath查询中使用envoy
名称空间前缀:
xpath('//envoy:payment')
完整的代码是:
$xml = simplexml_load_string($soap_response);
$xml->registerXPathNamespace('envoy', 'http://apilistener.envoyservices.com');
foreach ($xml->xpath('//envoy:payment') as $item)
{
print_r($item);
}
注意:我删除了soap
命名空间声明,因为您似乎没有使用它(只有在xpath查询中使用命名空间前缀时才有用)。 / p>
答案 3 :(得分:13)
$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;
结果是:
2010-11-15T15:19:45
答案 4 :(得分:0)
首先,我们需要过滤XML,以便将其解析为对象
$response = strtr($xml_string, ['</soap:' => '</', '<soap:' => '<']);
$output = json_decode(json_encode(simplexml_load_string($response)));
var_dump($output->Body->PaymentNotification->payment);
答案 5 :(得分:-1)
如果您随后需要将任何对象解析为数组,这也非常好: $ array = json_decode(json_encode($ responseXmlObject),true);
答案 6 :(得分:-1)
首先,我们需要过滤XML,以分析更改对象变为数组
//catch xml
$xmlElement = file_get_contents ('php://input');
//change become array
$Data = (array)simplexml_load_string($xmlElement);
//and see
print_r($Data);
答案 7 :(得分:-2)
为什么不尝试使用绝对xPath
//soap:Envelope[1]/soap:Body[1]/PaymentNotification[1]/payment
或者因为您知道这是付款而付款没有任何属性,只需直接从付款中选择
//soap:Envelope[1]/soap:Body[1]/PaymentNotification[1]/payment/*