2012-09-18 39 views
6

Sé que esta puede ser una pregunta para principiantes, pero por favor, cómprame un ojo. Al leer una cadena xml con "soap:" en las etiquetas, simplexml_load_string() no se leerá en el xml.simplexml_load_string() no leerá la respuesta de jabón con "jabón" en las etiquetas

dado este script:

#!/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))); 
?> 

puedo obtener este resultado:

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

Tengo curiosidad de por qué ocurre esto, y si hay una manera más adecuada para remediar el problema como opuesto a hacer un reemplazo de cadena.

+0

Parece que un problema con el espacio de nombres. – JvdBerg

Respuesta

12

un nombre de etiqueta con dos puntos en la etiqueta indica se encuentra en un espacio de nombres no predeterminada. SimpleXML solo mira un espacio de nombre a la vez, por lo que debe seleccionar específicamente el espacio de nombres usando the ->children() method.

En este caso, $xml->children('http://www.w3.org/2003/05/soap-envelope')->Body o $xml->children('soap', true)->Body deberían funcionar.

Por esta y otras razones, no es aconsejable usar print_r para depurar objetos SimpleXML. Pruebe this dedicated function en su lugar.

+0

gracias por la solución ... obtuve esto después de una larga búsqueda ... – 4naxr

5

Esto parece haber funcionado.

leer sobre ello aquí: 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

Puede hacer esto sin tocar XPath y simplemente usar las funciones/operadores SimpleXML principales. Vea la respuesta que acabo de agregar. – IMSoP

0

más simple:

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

de salida:

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

No veo cómo puede ser *** el más simple ***, también 'json_decode (json_encode' no tiene ningún sentido. –

Cuestiones relacionadas