2010-11-16 93 views
37

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> 

如何獲得 '金' 元素?

我嘗試解析(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

歡迎來到SO。下次單擊textarea頂部的格式按鈕,以便代碼更易於閱讀。 – stillstanding 2010-11-16 13:19:24

+0

@stillstanding:噢,顯然我改寫就像你提交它:) – BoltClock 2010-11-16 13:21:49

+0

等待幫助..... – Anton 2010-11-16 13:27:53

回答

-2

爲什麼不ü嘗試使用絕對路徑的XPath

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

或者因爲你知道,這是一個和支付沒有任何屬性,只需直接從支付選擇

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

foreach($ xml-> xpath('// soap:Envelope [1]/soap:Body [1]/PaymentNotification [1]/payment/*')as $ item) { print_r($ item); } 也是空的( – Anton 2010-11-16 13:39:26

+0

試着給你的第二個命名空間中的實際值和定義,然後 – almightyBob 2010-11-16 13:51:35

+0

你能給例如請 – Anton 2010-11-16 13:58:25

21

在您的代碼中,您正在查詢默認名稱空間中的payment元素,但在XML響應中,它聲明爲http://apilistener.envoyservices.com名稱空間。

所以,你缺少一個命名空間聲明

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

現在你可以使用envoy命名空間前綴在你的XPath查詢:

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查詢您將使用命名空間前綴)。

41

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; 
+0

救了我很多努力的人! – 2012-05-29 06:01:05

+2

這是什麼SoapFunction? – Edward 2013-06-11 12:08:43

+0

@Edward它是您想要訪問的SOAP服務的WSDL中定義的任何函數(操作) – Ivan 2013-06-11 15:42:37

6
$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 
+0

這會工作,但它在技術上不正確。您正在考慮將SOAP XML響應作爲DOM文檔,但事實並非如此。 – 2014-10-26 05:34:01

56

一個來處理命名空間前綴最簡單的方法是簡單地通過它通過對SimpleXML的,如之前從XML響應帶他們如下:

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

       ) 

     ) 

) 
+2

命名空間通常會產生誤導,並且刪除它似乎是恢復正確的xml對象的最快(黑客)方式。 thx – 2014-12-17 13:09:52

+14

真棒解決方案。肥皂很爛。 – 2015-06-18 05:18:48

+3

在我的情況下,我不得不向str_ireplace添加更多的數組值,但最終這是我發現的唯一工作解決方案。 Upvoted。還贊同@JohnBallinger肥皂太爛了。 – GTCrais 2015-11-19 17:11:11

0

如果隨後需要將任何對象解析爲數組,則這也相當不錯: $ array = json_decode(json_encode($ responseXmlObject),true);