Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: XML против регулярных выражений
 
 автор: mesos   (22.07.2007 в 02:34)   письмо автору
 
 

В свете последних тем на форуме, связанных с работой разного рода XML-сервисов у меня возник вопрос, почему во многих случаях для разбора данных применяются регулярные выражения? Вроде бы сейчас у большинства хостеров стоит PHP5 и поэтому для удобной работы с XML не требуется даже подключения модуля xmlrpc, а вполне достаточно встроенных классов DOM.
Хочу оговориться, что я ни в коем случае не против регулярных выражений, их знание в любом случае необходимо, но не будет ли более правильным, при работе с какой-то технологией, использование методов, созданных специально для нее?
На мой взгляд, любой Xpath-запрос применительно к XML намного нагляднее сложных (а зачастую весьма громоздких) шаблонов PCRE.
Чтобы не быть голословным, приведу примеры функций для получения курсов валют и погоды.
При необходимости, могу также предоставить примеры разбора любого XML-based формата (например RSS ;-).

Курсы валют
Функции передается два параметра - символьный код валюты (можно посмотреть на сайте ЦБ) и необязательный - дата (при отсутствии используется текущая).
Функция возвращает массив, в котором первым элементом будет дата изменения котировок, а вторым - хеш, соответствующий узлу Valute в XML, где ключами являются имена узлов, а значениями - соответствующие текстовые узлы.
<?php
function get_currency($ccode$date=false) {
    static 
$xmld,$xmlm false;
    
$xml_url "http://www.cbr.ru/scripts/XML_daily.asp?date=$date";
    
$ccode   strtoupper($ccode); if(!$date$date date('d/m/Y');
    
$daily   = array('AUD''GBP''BYR''DKK''USD''EUR'
                     
'ISK''KZT''CAD''CNY''NOK''XDR'
                     
'SGD''TRY''UAH''SEK''CHF''JPY',
                     );
    if(
in_array($ccode$daily)) $xml = @$xmld $xmld $xmld DOMDocument::load($xml_url);
    else 
$xml = @$xmlm $xmlm $xmlm DOMDocument::load($xml_url.'&d=1');
    if(!
$xml) return false;
    
$xpath = new DOMXpath($xml);
    
$cdate $xml->firstChild->getAttribute('Date');
    
$snippet $xpath->query("/ValCurs/Valute[CharCode='$ccode'][1]")->item(0);
    if(!
$snippet) return false;
    
$result = array();
    
$params $xpath->query("child::*"$snippet);
    foreach(
$params as $element
      
$result[strtolower($element->nodeName)] = 
        
function_exists('iconv') ? iconv('UTF-8''CP1251'$element->nodeValue) : 
          (
function_exists('libiconv') ? libiconv('UTF-8''CP1251'$element->nodeValue) : $element->nodeValue);
    return array(
$cdate$result);
}
?>

Особенности:
При отсутствии на сервере расширений iconv или libiconv, название валюты будет в кодировке UTF-8.
При получении курсов нескольких валют в пределах одного выполнения скрипта, запрос к серверу ЦБ происходит не более 1(2) раз(а) благодаря использованию статических переменных.
Использование функции выглядит так:
list($lastdate, $result) = get_currency('EUR');


Прогноз погоды с gismeteo.ru
Функции передается один параметр - код нужного города (берется с сайта gismeteo)
на выходе имеем хеш вида: town=>Название города, forecast=>массив с прогнозами.
Для массива прогнозов, ключ элемента представляет собой метку времени UNIX для даты, на которую составлен прогноз, а значение - двумерный хеш всяких параметров и значений.
Проще сделать print_r(get_meteo(27612)); чем описывать их все :)
<?php
function get_meteo($town_id) {
    if(!
intval($town_id)) return false;
    
$xml_url "http://informer.gismeteo.ru/xml/{$town_id}_1.xml";
    
$xml DOMDocument::load($xml_url);
    if(!
$xml) return false;
    
$result = array();
    
$xpath  = new DOMXpath($xml);
    
$temp   $xpath->query("//TOWN[@index=$town_id]/@sname");
    
$result['town'] = urldecode($temp->item(0)->nodeValue);
    
$temp   $xpath->query('FORECAST'$temp->item(0)->parentNode);
    foreach(
$temp as $element) {
        
$tmp  = array();
        
$date $xpath->query("@year|@month|@day|@hour"$element);
        foreach(
$date as $param$tmp[$param->nodeName]=$param->nodeValue;
        
$date strtotime("{$tmp['year']}-{$tmp['month']}-{$tmp['day']} {$tmp['hour']}:00:00");
        
$childs $xpath->query('child::*'$element);
        foreach(
$childs as $node) {
            
$tmp  = array();
            
$qres $xpath->query("@cloudiness|@precipitation|@rpower|@spower|@min|@max|@direction"$node);
            foreach(
$qres as $param$tmp[$param->nodeName]=$param->nodeValue;
            
$result['forecast'][$date][strtolower($node->nodeName)] = $tmp;
        }
    }
    return 
$result;
}
?>


Ну а теперь, полезные ссылки:
DOM functions
Описание Xpath
Примеры Xpath

   
 
 автор: cheops   (22.07.2007 в 11:47)   письмо автору
 
   для: mesos   (22.07.2007 в 02:34)
 

Хм... тему упинают в скорости - вы не хотите этот материал в статью оформить?

PS Регулярные выражения полезны при разборе не корректных (оборванных) XML-файлов.

   
 
 автор: mesos   (22.07.2007 в 14:13)   письмо автору
 
   для: cheops   (22.07.2007 в 11:47)
 

Насчет статьи попробую. Свободного времени к сожалению сейчас мало.
Как вам ее передать в случае чего?

А по поводу некорректных XML, может я идеалист, но все же верю, что XML всегда подразумевает структурное соответствие стандарту. Ну а если это просто недокачанный файл, то стоит подумать о улучшении каналов связи (просто за большинством XML-сервисов никогда не замечал некорректной работы даже при больших нагрузках).

   
 
 автор: cheops   (23.07.2007 в 11:29)   письмо автору
 
   для: mesos   (22.07.2007 в 14:13)
 

Если появится время для оформления статьи, пришли её пожалуйста на igor @ softtime.ru (сообщите таже своё ФИО).

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования