0

If I have a SimpleXMLElement object that is inside a foreach loop, How do I access it outside the loop?

$auth_tokens = array('tok1', 'tok2', 'tok3', 'tok4');

foreach($auth_tokens as $auth_token) { // 4 iterations in loop
    $response = curl_exec($connection); // API xml response
    $xml = simplexml_load_string($response); // loaded xml into object
}

echo header('content-type: text/xml');
echo $xml->asXML();

.= does not work

[] does not work

Update:

below is what's actually being output from the api xml $response. As you can see, because I'm querying 4 auth tokens, on each iteration it's a new xml response. When I try to access it outside the loop, it's not working due to multiple <?xml version="1.0" encoding="UTF-8"?> xml headers.

I'm stuck. Not sure how to put all 4 responses into one.

Update 2:

Nick helped me figure out how to put all 4 responses into one xml doc, but I need to edit node names and values and that was easy to do when the xml is in a SimpleXMLElement object. So I thought I could manipulate the data first while it is in the object, then when I'm done, convert the object back to xml and save. But I was running into problems when accessing the object outside the loop. It's because there are 4 objects and not just 1, so .= was not saving the data.

This is what the API outputs when I echo $response; and view source. It's just pure xml.

<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2018-10-26T16:04:38.375Z</Timestamp>
  <Ack>Success</Ack>
  <Version>1083</Version>
  <Build>E1083_CORE_APIXO_18856776_R1</Build>
  <PaginationResult>
    <TotalNumberOfEntries>1</TotalNumberOfEntries>
  </PaginationResult>
  <OrderArray>
    <Order>
      <OrderID>11306025</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T14:38:44.000Z</CreatedTime>
    </Order>
  </OrderArray>
</GetOrdersResponse>
<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2018-10-26T16:04:39.049Z</Timestamp>
  <Ack>Success</Ack>
  <Version>1083</Version>
  <Build>E1083_CORE_APIXO_18856776_R1</Build>
  <PaginationResult>
    <TotalNumberOfEntries>3</TotalNumberOfEntries>
  </PaginationResult>
  <OrderArray>
    <Order>
      <OrderID>39168452</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T14:38:53.000Z</CreatedTime>
    </Order>
    <Order>
      <OrderID>37219192</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T15:36:41.000Z</CreatedTime>
    </Order>
    <Order>
      <OrderID>37198277</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T15:35:01.000Z</CreatedTime>
    </Order>
  </OrderArray>
</GetOrdersResponse>
<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2018-10-26T16:04:39.454Z</Timestamp>
  <Ack>Success</Ack>
  <Version>1083</Version>
  <Build>E1083_CORE_APIXO_18856776_R1</Build>
  <PaginationResult>
    <TotalNumberOfEntries>2</TotalNumberOfEntries>
  </PaginationResult>
  <OrderArray>
    <Order>
      <OrderID>16283499</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T15:13:21.000Z</CreatedTime>
    </Order>
    <Order>
      <OrderID>16283499</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T15:36:40.000Z</CreatedTime>
    </Order>
  </OrderArray>
</GetOrdersResponse>
<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2018-10-26T16:04:39.782Z</Timestamp>
  <Ack>Success</Ack>
  <Version>1083</Version>
  <Build>E1083_CORE_APIXO_18856776_R1</Build>
  <PaginationResult>
    <TotalNumberOfEntries>1</TotalNumberOfEntries>
  </PaginationResult>
  <OrderArray>
    <Order>
      <OrderID>26348797</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T15:40:25.000Z</CreatedTime>
    </Order>
  </OrderArray>
</GetOrdersResponse>

This is what I get when I do a var_dump ($response); and view source.

string(504) "
<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2018-10-26T16:10:49.358Z</Timestamp>
  <Ack>Success</Ack>
  <Version>1083</Version>
  <Build>E1083_CORE_APIXO_18856776_R1</Build>
  <PaginationResult>
    <TotalNumberOfEntries>1</TotalNumberOfEntries>
  </PaginationResult>
  <OrderArray>
    <Order>
      <OrderID>11306025</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T14:38:44.000Z</CreatedTime>
    </Order>
  </OrderArray>
</GetOrdersResponse>
"
string(797) "
<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2018-10-26T16:10:49.439Z</Timestamp>
  <Ack>Success</Ack>
  <Version>1083</Version>
  <Build>E1083_CORE_APIXO_18856776_R1</Build>
  <PaginationResult>
    <TotalNumberOfEntries>3</TotalNumberOfEntries>
  </PaginationResult>
  <OrderArray>
    <Order>
      <OrderID>39168452</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T14:38:53.000Z</CreatedTime>
    </Order>
    <Order>
      <OrderID>37219192</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T15:36:41.000Z</CreatedTime>
    </Order>
    <Order>
      <OrderID>37198277</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T15:35:01.000Z</CreatedTime>
    </Order>
  </OrderArray>
</GetOrdersResponse>
"
string(798) "
<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2018-10-26T16:10:50.001Z</Timestamp>
  <Ack>Success</Ack>
  <Version>1083</Version>
  <Build>E1083_CORE_APIXO_18856776_R1</Build>
  <PaginationResult>
    <TotalNumberOfEntries>3</TotalNumberOfEntries>
  </PaginationResult>
  <OrderArray>
    <Order>
      <OrderID>16283499</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T15:13:21.000Z</CreatedTime>
    </Order>
    <Order>
      <OrderID>16283499</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T15:36:40.000Z</CreatedTime>
    </Order>
    <Order>
      <OrderID>16275107</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T16:09:40.000Z</CreatedTime>
    </Order>
  </OrderArray>
</GetOrdersResponse>
"
string(504) "
<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2018-10-26T16:10:50.329Z</Timestamp>
  <Ack>Success</Ack>
  <Version>1083</Version>
  <Build>E1083_CORE_APIXO_18856776_R1</Build>
  <PaginationResult>
    <TotalNumberOfEntries>1</TotalNumberOfEntries>
  </PaginationResult>
  <OrderArray>
    <Order>
      <OrderID>26348797</OrderID>
      <OrderStatus>Completed</OrderStatus>
      <CreatedTime>2018-10-26T15:40:25.000Z</CreatedTime>
    </Order>
  </OrderArray>
</GetOrdersResponse>
"

If i use $xml = simplexml_load_string($response); in the foreach, and var_dump ($xml);, 4 objects gets output.

object(SimpleXMLElement)#1 (6) {
  ["Timestamp"]=>
  string(24) "2018-10-26T16:32:21.048Z"
  ["Ack"]=>
  string(7) "Success"
  ["Version"]=>
  string(4) "1083"
  ["Build"]=>
  string(28) "E1083_CORE_APIXO_18856776_R1"
  ["PaginationResult"]=>
  object(SimpleXMLElement)#2 (1) {
    ["TotalNumberOfEntries"]=>
    string(1) "1"
  }
  ["OrderArray"]=>
  object(SimpleXMLElement)#3 (1) {
    ["Order"]=>
    object(SimpleXMLElement)#4 (3) {
      ["OrderID"]=>
      string(26) "11306025"
      ["OrderStatus"]=>
      string(9) "Completed"
      ["CreatedTime"]=>
      string(24) "2018-10-26T14:38:44.000Z"
    }
  }
}
object(SimpleXMLElement)#3 (6) {
  ["Timestamp"]=>
  string(24) "2018-10-26T16:32:21.736Z"
  ["Ack"]=>
  string(7) "Success"
  ["Version"]=>
  string(4) "1083"
  ["Build"]=>
  string(28) "E1083_CORE_APIXO_18856776_R1"
  ["PaginationResult"]=>
  object(SimpleXMLElement)#1 (1) {
    ["TotalNumberOfEntries"]=>
    string(1) "4"
  }
  ["OrderArray"]=>
  object(SimpleXMLElement)#2 (1) {
    ["Order"]=>
    array(4) {
      [0]=>
      object(SimpleXMLElement)#4 (3) {
        ["OrderID"]=>
        string(25) "39168452"
        ["OrderStatus"]=>
        string(9) "Completed"
        ["CreatedTime"]=>
        string(24) "2018-10-26T14:38:53.000Z"
      }
      [1]=>
      object(SimpleXMLElement)#5 (3) {
        ["OrderID"]=>
        string(26) "37219192"
        ["OrderStatus"]=>
        string(9) "Completed"
        ["CreatedTime"]=>
        string(24) "2018-10-26T15:36:41.000Z"
      }
      [2]=>
      object(SimpleXMLElement)#6 (3) {
        ["OrderID"]=>
        string(26) "37198277"
        ["OrderStatus"]=>
        string(9) "Completed"
        ["CreatedTime"]=>
        string(24) "2018-10-26T15:35:01.000Z"
      }
      [3]=>
      object(SimpleXMLElement)#7 (3) {
        ["OrderID"]=>
        string(26) "37185515"
        ["OrderStatus"]=>
        string(9) "Completed"
        ["CreatedTime"]=>
        string(24) "2018-10-26T16:24:19.000Z"
      }
    }
  }
}
object(SimpleXMLElement)#2 (6) {
  ["Timestamp"]=>
  string(24) "2018-10-26T16:32:22.529Z"
  ["Ack"]=>
  string(7) "Success"
  ["Version"]=>
  string(4) "1083"
  ["Build"]=>
  string(28) "E1083_CORE_APIXO_18856776_R1"
  ["PaginationResult"]=>
  object(SimpleXMLElement)#3 (1) {
    ["TotalNumberOfEntries"]=>
    string(1) "3"
  }
  ["OrderArray"]=>
  object(SimpleXMLElement)#1 (1) {
    ["Order"]=>
    array(3) {
      [0]=>
      object(SimpleXMLElement)#7 (3) {
        ["OrderID"]=>
        string(26) "16283499"
        ["OrderStatus"]=>
        string(9) "Completed"
        ["CreatedTime"]=>
        string(24) "2018-10-26T15:13:21.000Z"
      }
      [1]=>
      object(SimpleXMLElement)#6 (3) {
        ["OrderID"]=>
        string(26) "16283499"
        ["OrderStatus"]=>
        string(9) "Completed"
        ["CreatedTime"]=>
        string(24) "2018-10-26T15:36:40.000Z"
      }
      [2]=>
      object(SimpleXMLElement)#5 (3) {
        ["OrderID"]=>
        string(26) "16275107"
        ["OrderStatus"]=>
        string(9) "Completed"
        ["CreatedTime"]=>
        string(24) "2018-10-26T16:09:40.000Z"
      }
    }
  }
}
object(SimpleXMLElement)#1 (6) {
  ["Timestamp"]=>
  string(24) "2018-10-26T16:32:22.751Z"
  ["Ack"]=>
  string(7) "Success"
  ["Version"]=>
  string(4) "1083"
  ["Build"]=>
  string(28) "E1083_CORE_APIXO_18856776_R1"
  ["PaginationResult"]=>
  object(SimpleXMLElement)#2 (1) {
    ["TotalNumberOfEntries"]=>
    string(1) "1"
  }
  ["OrderArray"]=>
  object(SimpleXMLElement)#3 (1) {
    ["Order"]=>
    object(SimpleXMLElement)#5 (3) {
      ["OrderID"]=>
      string(26) "26348797"
      ["OrderStatus"]=>
      string(9) "Completed"
      ["CreatedTime"]=>
      string(24) "2018-10-26T15:40:25.000Z"
    }
  }
}

And this is what gets output when I echo '<pre>' . var_export($xml, true) . '</pre><br>';. I find this one is easier to read and can see clear it's 4 objects.

SimpleXMLElement::__set_state(array(
   'Timestamp' => '2018-10-26T16:36:41.377Z',
   'Ack' => 'Success',
   'Version' => '1083',
   'Build' => 'E1083_CORE_APIXO_18856776_R1',
   'PaginationResult' => 
  SimpleXMLElement::__set_state(array(
     'TotalNumberOfEntries' => '1',
  )),
   'OrderArray' => 
  SimpleXMLElement::__set_state(array(
     'Order' => 
    SimpleXMLElement::__set_state(array(
       'OrderID' => '11306025',
       'OrderStatus' => 'Completed',
       'CreatedTime' => '2018-10-26T14:38:44.000Z',
    )),
  )),
))


SimpleXMLElement::__set_state(array(
   'Timestamp' => '2018-10-26T16:36:43.083Z',
   'Ack' => 'Success',
   'Version' => '1083',
   'Build' => 'E1083_CORE_APIXO_18856776_R1',
   'PaginationResult' => 
  SimpleXMLElement::__set_state(array(
     'TotalNumberOfEntries' => '4',
  )),
   'OrderArray' => 
  SimpleXMLElement::__set_state(array(
     'Order' => 
    array (
      0 => 
      SimpleXMLElement::__set_state(array(
         'OrderID' => '39168452',
         'OrderStatus' => 'Completed',
         'CreatedTime' => '2018-10-26T14:38:53.000Z',
      )),
      1 => 
      SimpleXMLElement::__set_state(array(
         'OrderID' => '37219192',
         'OrderStatus' => 'Completed',
         'CreatedTime' => '2018-10-26T15:36:41.000Z',
      )),
      2 => 
      SimpleXMLElement::__set_state(array(
         'OrderID' => '37198277',
         'OrderStatus' => 'Completed',
         'CreatedTime' => '2018-10-26T15:35:01.000Z',
      )),
      3 => 
      SimpleXMLElement::__set_state(array(
         'OrderID' => '37185515',
         'OrderStatus' => 'Completed',
         'CreatedTime' => '2018-10-26T16:24:19.000Z',
      )),
    ),
  )),
))


SimpleXMLElement::__set_state(array(
   'Timestamp' => '2018-10-26T16:36:43.783Z',
   'Ack' => 'Success',
   'Version' => '1083',
   'Build' => 'E1083_CORE_APIXO_18856776_R1',
   'PaginationResult' => 
  SimpleXMLElement::__set_state(array(
     'TotalNumberOfEntries' => '4',
  )),
   'OrderArray' => 
  SimpleXMLElement::__set_state(array(
     'Order' => 
    array (
      0 => 
      SimpleXMLElement::__set_state(array(
         'OrderID' => '16283499',
         'OrderStatus' => 'Completed',
         'CreatedTime' => '2018-10-26T15:13:21.000Z',
      )),
      1 => 
      SimpleXMLElement::__set_state(array(
         'OrderID' => '16283499',
         'OrderStatus' => 'Completed',
         'CreatedTime' => '2018-10-26T15:36:40.000Z',
      )),
      2 => 
      SimpleXMLElement::__set_state(array(
         'OrderID' => '16275107',
         'OrderStatus' => 'Completed',
         'CreatedTime' => '2018-10-26T16:09:40.000Z',
      )),
      3 => 
      SimpleXMLElement::__set_state(array(
         'OrderID' => '16258277',
         'OrderStatus' => 'Completed',
         'CreatedTime' => '2018-10-26T16:36:19.000Z',
      )),
    ),
  )),
))


SimpleXMLElement::__set_state(array(
   'Timestamp' => '2018-10-26T16:36:44.157Z',
   'Ack' => 'Success',
   'Version' => '1083',
   'Build' => 'E1083_CORE_APIXO_18856776_R1',
   'PaginationResult' => 
  SimpleXMLElement::__set_state(array(
     'TotalNumberOfEntries' => '1',
  )),
   'OrderArray' => 
  SimpleXMLElement::__set_state(array(
     'Order' => 
    SimpleXMLElement::__set_state(array(
       'OrderID' => '26348797',
       'OrderStatus' => 'Completed',
       'CreatedTime' => '2018-10-26T15:40:25.000Z',
    )),
  )),
))

And this is what gets output when I use this echo header('content-type: text/xml'); echo $xml->asXML(); inside the loop.

  <?xml version="1.0" encoding="UTF-8"?>
  <GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
    <Timestamp>2018-10-26T16:42:57.532Z</Timestamp>
    <Ack>Success</Ack>
    <Version>1083</Version>
    <Build>E1083_CORE_APIXO_18856776_R1</Build>
    <PaginationResult>
      <TotalNumberOfEntries>1</TotalNumberOfEntries>
    </PaginationResult>
    <OrderArray>
      <Order>
        <OrderID>11306025</OrderID>
        <OrderStatus>Completed</OrderStatus>
        <CreatedTime>2018-10-26T14:38:44.000Z</CreatedTime>
      </Order>
    </OrderArray>
  </GetOrdersResponse>
  <?xml version="1.0" encoding="UTF-8"?>
  <GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
    <Timestamp>2018-10-26T16:42:58.218Z</Timestamp>
    <Ack>Success</Ack>
    <Version>1083</Version>
    <Build>E1083_CORE_APIXO_18856776_R1</Build>
    <PaginationResult>
      <TotalNumberOfEntries>4</TotalNumberOfEntries>
    </PaginationResult>
    <OrderArray>
      <Order>
        <OrderID>39168452</OrderID>
        <OrderStatus>Completed</OrderStatus>
        <CreatedTime>2018-10-26T14:38:53.000Z</CreatedTime>
      </Order>
      <Order>
        <OrderID>37219192</OrderID>
        <OrderStatus>Completed</OrderStatus>
        <CreatedTime>2018-10-26T15:36:41.000Z</CreatedTime>
      </Order>
      <Order>
        <OrderID>37198277</OrderID>
        <OrderStatus>Completed</OrderStatus>
        <CreatedTime>2018-10-26T15:35:01.000Z</CreatedTime>
      </Order>
      <Order>
        <OrderID>37185515</OrderID>
        <OrderStatus>Completed</OrderStatus>
        <CreatedTime>2018-10-26T16:24:19.000Z</CreatedTime>
      </Order>
    </OrderArray>
  </GetOrdersResponse>
  <?xml version="1.0" encoding="UTF-8"?>
  <GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
    <Timestamp>2018-10-26T16:42:58.861Z</Timestamp>
    <Ack>Success</Ack>
    <Version>1083</Version>
    <Build>E1083_CORE_APIXO_18856776_R1</Build>
    <PaginationResult>
      <TotalNumberOfEntries>4</TotalNumberOfEntries>
    </PaginationResult>
    <OrderArray>
      <Order>
        <OrderID>16283499</OrderID>
        <OrderStatus>Completed</OrderStatus>
        <CreatedTime>2018-10-26T15:13:21.000Z</CreatedTime>
      </Order>
      <Order>
        <OrderID>16283499</OrderID>
        <OrderStatus>Completed</OrderStatus>
        <CreatedTime>2018-10-26T15:36:40.000Z</CreatedTime>
      </Order>
      <Order>
        <OrderID>16275107</OrderID>
        <OrderStatus>Completed</OrderStatus>
        <CreatedTime>2018-10-26T16:09:40.000Z</CreatedTime>
      </Order>
      <Order>
        <OrderID>16258277</OrderID>
        <OrderStatus>Completed</OrderStatus>
        <CreatedTime>2018-10-26T16:36:19.000Z</CreatedTime>
      </Order>
    </OrderArray>
  </GetOrdersResponse>
  <?xml version="1.0" encoding="UTF-8"?>
  <GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
    <Timestamp>2018-10-26T16:42:59.253Z</Timestamp>
    <Ack>Success</Ack>
    <Version>1083</Version>
    <Build>E1083_CORE_APIXO_18856776_R1</Build>
    <PaginationResult>
      <TotalNumberOfEntries>1</TotalNumberOfEntries>
    </PaginationResult>
    <OrderArray>
      <Order>
        <OrderID>26348797</OrderID>
        <OrderStatus>Completed</OrderStatus>
        <CreatedTime>2018-10-26T15:40:25.000Z</CreatedTime>
      </Order>
    </OrderArray>
  </GetOrdersResponse>

What I need is to change all the <OrderID></OrderID> nodes to display <Test></Test> and append to the value in it, and I did that with this

foreach($auth_tokens as $key => $auth_token) {

    $responses = curl_exec($connection);
    $xml = simplexml_load_string($responses);
    curl_close($connection);

    $entries = $xml->PaginationResult->TotalNumberOfEntries;
    $xml = $xml->OrderArray->Order;

    if($entries == 0) {
        continue;
    } else {

        foreach($xml as $key => $val) {

            $val->Test = substr($val->OrderStatus, 0, 3) . $val->OrderID; // changes the <OrderID> node from <OrderID> to <Test> and appends the first 3 charachters from <OrderStatus> value to the <Test> value
            unset($val->OrderID); // deletes the now empty <OrderID> node

        } // end foreach

    }

echo header('content-type: text/xml');
echo $xml->asXML();

} // end foreach

And this outputs exactly what I need, except it just needs a parent node wrapped around it and it's only outputting 1 order from each response.

<Order>
  <OrderStatus>Completed</OrderStatus>
  <CreatedTime>2018-10-26T15:36:41.000Z</CreatedTime>
  <Test>Com372191926</Test>
</Order>
<Order>
  <OrderStatus>Completed</OrderStatus>
  <CreatedTime>2018-10-26T15:13:21.000Z</CreatedTime>
  <Test>Com16283499</Test>
</Order>
<Order>
  <OrderStatus>Completed</OrderStatus>
  <CreatedTime>2018-10-26T15:40:25.000Z</CreatedTime>
  <Test>Com26348797</Test>
</Order>

But I can't seem to get a parent node around this because I can't successfully save this data and access it outside the foreach loop. I'm so close!

3
  • 1
    You are overwriting $xml each time round the loop. So outside the loop you will see only the last response in $xml Commented Oct 25, 2018 at 23:10
  • @RiggsFolly Yes I know that. But .= is not working to access it outside the loop. Commented Oct 26, 2018 at 0:46
  • I figured it out. See my answer. stackoverflow.com/a/53016076/3950902 Commented Oct 26, 2018 at 20:46

2 Answers 2

3

You could try something like this, aggregating the responses into an XML string and then wrapping that in a root element before converting:

$auth_tokens = array('tok1', 'tok2', 'tok3', 'tok4');
$xmlstr = '';
foreach($auth_tokens as $auth_token) { // 4 iterations in loop
    $response = curl_exec($connection); // API xml response
    $xmlstr .= $response;               // add response to XML
}
$xml = simplexml_load_string("<Orders>$xmlstr</Orders>");
header('content-type: text/xml');
echo $xml->asXML();

Update

The above code doesn't work if the XML response includes <?xml ... > headers. The quick and dirty fix is to strip them out using preg_replace i.e. change $xmlstr .= $response; to

$xmlstr .= preg_replace('/<\?xml[^>]*>/', '', $response);

Demo

The "correct" fix is to process the XML responses separately and add them as children to a root document. This can be done using DomDocument:

$xml = new DomDocument();
$xml->loadXML('<Orders></Orders>');
$xmlroot = $xml->documentElement;
$respdoc = new DomDocument();
foreach($auth_tokens as $auth_token) {   // 4 iterations in loop
    $response = curl_exec($connection); // API xml response
    $respdoc->loadXML($response);        // create a domDocument
    $resproot = $respdoc->documentElement;   // get the root element
    $resproot = $xml->importNode($resproot, true); // import into XML
    $xmlroot->appendChild($resproot);
}
header('content-type: text/xml');
echo $xml->saveXML();

Demo

Sign up to request clarification or add additional context in comments.

21 Comments

.= is not working, have you tested it? Nothing is output. Only when I move those last 3 lines of code inside the loop, then it outputs.
@Mike I couldn't test it exactly as you are using it I don't have access to the API you are calling but when I simulated the responses with an array this code worked fine: 3v4l.org/r7180.
@Mike can you do a var_dump of $response inside the loop? That could help debug the problem.
I updated my question. I added the exact output format I'm getting from the api response. Since it is an xml response, and I'm querying 4 auth tokens in the loop, I get 4 <?xml version="1.0" encoding="UTF-8"?> in the response. I think this is the problem.
@Mike you're right, the extra xml header lines are the issue. Give me a minute and I'll work out a fix
|
0

I figured out the issue. I needed to concatenate .= inside the child foreach loop, not the parent. Then I was able to access the data outside the loop. And I had to save the data to a variable using $val->asXML(). Notice the comment lines in the code below.

foreach($auth_tokens as $key => $auth_token) { // 4 iterations in loop

    $responses = curl_exec($connection); // API xml response
    $xml = simplexml_load_string($responses); // loaded xml into SimpleXMLElement object
    curl_close($connection);

    $entries = $xml->PaginationResult->TotalNumberOfEntries;
    $xml = $xml->OrderArray->Order; // Just get the Order elements

    if($entries == 0) {
        continue;
    } else {

        foreach($xml as $key => $val) {

            $val->Test = substr($val->OrderStatus, 0, 3) . $val->OrderID; // changes the <OrderID> node from <OrderID> to <Test> and appends the first 3 charachters from <OrderStatus> value to the <Test> value
            unset($val->OrderID); // deletes the <OrderID> node

            $orders .= $val->asXML(); // concatenate here in child loop instead of parent foreach

        } // end child foreach

    }

} // end parent foreach

$xml = new DomDocument('1.0', 'utf-8');
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;
$xml->loadXML('<Orders>' . $orders . '</Orders>'); // able to add my parent node <orders></Orders>
$xml->save('test.xml', LIBXML_NOEMPTYTAG); // saves xml to file

header('content-type: text/xml');
echo $xml->saveXML(); // saves xml for display

The output is exactly what I need, and without too much overhead and it's formatted nicely too.

<?xml version="1.0"?>
<Orders>
  <Order>
    <OrderStatus>Completed</OrderStatus>
    <CreatedTime>2018-10-26T15:36:41.000Z</CreatedTime>
    <Test>Com10789</Test>
  </Order>
  <Order>
    <OrderStatus>Completed</OrderStatus>
    <CreatedTime>2018-10-26T15:13:21.000Z</CreatedTime>
    <Test>Com10790</Test>
  </Order>
  <Order>
    <OrderStatus>Completed</OrderStatus>
    <CreatedTime>2018-10-26T15:40:25.000Z</CreatedTime>
    <Test>Com141570</Test>
  </Order>
  <Order>
    <OrderStatus>Completed</OrderStatus>
    <CreatedTime>2018-10-26T15:36:41.000Z</CreatedTime>
    <Test>Com141571</Test>
  </Order>
  <Order>
    <OrderStatus>Completed</OrderStatus>
    <CreatedTime>2018-10-26T15:13:21.000Z</CreatedTime>
    <Test>Com141572</Test>
  </Order>
  <Order>
    <OrderStatus>Completed</OrderStatus>
    <CreatedTime>2018-10-26T15:36:41.000Z</CreatedTime>
    <Test>Com19992</Test>
  </Order>
  <Order>
    <OrderStatus>Completed</OrderStatus>
    <CreatedTime>2018-10-26T15:40:25.000Z</CreatedTime>
    <Test>Com19993</Test>
  </Order>
</Orders>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.