2010-06-11 21 views
5

Después de pasar VARIAS horas frustradas en esto, estoy pidiendo su ayuda.SimpleXML respuesta SOAP Problemas del espacio de nombres

Estoy tratando de obtener el contenido de nodos particulares de una respuesta SOAP.

La respuesta es

<?xml version="1.0" encoding="UTF-8"?> 
<env:Envelope xmlns:env="<a href="http://www.w3.org/2003/05/soap-envelope">http://www.w3.org/2003/05/soap-envelope</a>"<xmlns:ns1="<a href="http://soap.xxxxxx.co.uk/">http://soap.xxxxxx.co.uk/</a>"> 
    <env:Body> 
     <ns1:PlaceOrderResponse> 
      <xxxxxOrderNumber></xxxxxOrderNumber> 
      <ErrorArray> 
       <Error> 
        <ErrorCode>24</ErrorCode> 
        <ErrorText>The+client+order+number+3002254+is+already+in+use</ErrorText> 
       </Error> 
       <Error> 
        <ErrorCode>1</ErrorCode> 
        <ErrorText>Aborting</ErrorText> 
       </Error> 
      </ErrorArray> 
     </ns1:PlaceOrderResponse> 
    </env:Body> 
</env:Envelope> 

que estoy tratando de llegar a los nodos y los niños de < ErrorArray>. Debido a los espacios de nombres XML que contiene

$XmlArray = new SimpleXMLElement($XmlStr); 

foreach ($XmlArray->env:Envelope->env:Body->ns1:PlaceOrderResponse->ErrorArray->Error as $Error) 
{ 
    echo $Error->ErrorCode."<br />"; 
} 

no funciona. He leído varios artículos tales como

y cerca de 20 preguntas en este sitio, que por desgracia no están ayudando.

Incluso escribir,

$XmlArray = new SimpleXMLElement($XmlStr); 

echo "<br /><br /><pre>\n"; 
print_r($XmlArray); 
echo "<pre><br /><br />\n"; 

da

SimpleXMLElement Object 
(
) 

que me pregunto si la respuesta de jabón ($ XmlStr) es en realidad una entrada válida para SimpleXMLElement.

Parece que la línea

$XmlArray = new SimpleXMLElement($XmlStr); 

no está haciendo lo que espero que lo haga.

Cualquier ayuda sobre cómo obtener los nodos del XML anterior sería muy bienvenida.

Obviamente hacerlo funcionar (tener un ejemplo de trabajo) es lo que necesito a corto plazo, pero si alguien pudiera ayudarme a entender lo que estoy haciendo mal sería mejor a largo plazo.

Saludos. Stu

Respuesta

12

Tiene que usar SimpleXMLElement::children(), aunque en este punto probablemente sea más fácil usar XPath.

<?php 
    $XmlStr = <<<XML 
<?xml version="1.0" encoding="UTF-8"?> 
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://soap.xxxxxx.co.uk/" > 
    <env:Body> 
     <ns1:PlaceOrderResponse> 
      <xxxxxOrderNumber></xxxxxOrderNumber> 
      <ErrorArray> 
       <Error> 
        <ErrorCode>24</ErrorCode> 
        <ErrorText>The+client+order+number+3002254+is+already+in+use</ErrorText> 
       </Error> 
       <Error> 
        <ErrorCode>1</ErrorCode> 
        <ErrorText>Aborting</ErrorText> 
       </Error> 
      </ErrorArray> 
     </ns1:PlaceOrderResponse> 
    </env:Body> 
</env:Envelope> 
XML; 

    $XmlArray = new SimpleXMLElement($XmlStr); 

    $t = $XmlArray->children("env", true)->Body-> 
     children("ns1", true)->PlaceOrderResponse-> 
     children()->ErrorArray->Error; 
    foreach ($t as $error) { 
     echo $error->ErrorCode, " " , $error->ErrorText, "<br />"; 
    } 

da:

 
24 The+client+order+number+3002254+is+already+in+use 
1 Aborting 
+0

GRACIAS !, yo estaba tan cerca. Ya había buscado en el método children() y estaba usando foreach ($ XmlArray-> children ('env', true) -> Sobre-> hijos ('env', verdadero) -> Body- > children ('ns1', true) -> PlaceOrderResponse-> ErrorArray-> Error as $ Error) Nuevamente, gracias :-) Ps ¿Cuáles son las etiquetas para formatear el código correctamente en stackoverflow? No pude encontrarlo en el lado. – Stu

+0

@Stu Solo tiene que presionar el botón 0101 con su código seleccionado. Por cierto, si la respuesta fue realmente satisfactoria, debes aceptarla. – Artefacto

0

Una forma barata y desagradable es simplemente eliminar los prefijos:

$xml = preg_replace('%<(\/)?(\S+):(\w+)%', '<$1$3', $xml); 
Cuestiones relacionadas