XML в ассоциативный массив и вывод конкретных значений

Я не уверен, что делаю это правильно, но я пытаюсь отразить отдельные элементы данных из массива, но безуспешно, мне нужно всего лишь получить около 10 переменных для среднего расхода топлива из XML-файла здесь: https://www.fueleconomy.gov/ws/rest/ympg/shared/vehicles?make=honda&model=civic

Мне нужны только марка, модель, год avgMpg, который является дочерним элементом youMpgVehicle и т. д., поэтому я могу поместить их в таблицу так же, как вы можете вывести данные SQL в PHP.

function download_page($path){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$path);
curl_setopt($ch, CURLOPT_FAILONERROR,1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
//curl_setopt($ch, CURLOPT_SSLVERSION,3); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 

$retValue = curl_exec($ch);          
curl_close($ch);
return $retValue;
}

$sXML = download_page('https://www.fueleconomy.gov/ws/rest/ympg/shared/vehicles?make=honda&model=civic');
$oXML = new SimpleXMLElement($sXML);

$dom = new DomDocument();
$dom->loadXml($sXML);
$dataElements = $dom->getElementsByTagName('vehicle');
$array = array();
foreach ($dataElements as $element) {
$subarray = array();
foreach ($element->childNodes as $node) {
    if (!$node instanceof DomElement) {
        continue;
    }
    $key = $node->tagName;
    $value = $node->textContent;
    $subarray[$key] = $value;
 }
 $array[] = $subarray;
 // var_dump($array);  // returns the array as expected

var_dump($array[0]["barrels08"]); //how can I get this and other variables?


}

Структура такая: (Или вы можете нажать на гиперссылку выше)

-<vehicles>
-<vehicle>
<atvType/>
<barrels08>10.283832</barrels08>
<barrelsA08>0.0</barrelsA08>
<charge120>0.0</charge120>
<charge240>0.0</charge240>
<city08>28</city08>
<city08U>28.0743</city08U>
<cityA08>0</cityA08>
<cityA08U>0.0</cityA08U>
<cityCD>0.0</cityCD>
<cityE>0.0</cityE>
<cityUF>0.0</cityUF>
<co2>279</co2>
<co2A>-1</co2A>
<co2TailpipeAGpm>0.0</co2TailpipeAGpm>
<co2TailpipeGpm>279.0</co2TailpipeGpm>
<comb08>32</comb08>
<comb08U>31.9768</comb08U>
<combA08>0</combA08>
<combA08U>0.0</combA08U>
<combE>0.0</combE>
<combinedCD>0.0</combinedCD>
<combinedUF>0.0</combinedUF>
<cylinders>4</cylinders>
<displ>1.8</displ>
<drive>Front-Wheel Drive</drive>
<engId>18</engId>
<eng_dscr/>
<evMotor/>
<feScore>8</feScore>
<fuelCost08>1550</fuelCost08>
<fuelCostA08>0</fuelCostA08>
<fuelType>Regular</fuelType>
<fuelType1/>
<fuelType2/>
<ghgScore>8</ghgScore>
<ghgScoreA>-1</ghgScoreA>
<guzzler/>
<highway08>39</highway08>
<highway08U>38.5216</highway08U>
<highwayA08>0</highwayA08>
<highwayA08U>0.0</highwayA08U>
<highwayCD>0.0</highwayCD>
<highwayE>0.0</highwayE>
<highwayUF>0.0</highwayUF>
<hlv>0</hlv>
<hpv>0</hpv>
<id>33504</id>
<lv2>12</lv2>
<lv4>12</lv4>
<make>Honda</make>
<mfrCode>HNX</mfrCode>
<model>Civic</model>
<mpgData>Y</mpgData>
<phevBlended>false</phevBlended>
<pv2>83</pv2>
<pv4>95</pv4>
<rangeA/>
<rangeCityA>0.0</rangeCityA>
<rangeHwyA>0.0</rangeHwyA>
<trans_dscr/>
<trany>Automatic 5-spd</trany>
<UCity>36.4794</UCity>
<UCityA>0.0</UCityA>
<UHighway>55.5375</UHighway>
<UHighwayA>0.0</UHighwayA>
<VClass>Compact Cars</VClass>
<year>2013</year>
<youSaveSpend>3000</youSaveSpend>

- 33.612226599 45 55 47 28 16 33504


person user3270591    schedule 12.02.2014    source источник
comment
этот код работает так, как ожидалось. var_dump($array[0]["barrels08"]); выводит правильные данные. в чем дело?   -  person Volkan Ulukut    schedule 12.02.2014
comment
Да, похоже, это работает, но если вы измените это на var_dump($array[0][barrelsA08]); который является следующим узлом, это не так, если только я не ошибаюсь. Изменение 0 на 1, 2, 3 и т. д., похоже, тоже не имеет значения.   -  person user3270591    schedule 12.02.2014


Ответы (2)


На самом деле вам не нужно помещать все в массив, если вы просто хотите отобразить данные. SimpleXML упрощает обработку XML-данных. Если я могу предложить, возможно, менее сложное решение:

<?php

function getFuelDataAsXml($make, $model)
{
  // In most cases CURL is overkill, unless you need something more complex
  $data = file_get_contents("https://www.fueleconomy.gov/ws/rest/ympg/shared/vehicles?make={$make}&model={$model}");

  // If we got some data, return it as XML, otherwise return null       
  return $data ? simplexml_load_string($data) : null;
}

// get the data for a specific make and model
$data = getFuelDataAsXml('honda', 'civic');

// iterate over all vehicle-nodes
foreach($data->vehicle as $vehicleData)
{
  echo $vehicleData->barrels08 . '<br />';
  echo $vehicleData->yourMpgVehicle->avgMpg . '<br />';
  echo '<hr />';
}
person Quasdunk    schedule 12.02.2014
comment
Спасибо, это похоже на то, что я искал! Большое спасибо за вашу помощь! - person user3270591; 12.02.2014
comment
@ user3270591 Рад, что смог помочь :) - person Quasdunk; 12.02.2014

Чтобы получить данные из DOM, используйте Xpath:

$url = "https://www.fueleconomy.gov/ws/rest/ympg/shared/vehicles?make=honda&model=civic";

$dom = new DomDocument();
$dom->load($url);
$xpath = new DOMXpath($dom);

foreach ($$xpath->evaluate('/*/vehicle') as $vehicle) {
  var_dump(         
    array(
      $xpath->evaluate('string(fuelType)', $vehicle),
      $xpath->evaluate('number(fuelCost08)', $vehicle),
      $xpath->evaluate('number(barrels08)', $vehicle)
    )
  ); 
}

Большинство выражений Xpath возвращают список узлов, которые можно повторить с помощью foreach. Использование number() или string() преобразует значение или содержимое первого узла в число с плавающей запятой или строку. Если список был пуст, вы получите пустое значение.

person ThW    schedule 12.02.2014