Search code examples
phpxmlsimplexml

SimpleXML Returns 0 Element


I'm taking my response from a Soap Request, and passing it into a new SimpleXML construct.

$response = $this->client->$method(array("Request" => $this->params));
$response_string = $this->client->__getLastResponse();
$this->response = new Classes_Result(new SimpleXMLElement($result));

If I echo the $response_string, it outputs a proper xml string. Here is a snippet as it's quite long.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body><GetClassesResponse xmlns="http://clients.mindbodyonline.com/api/0_5">      
    <GetClassesResult>
     <Status>Success</Status>
     <XMLDetail>Full</XMLDetail>
     <ResultCount>6</ResultCount>
     <CurrentPageIndex>0</CurrentPageIndex>
     <TotalPageCount>1</TotalPageCount>
     <Classes>
      <Class>
       <ClassScheduleID>4</ClassScheduleID>
       <Location>
        <SiteID>20853</SiteID>
  ....</soap:Envelope>

Hoever, when I try to work with this object, I get errors or if I dump the object it outputs:

object(SimpleXMLElement)#51 (0)

Any ideas why this might be happening?


Solution

  • You are not actually using $response_string, and you have not set $result anywhere, which you have passed to new SimpleXMLElement($result).

    Perhaps you intend to build a SimpleXML object with the $response_string string via simplexml_load_string()?

    $response = $this->client->$method(array("Request" => $this->params));
    $response_string = $this->client->__getLastResponse();
    // Load XML via simplexml_load_string()
    $this->response = new Classes_Result(simplexml_load_string($response_string));
    
    // Or if you do expect a SimpleXMLElement(), pass in the string
    $this->response = new Classes_Result(new SimpleXMLElement($response_string));
    

    The <soap:Body> element of your SOAP response is namespaced with (soap). To loop over it with SimpleXML, you must provide the correct namespace:

    // After creating new SimpleXMLElement()
    var_dump($this->response->children("http://schemas.xmlsoap.org/soap/envelope/"));
    
    // class SimpleXMLElement#2 (1) {
    //   public $Body =>
    //   class SimpleXMLElement#4 (0) {
    //  }
    // }
    

    To loop over the body:

    foreach ($this->response->children("http://schemas.xmlsoap.org/soap/envelope/") as $b) {
      $body_nodes = $b->children();
      // Get somethign specific
      foreach ($body_nodes->GetClassesResponse->GetClassesResult as $bn) {
        echo $bn->ResultCount . ", ";
        echo $bn->TotalPageCount;
      }
    }
    // 6, 1