очистка между определенными идентифицируемыми тегами из xml

у меня есть следующее, чтобы извлечь название валюты, код валюты, страну и курс, проблема в том, что он захватывает все валюты, я хотел бы получить только определенные валюты, то есть только доллары США, фунты стерлингов и канадские доллары.

<?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>';
?>

person Dasa    schedule 04.05.2011    source источник


Ответы (6)


Этот фрагмент кода должен выполнять работу намного чище:

<?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']

person James C    schedule 04.05.2011

Кажется, это работает достаточно прилично: оно отфильтровывает все, чего нет в $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";
person Berry Langerak    schedule 31.05.2011

Говорящий код

$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 copy&pase **/

Шаг за шагом

Хорошо, во-первых, вы используете объект SimpleXML для чтения данных из банка Израиля. Я предлагаю использовать этот объект для выполнения большей части работы (что намного быстрее по сравнению с фильтрацией с помощью PHP, хотя SimpleXML не лучший вариант для повышения производительности).

Итак, прежде всего, чего мы хотим достичь? Получение данных на основе содержимого его элемента. Для веб-дизайнера это должно звучать как 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);

Удачного зацикливания!

person Samuel Herzog    schedule 01.06.2011
comment
Такой же как ты. Возьмите то, что вы разместили, и замените первую строку ($ xchange = new ...) кодом, который я принес, и он будет работать. - person Samuel Herzog; 01.06.2011

Просто замените

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>";
    }
}
person Doug    schedule 03.06.2011

Я делаю это следующим образом

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'];
    }
  }
}
person Touchpad    schedule 07.06.2011

ПОНЯТНО

<?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>";


?>
person Dasa    schedule 31.05.2011
comment
это не способ сделать это, порядок и количество валют могут измениться - person borrel; 07.06.2011