2012-09-18 79 views
6

我知道這可能是一個新手問題,但請幽默我。在標籤中使用「soap:」讀取xml字符串時,simplexml_load_string()不會讀入xml。simplexml_load_string()不會在標籤中使用「soap:」讀取soap響應

給出這個腳本:

#!/usr/bin/php 
<?php 

$s=' 
    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> 
     <soap:Header> 
     <context xmlns="urn:zimbra"/> 
     </soap:Header> 
     <soap:Body> 
      <AuthResponse xmlns="urn:zimbraAdmin"> 
       <authToken>somevalue</authToken> 
       <lifetime>123124123</lifetime> 
       <a n="zimbraIsDomainAdminAccount">false</a> 
      </AuthResponse> 
     </soap:Body> 
    </soap:Envelope>'; 


print_r(simplexml_load_string($s)); 
echo "\n\n"; 
print_r(simplexml_load_string(str_ireplace("soap:", "", $s))); 
?> 

我得到這樣的輸出:

[email protected]:~/code/zmsoap$ ./xmltest.php 
SimpleXMLElement Object 
(
) 

SimpleXMLElement Object 
(
    [Header] => SimpleXMLElement Object 
     (
      [context] => SimpleXMLElement Object 
       (
       ) 

     ) 

    [Body] => SimpleXMLElement Object 
     (
      [AuthResponse] => SimpleXMLElement Object 
       (
        [authToken] => somevalue 
        [lifetime] => 123124123 
        [a] => false 
       ) 

     ) 

) 
[email protected]:~/code/zmsoap$ 

我只是好奇,爲什麼發生這種情況,如果有來解決這個問題作爲一個更合適的方式反對做一個字符串替換。

+0

貌似與命名空間的問題。 – JvdBerg

回答

12

與冒號的標籤名錶示標記是在非默認命名空間。 SimpleXML一次僅查看一個名稱空間,因此您需要使用the ->children() method專門選擇名稱空間。

在這種情況下,$xml->children('http://www.w3.org/2003/05/soap-envelope')->Body$xml->children('soap', true)->Body都應該工作。

由於這個原因和其他原因,不建議使用print_r來調試SimpleXML對象。改爲嘗試this dedicated function

+0

感謝您的解決方案...經過長時間的搜索後得到了這個... – 4naxr

5

這似乎奏效了。

讀到它在這裏:Parse XML with Namespace using SimpleXML

#!/usr/bin/php 
<?php 

$s=' 
    <soap:Envelope xmlns:soap="urn:zimbra"> 
     <soap:Header> 
     <context xmlns="urn:zimbra"/> 
     </soap:Header> 
     <soap:Body> 
      <AuthResponse xmlns="urn:zimbraAdmin"> 
       <authToken>somevalue</authToken> 
       <lifetime>123124123</lifetime> 
       <a n="zimbraIsDomainAdminAccount">false</a> 
      </AuthResponse> 
     </soap:Body> 
    </soap:Envelope>'; 
//print_r(simplexml_load_string($s)); 
//echo "\n\n"; 
//print_r(simplexml_load_string(str_ireplace("soap:", "", $s))); 
$xml = simplexml_load_string($s); 
$xml->registerXPathNamespace("soap", "http://www.w3.org/2003/05/soap-envelope"); 
print_r($xml->xpath('//soap:Body')); 

?> 
+0

您可以在不觸摸XPath的情況下執行此操作,而僅使用主要的SimpleXML函數/操作符。看到我剛剛添加的答案。 – IMSoP

0

簡單:

$xml='<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><AddOrderResult>1</AddOrderResult></soap:Body></soap:Envelope>'; 
var_export(json_decode(json_encode(simplexml_load_string(strtr($xml, array(' xmlns:'=>' ')))), 1)); 

輸出:

array (
    '@attributes' => 
    array (
    'soap' => 'http://schemas.xmlsoap.org/soap/envelope/', 
), 
    'soap:Body' => 
    array (
    'AddOrderResult' => '1', 
), 
) 
+0

我不明白這怎麼可能是***最簡單的***,也'json_decode(json_encode'沒有任何意義。 –