Search code examples
phplaravelsimplexml

Getting specific value from XML HTTP Client Response in Laravel


I am communicating with a domain registrar API, where I make a call to get available TLD list.

The response should look like this in a browser:

<?xml version="1.0" encoding="UTF-8"?>
<ApiResponse xmlns="http://api.namecheap.com/xml.response" Status="OK">
  <Errors />
  <RequestedCommand>namecheap.domains.getTldList</RequestedCommand>
  <CommandResponse Type="namecheap.domains.getTldList">
    <Tlds>
      <Tld Name="biz" NonRealTime="false" MinRegisterYears="1" MaxRegisterYears="10" MinRenewYears="1" MaxRenewYears="10" MinTransferYears="1" MaxTransferYears="10" IsApiRegisterable="true" IsApiRenewable="true" IsApiTransferable="false" IsEppRequired="false" IsDisableModContact="false" IsDisableWGAllot="false" IsIncludeInExtendedSearchOnly="false" SequenceNumber="5" Type="GTLD" IsSupportsIDN="false" Category="P">US Business</Tld>
      <Tld Name="bz" NonRealTime="false" MinRegisterYears="1" MaxRegisterYears="10" MinRenewYears="1" MaxRenewYears="10" MinTransferYears="1" MaxTransferYears="10" IsApiRegisterable="false" IsApiRenewable="false" IsApiTransferable="false" IsEppRequired="false" IsDisableModContact="false" IsDisableWGAllot="false" IsIncludeInExtendedSearchOnly="true" SequenceNumber="11" Type="CCTLD" IsSupportsIDN="false" Category="A">BZ Country Domain</Tld>
      <Tld Name="ca" NonRealTime="true" MinRegisterYears="1" MaxRegisterYears="10" MinRenewYears="1" MaxRenewYears="10" MinTransferYears="1" MaxTransferYears="10" IsApiRegisterable="false" IsApiRenewable="false" IsApiTransferable="false" IsEppRequired="false" IsDisableModContact="false" IsDisableWGAllot="false" IsIncludeInExtendedSearchOnly="true" SequenceNumber="7" Type="CCTLD" IsSupportsIDN="false" Category="A">Canada Country TLD</Tld>
      <Tld Name="cc" NonRealTime="false" MinRegisterYears="1" MaxRegisterYears="10" MinRenewYears="1" MaxRenewYears="10" MinTransferYears="1" MaxTransferYears="10" IsApiRegisterable="false" IsApiRenewable="false" IsApiTransferable="false" IsEppRequired="false" IsDisableModContact="false" IsDisableWGAllot="false" IsIncludeInExtendedSearchOnly="true" SequenceNumber="9" Type="CCTLD" IsSupportsIDN="false" Category="A">CC TLD</Tld>
      <Tld Name="co.uk" NonRealTime="false" MinRegisterYears="2" MaxRegisterYears="10" MinRenewYears="2" MaxRenewYears="10" MinTransferYears="2" MaxTransferYears="10" IsApiRegisterable="true" IsApiRenewable="false" IsApiTransferable="false" IsEppRequired="false" IsDisableModContact="false" IsDisableWGAllot="false" IsIncludeInExtendedSearchOnly="false" SequenceNumber="18" Type="CCTLD" IsSupportsIDN="false" Category="A">UK based domain</Tld>
    </Tlds>
  </CommandResponse>
  <Server>IMWS-A06</Server>
  <GMTTimeDifference>+5:30</GMTTimeDifference>
  <ExecutionTime>0.047</ExecutionTime>
</ApiResponse>

I make the call like so:

$response = Http::get(env('NAMECHEAP_SANDBOX'), [
    'ApiUser' => env('NAMECHEAP_APIUSER'),
    'ApiKey' => env('NAMECHEAP_APIKEY'),
    'UserName' => env('NAMECHEAP_USERNAME'),
    'Command' => 'namecheap.domains.gettldlist',
    'ClientIp' => env('NAMECHEAP_IP')
]);

$xml = simplexml_load_string($response->getBody(), 'SimpleXMLElement', LIBXML_NOCDATA);
$json = json_encode($xml);
$array = json_decode($json, TRUE);

I get a response where gTLDs are shown like so: tld-list-image

The overall structure of the returned array is:

structure-image

However, I would like to retrieve a list of names that are simple as shown in their API docs. Like biz, cc, and so on. If anyone could point me in a direction it would be very helpful.


Solution

  • The image is misleading. The whole data contained in the SimpleXMLElement is not showing.

    $xml = simplexml_load_string($response->getBody(), 'SimpleXMLElement', LIBXML_NOCDATA);
    
    /* I don't think this is needed
    $json = json_encode($xml);
    $array = json_decode($json, TRUE);
    */
    
    dd($xml) // This should look like your images. Notice no extra data is in the Tlds.
    
    dd($xml->CommandResponse->Tlds->Tld[0]); // surprise, the data is there.
    

    If you want to dump the attributes, you can use string casting to do it.

    foreach ($xml->CommandResponse->Tlds->Tld as $tld) {
        dump( (string) $tld['Name'] );
    }
    

    For example, this is the output of trying this out with the sample XML enter image description here