parsing XML from curl (mobile.de API) won't work

there,

I would like to create a homepage and automatically display the ads of mobile.de on it. For this there is an API from mobile.de: https://services.mobile.de/manual/search-api.html

I have the right access data and when I start the call via the browser: https://services.mobile.de/search-api/search?customerNumber=503300

I get this result:

<search:search-result xmlns:seller="http://services.mobile.de/schema/seller" xmlns:ad="http://services.mobile.de/schema/ad" xmlns:search="http://services.mobile.de/schema/search" xmlns:financing="http://services.mobile.de/schema/common/financing-1.0" xmlns:resource="http://services.mobile.de/schema/resource" xmlns:error="http://services.mobile.de/schema/common/error-1.0">
<search:total>4</search:total>
<search:page-size>20</search:page-size>
<search:current-page>1</search:current-page>
<search:max-pages>1</search:max-pages>
<search:ads>
<ad:ad key="266399529" url="https://services.mobile.de/search-api/ad/266399529">
<ad:creation-date value="2018-11-19T07:53:58+01:00"/>
<ad:modification-date value="2018-11-19T07:53:58+01:00"/>
<ad:detail-page url="https://suchen.mobile.de/auto-inserat/porsche-997-gt3-rs-ruf-4-0-einzelst%C3%BCck-allrad-solms/266399529.html?source=api"/>
<ad:vehicle>

Looks good to me! Now I would like to go through the individual ads and there are problems. The individual ads are grouped by this line:

<ad:ad key="266399529" url="https://services.mobile.de/search-api/ad/266399529">

Through my long years of experience and especially through the Internet, I have come to the following code:

        error_reporting(E_ALL);
    ini_set('display_errors', true);
    $process = curl_init("https://services.mobile.de/search-api/search?customerNumber=503300"); 
    curl_setopt($process, CURLOPT_HTTPHEADER, array('Content-Type: application/xml')); 
    curl_setopt($process, CURLOPT_HEADER, 0); 
    curl_setopt($process, CURLOPT_USERPWD, "username:password"); 
    curl_setopt($process, CURLOPT_TIMEOUT, 30); 
    curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE); 
    $return = curl_exec($process); 
    curl_close($process);  
    $xml = simplexml_load_string($return);
    $ns = $xml->children('http://services.mobile.de/schema/ad');
    foreach($ns as $ad) {
        $attributes = $ad->attributes();
        $key = (string) $attributes['key'];

        var_dump($key);
    }  

Unfortunately I get exactly nothing as an answer, an empty page without error message.

Upvotes: 0

Views: 2252

Answers (2)

Nigel Ren
Nigel Ren

Reputation: 57131

The problem is that you have another element in between your root node and the <ad:ad> element. You need to go via the <search:ads> element...

$ns = $xml->children('http://services.mobile.de/schema/search')->ads
    ->children('http://services.mobile.de/schema/ad');

To access the details of the ads, you need to again look at the structure and see what elements you want and what namespace they are in. So for the text of the category element of each ad, you can use a loop and...

$ns = $xml->children('http://services.mobile.de/schema/search')->ads
    ->children('http://services.mobile.de/schema/ad');

foreach($ns as $ad) {
    foreach ( $ad->vehicle as $vehicle )    {
        echo (string)$vehicle->category[0]
            ->children("http://services.mobile.de/schema/resource")
            ->{'local-description'}.PHP_EOL;
    }
}  

A couple of things with this is that the <resource:local-description> element is in a different namespace, which is why it uses the ->children() with this other namespace. Also as the name contains a -, you have to access it using ->{'local-description'} to make it a valid name.

Lastly - as all this will return the element it points to, you should cast it to a string ( using (string) at the start) to make sure you end up with just the text from the element.

Upvotes: 1

The fourth bird
The fourth bird

Reputation: 163477

As an alternative you might also use an xpath expression using the namespace prefix:

//search:search-result/search:ads/ad:ad

For example:

$ads = $xml->xpath('//search:search-result/search:ads/ad:ad');
foreach ($ads as $ad) {
    $key = (string)$ad->attributes()->key;
}

Upvotes: 0

Related Questions