Home > Net >  How to correctly parse and format XML in PHP?
How to correctly parse and format XML in PHP?

Time:11-20

So, i am doing an assignment where i need to get the current currency exchange between EUR - USD, i must use PHP and have never used it before, all the data is available on this website https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml?5105e8233f9433cf70ac379d6ccc5775

My code so far is

`<php
    
    ini_set('default_charset', 'UTF-8');
    $url = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml?5105e8233f9433cf70ac379d6ccc5775";
    $xml = simplexml_load_file($url);
    echo $xml->Cube;
    foreach ($xml as $record) {
        print_r($record);
    }

?>`

The output for me is really confusing because it is showing arrays and the tags have ":" like "gesmes:Envelope" and i don't know how to do it, any help is appreciated!

CodePudding user response:

The XML is indeed a little confusing.
I had this topic before so i can give you a working example:

EDIT: im not sure what the hash tag is for on your url. I think you do not need it.

ini_set('default_charset', 'UTF-8');
$url = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml?5105e8233f9433cf70ac379d6ccc5775";
$xml = simplexml_load_file($url, 'SimpleXMLElement', LIBXML_NOCDATA);
if (!$xml instanceof \SimpleXMLElement) {
    throw new \Exception("Cannot get currency rates. Cannot parse Xml.");
}
if (!isset($xml->Cube->Cube->Cube)) {
    throw new \Exception("Cannot get currency rates. Xml path wrong.");
}
$rates = [];
foreach ($xml->Cube->Cube->Cube as $rate) {
    $rates[strtoupper((string)$rate['currency'])] = (float)$rate['rate'];
}
echo var_export($rates, true) . PHP_EOL;

Result:

// array (
//     'USD' => 1.1271,
//     'JPY' => 128.22,
//     'BGN' => 1.9558,
//     'CZK' => 25.413,
//     'DKK' => 7.4366,
//     'GBP' => 0.83928,
//     'HUF' => 367.8,
//     'PLN' => 4.6818,
//     'RON' => 4.9495,
//     'SEK' => 10.096,
//     'CHF' => 1.0462,
//     'ISK' => 147.8,
//     'NOK' => 10.0483,
//     'HRK' => 7.516,
//     'RUB' => 82.8124,
//     'TRY' => 12.5247,
//     'AUD' => 1.5581,
//     'BRL' => 6.268,
//     'CAD' => 1.4254,
//     'CNY' => 7.2027,
//     'HKD' => 8.7832,
//     'IDR' => 16105.54,
//     'ILS' => 3.4887,
//     'INR' => 83.6905,
//     'KRW' => 1344.64,
//     'MXN' => 23.4637,
//     'MYR' => 4.7152,
//     'NZD' => 1.6098,
//     'PHP' => 57.073,
//     'SGD' => 1.5344,
//     'THB' => 36.969,
//     'ZAR' => 17.7513,
// )

EDIT 2: you may also have a look https://api.exchangerate.host/ .
Example call for only USD: https://api.exchangerate.host/latest?base=EUR&symbols=USD
Example call for all: https://api.exchangerate.host/latest?base=EUR
And when i remember right you can use a date (history) instead of latest.

CodePudding user response:

You can use XPath to select directly the value you are interested of :

$url = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml?5105e8233f9433cf70ac379d6ccc5775";
$xml = simplexml_load_file($url);
$xml->registerXPathNamespace('c', "http://www.ecb.int/vocabulary/2002-08-01/eurofxref");

$currencyTarget = 'USD' ;

// look at all Cube elements (everywhere in the document) 
// that have a attribute 'currency' equals to 'USD', 
// and returns its rate attribute
$rates = $xml->xpath("//c:Cube[@currency = '$currencyTarget']//@rate"); 

// xpath returns an array, select the first (and unique) element, and convert the attribute to double
$rate = doubleval($rates[0]) ; 

var_dump($rate); // float(1.1271) 
  • Related