#php #xml #simplexml
#php #xml #simplexml
Вопрос:
у меня есть следующее, чтобы извлечь название валюты, код валюты, страну и курс, проблема в том, что он захватывает все валюты, я хотел бы получить только определенные валюты, т. Е. только usd gbp и cad
<?php
$xchange = new SimpleXMLElement('http://www.bankisrael.gov.il/currency.xml', NULL, TRUE);
echo "
<table>
<tr>
<th>n</th>
<th>cc</th>
<th>c</th>
<th>r</th>
</tr>";
foreach($xchange as $curr) // loop through our books
{
echo "
<tr>
<td>{$curr->NAME}</td>
<td>{$curr->CURRENCYCODE}</td>
<td>{$curr->COUNTRY}</td>
<td>{$curr->RATE}</td>
</tr>";
}
echo '</table>';
?>
Ответ №1:
Этот фрагмент кода должен выполнять работу гораздо более чистым способом:
<?php
$a = getCurrencyData('http://www.bankisrael.gov.il/currency.xml');
print_r($a);
function getCurrencyData($url) {
$raw = file_get_contents($url);
$xml = new SimpleXMLElement($raw);
$ret = array();
foreach($xml->CURRENCY as $currency) {
$currency = (array) $currency;
$ret[$currency['CURRENCYCODE']] = $currency;
}
return $ret;
}
Теперь вы можете просто получить нужные валюты, используя код валюты, например $a['GBP']
Ответ №2:
Кажется, это работает достаточно прилично: оно отфильтровывает все, чего нет в $ filter. Если он находится в $filter, он будет отображаться. Я протестировал это, и, похоже, это работает как шарм.
<?php
/**
* This is an array indicating which currencies you want to show.
*/
$filter = array(
'usd',
'gbp',
'cad'
);
$root = simplexml_load_file( 'http://www.bankisrael.gov.il/currency.xml' );
echo "
<table>
<tr>
<th>n</th>
<th>cc</th>
<th>c</th>
<th>r</th>
</tr>n";
foreach( $root->CURRENCY as $currency ) {
if( in_array( (string) strtolower( $currency->CURRENCYCODE ), $filter ) ) {
echo "
<tr>
<td>{$currency->NAME}</td>
<td>{$currency->CURRENCYCODE}</td>
<td>{$currency->COUNTRY}</td>
<td>{$currency->RATE}</td>
</tr>n";
}
}
echo "</table>n";
Ответ №3:
Говорящий код
$xchange = new SimpleXMLElement('http://www.bankisrael.gov.il/currency.xml', NULL, TRUE);
$filterCurrencies = array( 'USD', 'GBP' );
$filter = implode( array_map( function($filler) { return 'text()="'.$filler.'"'; }, $filterCurrencies), ' or ' );
$xpathQuery = $xpath = '//CURRENCYCODE[%filter%]/parent::*';
$xpathQuery = str_replace('%filter%', , $xpathQuery);
$currencies = $xchange->xpath($xpathQuery);
/** I do know you already have to code to echo it ... the code is tested, feel free to copyamp;pase **/
Шаг за шагом
Хорошо, прежде всего, вы используете объект SimpleXML для чтения данных из bank israel. Я предлагаю использовать этот объект для выполнения большей части работы (что намного быстрее по сравнению с фильтрацией с помощью PHP, хотя SimpleXML не самый лучший вариант для производительности).
Итак, прежде всего, чего мы хотим достичь? Получение данных a на основе содержимого его элемента. Для веб-дизайнера это должно звучать как CSS, но не совсем правильно. Для веб-разработчика, имеющего в своих руках XML, который должен звучать как XPath, что является идеальным выбором! К счастью, SimpleXML позволяет нам использовать XPath, поэтому мы создадим запрос:
Основы XPath:
//CURRENCYCODE
выберет любой элемент currencycode
//CURRENCYCODE/parent::*
выберет родительский код currencycodes ( <CURRENCY>
), в котором находятся наши данные
//CURRENCYCODE[text()="JPY"]
будут выбраны только <CURRENCY>
элементы, текст которых точно равен JPY.
Здесь мы солим с нашим списком требований:
$filterCurrencies = array( 'USD', 'GBP' ); // we want us dollars and british pounds
$filter = implode( array_map( function($token) { return 'text()="'.$token.'"'; }, $filterCurrencies), ' or ' );
// this will make a string like 'text()="USD" or text()="GBP"' by mapping the filter against the requirements string (currenciecodes get tokens) glueing it with a logical or
Теперь единственное, что осталось сделать, это интегрировать это с нашим шаблоном XPATH
$xpath = '//CURRENCY[%filter%]/parent::*';
$xpath = str_replace('%filter%', $filter, $xpath);
$currencies = $xchange->xpath($xpath);
Удачного зацикливания!
Комментарии:
1. То же, что и вы. Возьмите то, что вы опубликовали, и замените первую строку ($ xchange = new …) приведенным мной кодом, и это сработает.
Ответ №4:
Просто замените
foreach($xchange as $curr) // loop through our books
{
echo "
<tr>
<td>{$curr->NAME}</td>
<td>{$curr->CURRENCYCODE}</td>
<td>{$curr->COUNTRY}</td>
<td>{$curr->RATE}</td>
</tr>";
}
с
foreach($xchange as $curr) // loop through our books
{
if (in_array($curr->CURRENCYCODE, array('usd', 'gbp', 'cad'))) {
echo "
<tr>
<td>{$curr->NAME}</td>
<td>{$curr->CURRENCYCODE}</td>
<td>{$curr->COUNTRY}</td>
<td>{$curr->RATE}</td>
</tr>";
}
}
Ответ №5:
Я делаю это следующим образом
function xml ($url) {
$text = file_get_contents($url) or die("ERROR: Unable to read file");
$p = xml_parser_create();
xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
xml_parse_into_struct($p, $text, $vals, $index);
xml_parser_free($p);
for($i=0; $i<count ($index['Title']); $i ) {
foreach(array('var1', 'var2', 'var3') as $key) {
$info[$i][$key] = $vals[$index[$key][$i]]['value'];
}
}
}
Ответ №6:
ПОНЯЛ
<?php
$xchange = new SimpleXMLElement('http://www.bankisrael.gov.il/currency.xml', NULL, TRUE);
echo "
<table>
<tr>
<th>n</th>
<th>cc</th>
<th>c</th>
<th>r</th>
</tr>
<tr>
<td>United States {$xchange->CURRENCY[0]->NAME} </td>
<td>{$xchange->CURRENCY[0]->CURRENCYCODE} </td>
<td>{$xchange->CURRENCY[0]->RATE} </td>
</tr>
<tr>
<td>{$xchange->CURRENCY[1]->COUNTRY} {$xchange->CURRENCY[1]->NAME} </td>
<td>{$xchange->CURRENCY[1]->CURRENCYCODE} </td>
<td>{$xchange->CURRENCY[1]->RATE} </td>
</tr>
<tr>
<td>{$xchange->CURRENCY[3]->NAME} </td>
<td>{$xchange->CURRENCY[3]->CURRENCYCODE} </td>
<td>{$xchange->CURRENCY[3]->RATE} </td>
</tr>
<tr>
<td>{$xchange->CURRENCY[4]->COUNTRY}n {$xchange->CURRENCY[4]->NAME} </td>
<td>{$xchange->CURRENCY[4]->CURRENCYCODE} </td>
<td>{$xchange->CURRENCY[4]->RATE} </td>
</tr>
<tr>
<td>Canadian {$xchange->CURRENCY[5]->NAME} </td>
<td>{$xchange->CURRENCY[5]->CURRENCYCODE} </td>
<td>{$xchange->CURRENCY[5]->RATE} </td>
</tr>
<tr>
<td>{$xchange->CURRENCY[8]->COUNTRY}n {$xchange->CURRENCY[8]->NAME} </td>
<td>{$xchange->CURRENCY[8]->CURRENCYCODE} </td>
<td>{$xchange->CURRENCY[8]->RATE} </td>
</tr>
<tr>
<td>Swiss {$xchange->CURRENCY[10]->NAME} </td>
<td>{$xchange->CURRENCY[10]->CURRENCYCODE} </td>
<td>{$xchange->CURRENCY[10]->RATE} </td>
</tr>
</table>";
?>
Комментарии:
1. это не способ сделать это, порядок и количество валют могут измениться