Jachym
Jachym

Reputation: 485

Getting data from XML

I am struggling with reading XML file using PHP.

The XML I want to use is here: http://www.gdacs.org/xml/rss.xml

Now, the data I am interested are the "item" nodes.

I created the following function, which gets the data:

$rawData = simplexml_load_string($response_xml_data);

foreach($rawData->channel->item as $value) { 
    $title = $value->title;

.... this works fine.

The nodes with the "gdcs:xxxx" were slightly more problematic, but I used the following code, which also works:

$subject = $value->children('dc', true)->subject;

Now the problem I have is with the "resources" node,

Basically the stripped down version of it would look like this:

<channel>
   <item>
      <gdacs:resources>
         <gdacs:resource id="xx" version="0" source="xx" url="xx" type="xx">
            <gdacs:title>xxx</gdacs:title>
         </gdacs:resource>
         <gdacs:resource id="xx" version="0" source="xx" url="xx" type="xx">
            <gdacs:title>xxx</gdacs:title>
         </gdacs:resource>
         <gdacs:resource id="xx" version="0" source="xx" url="xx" type="xx">
            <gdacs:title>xxx</gdacs:title>
         </gdacs:resource>
      </gdacs:resources>
   </item>
</channel>

How in this case would I get the resources? I was able to get always just the first resource and only the title of it. What I would like to do is get all the resources items, which have "type" of a particular value and get their URL.

Upvotes: 2

Views: 180

Answers (2)

DannyZB
DannyZB

Reputation: 543

Running through XML the regular path, is , from my experience, slow and excruciating.

Have a look into XPath -> it's a way to extract data from XML through selectors ( similar to CSS selectors )

http://php.net/manual/en/simplexmlelement.xpath.php

You can select elements by their attributes similar to CSS

<?php
$xmlStr = file_get_contents('some_xml.xml'); 
$xml = new SimpleXMLElement($xmlStr); 

$items = $xml->xpath("//channel/item");

$urls_by_item = array();
foreach($items as $x) {
    $urls_by_item [] = $x->xpath("//gdacs:resources/gdacs:resource[@type='image']/@url");
} 

Upvotes: 2

Parfait
Parfait

Reputation: 107767

Consider using the node occurrence of xpath with square brackets [] to align urls with corresponding titles. A more involved modification of @Daniel Batkilin's answer, you can incorporate both data pieces in an associative multidimensional array, requiring nested for loops.

$xml = simplexml_load_file('http://www.gdacs.org/xml/rss.xml'); 
$xml->registerXPathNamespace('gdacs', 'http://www.gdacs.org');

$items = $xml->xpath("//channel/item");

$i = 1;
$out = array();
foreach($items as $x) {       

    $titles = $xml->xpath("//channel/item[".$i."]/gdacs:resources/gdacs:resource[@type='image']/gdacs:title");
    $urls = $xml->xpath("//channel/item[".$i."]/gdacs:resources/gdacs:resource[@type='image']/@url");

    for($j=0; $j<count($urls); $j++) {

        $out[$j.$i]['title'] = (string)$titles[$j];
        $out[$j.$i]['url'] = (string)$urls[$j];                    

    }

    $i++;
}

$out = array_values($out);
var_dump($out);

ARRAY DUMP

array(40) {
  [0]=>
  array(2) {
    ["title"]=>
    string(21) "Storm surge animation"
    ["url"]=>
    string(92) "http://webcritech.jrc.ec.europa.eu/ModellingCyclone/cyclonesurgeVM/1000226/final/outres1.gif"
  }
  [1]=>
  array(2) {
    ["title"]=>
    string(26) "Storm surge maximum height"
    ["url"]=>
    string(101) "http://webcritech.jrc.ec.europa.eu/ModellingCyclone/cyclonesurgeVM/1000226/final/P1_MAXHEIGHT_END.jpg"
  }
  [2]=>
  array(2) {
    ["title"]=>
    string(12) "Overview map"
    ["url"]=>
    string(64) "http://dma.gdacs.org/saved/gdacs/tc/1000226/clouds_1000226_2.png"
  }
  [3]=>
  array(2) {
    ["title"]=>
    string(41) "Map of rainfall accummulation in past 24h"
    ["url"]=>
    string(70) "http://dma.gdacs.org/saved/gdacs/tc/1000226/current_rain_1000226_2.png"
  }
  [4]=>
  array(2) {
    ["title"]=>
    string(23) "Map of extreme rainfall"
    ["url"]=>
    string(62) "http://dma.gdacs.org/saved/gdacs/tc/1000226/rain_1000226_2.png"
  }
  [5]=>
  array(2) {
    ["title"]=>
    string(34) "Map of extreme rainfall (original)"
    ["url"]=>
    string(97) "http://www.ssd.noaa.gov/PS/TROP/DATA/ETRAP/2015/NorthIndian/THREE/2015THREE.pmqpf.10100000.00.GIF"
  }

...

Upvotes: 1

Related Questions