XML feed uitlezen met PHP

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Brecht S

Brecht S

16/05/2015 20:07:36
Quote Anchor link
Hieronder een voorbeeld van mijn feed URL
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<weatherdata>
<location>
<name>Gent</name>
<type/>
<country>BE</country>
<timezone/>
<location altitude="0" latitude="51.049999" longitude="3.71667" geobase="geonames" geobaseid="0"/>
</location>
<credit/>

<meta>
<lastupdate/>
<calctime>0.011</calctime>
<nextupdate/>
</meta>

<sun rise="2015-05-16T03:53:02" set="2015-05-16T19:29:58"/>

<forecast>

<time day="2015-05-16">
<symbol number="500" name="light rain" var="10d"/>
<precipitation value="0.5" type="rain"/>
<windDirection deg="322" code="NW" name="Northwest"/>
<windSpeed mps="4.76" name="Gentle Breeze"/>
<temperature day="13.83" min="5.78" max="14.01" night="5.78" eve="14.01" morn="13.83"/>
<pressure unit="hPa" value="1033.93"/>
<humidity value="93" unit="%"/>
<clouds value="overcast clouds" all="92" unit="%"/>
</time>

<time day="2015-05-17">
<symbol number="800" name="sky is clear" var="02d"/>
<precipitation/>
<windDirection deg="274" code="W" name="West"/>
<windSpeed mps="3.47" name="Gentle Breeze"/>
<temperature day="16.37" min="7.6" max="17.13" night="7.6" eve="15.53" morn="9.14"/>
<pressure unit="hPa" value="1034.56"/>
<humidity value="77" unit="%"/>
<clouds value="clear sky" all="8" unit="%"/>
</time>

</forecast>
</weatherdata>


Ik lees die op de onderstaande manier uit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
// Dit is de URL waarvan de output hierboven staat
$request_url1 = "http://api.openweathermap.org/data/2.5/forecast/daily?q=gent&mode=xml&units=metric&cnt=2";

$xml1 = simplexml_load_file($request_url1) or die("feed not loading");

foreach($xml1->time[0]->temperature->attributes() as $key => $test2) {
    if($key == 'day') {
        echo $test2.'C';
    }

}


Nu krijg ik geen resultaat. Waar heb ik een fout gemaakt?
Gewijzigd op 16/05/2015 20:35:10 door Brecht S
 
PHP hulp

PHP hulp

25/04/2024 19:14:30
 
Eddy E

Eddy E

16/05/2015 20:31:46
Quote Anchor link
Op regel 4 maak je $xml1 (let op de 1) aan.
Op regel 6 ga je verder met $xml (zonder 1).
 
Brecht S

Brecht S

16/05/2015 20:35:33
Quote Anchor link
Thanks Eddy. Ik heb de code even aangepast. Werkt nog steeds niet.
 
Eddy E

Eddy E

16/05/2015 20:50:51
Quote Anchor link
Welke foutmelding krijg je?

Staat error_reporting(E_ALL); bovenaan?

Toevoeging op 16/05/2015 20:52:00:

Je mist ook een } aan het eind.
 
Brecht S

Brecht S

16/05/2015 20:53:10
Quote Anchor link
Waar mis ik een } ?
Ik kreeg geen foutmelding en ook geen resultaat.
 
Eddy E

Eddy E

16/05/2015 20:59:56
Quote Anchor link
http://zunflappie.nl/phphulp/xml1.php

En dat is:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
    // altijd alle fouten tonen. Bij LIVE-gaan dit op 0 zetten.
    error_reporting(E_ALL);

    // wat halen we op?
    $xml = simplexml_load_file("http://api.openweathermap.org/data/2.5/forecast/daily?q=gent&mode=xml&units=metric&cnt=2");
    if (false === $xml)
    {

        echo 'Data kon niet geladen worden';
    }


    // benodigde functie. Kan ook ergens als include.
    function xml_attribute($object, $attribute)
    {

        if (isset($object[$attribute]))
        {

            return (string)$object[$attribute];
        }
    }


    // even een dump van de XML
    echo '<pre>' . print_r($xml, true) . '<pre>';

    echo 'Wat jij wilt hebben: '. (xml_attribute($xml -> forecast -> time[0] -> temperature, 'day'));
?>

Hetgeen wat fout ging is dat je een object wilt benaderen als string. Dat kan, maar dan eerst omzetten.
Zie http://php.net/manual/en/simplexmlelement.attributes.php

Sorry, ik had die laatste } niet meegekopieerd.
Gewijzigd op 16/05/2015 21:02:28 door Eddy E
 

16/05/2015 21:03:57
Quote Anchor link
Nogal wiedes, deze melding verschijnt:
Fatal error: Call to a member function attributes() on a non-object

Dus het is niet heel moeilijk om de fout te achterhalen. Op regel 6 moet je hebben:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
foreach($xml1->forecast->time[0]->temperature->attributes() as $key => $test2) {


Je zou je code robuuster kunnen maken met extra checks of bepaalde objecten die je verwacht niet ineens NULL blijken te zijn.

Maaruhm, je weet wel zeker dat de API de temperatuur in graden Celcius (ipv. Fahrenheit) weergeeft? :-)
 
Brecht S

Brecht S

16/05/2015 21:25:04
Quote Anchor link
Ok, nu werkt het. Thanks.
Nu wil ik een 2de URL feed doen en op dezelfde manier data eruit halen.
De url feed is nu http://api.openweathermap.org/data/2.5/weather?q=Gent&mode=xml&units=metric
Dit is een andere dan de eerste. Als ik die 2 achter elkaar zet loopt het fout en krijg ik op de eerste ook geen resultaat meer. Is dat normaal?
 

16/05/2015 21:56:04
Quote Anchor link
Kan je niet makkelijker een XPath query maken? Dat lijkt me robuuster:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$url = 'http://api.openweathermap.org/data/2.5/weather?q=Gent&mode=xml&units=metric';
$query = '//current/temperature';

$sxe = simplexml_load_file($url);
$imp = new DOMImplementation();
$dom = $imp->createDocument(null, '');
$dom->xmlVersion = '1.0';
$dom->encoding = 'UTF-8';
$xpath = new DOMXPath($dom);
$dom_sxe = dom_import_simplexml($sxe);
$dom_sxe = $dom->importNode($dom_sxe, true);
$dom_sxe = $dom->appendChild($dom_sxe);
$firstNode = $xpath->query($query)->item(0);

$temp = $firstNode->getAttribute('value') . ' graden '
      . $firstNode->getAttribute('unit');
print $temp;

/* DEBUG
header('content-type:text/plain');
var_dump($dom->saveXML());
//*/
Gewijzigd op 16/05/2015 21:56:22 door
 
Brecht S

Brecht S

16/05/2015 22:04:58
Quote Anchor link
En als ik beide url's door elkaar wil gebruiken? Lukt dit dan ook nog met XPath?
 

16/05/2015 22:09:14
Quote Anchor link
XPath is een soort querytaal om in hierarchische XML-structuren te zoeken. Je kunt bijvoorbeeld met de query '//temperature' in 1x zoeken op alle <temperature> nodes in beide URL's ja.
 
Brecht S

Brecht S

16/05/2015 22:14:06
Quote Anchor link
Kan je eens een voorbeeld posten van het gebruik in beide urls? Bvb de temperatuur van de eerste en de pressure van de 2de? Ik zie het niet voor mij hoe ik dit moet aanpakken.
 

16/05/2015 22:24:14
Quote Anchor link
Zoiets?
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
define('EOL', "\n", true);
$urls = array(
  'http://api.openweathermap.org/data/2.5/weather?q=Gent&mode=xml&units=metric',
  'http://api.openweathermap.org/data/2.5/forecast/daily?q=gent&mode=xml&units=metric&cnt=2',
);
$query = '//temperature';
$units = ' graden celcius';

$imp = new DOMImplementation();
$dom = $imp->createDocument(null, '');
$dom->xmlVersion = '1.0';
$dom->encoding = 'UTF-8';
$xpath = new DOMXPath($dom);
foreach ($urls as $url) {
  $sxe = simplexml_load_file($url);
  $dom_sxe = dom_import_simplexml($sxe);
  $dom_sxe = $dom->importNode($dom_sxe, true);
  $dom_sxe = $dom->appendChild($dom_sxe);
}

header('content-type:text/plain');
foreach ($xpath->query($query) as $node) {
  $temp = $node->getAttribute('value');
  if (!is_numeric($temp)) $temp = $node->getAttribute('day');
  print $temp . $units . EOL;
}
 
Brecht S

Brecht S

27/05/2015 11:29:05
Quote Anchor link
Werkt allemaal perfect. Hier en daar wel nog enkele aanpassingen moeten doen.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.