Помогите с парсером погоды

Тема в разделе "PHP", создана пользователем VandJ, 12 мар 2009.

Модераторы: latteo
  1. VandJ

    VandJ

    Регистр.:
    8 апр 2008
    Сообщения:
    318
    Симпатии:
    113
    Добрый день
    Хочу сделать парсер погоды с wether.co.ua
    С сервера передается следующий код
    Код:
    <forecast version="1.2" last_updated="Thu, 12 Mar 2009 19:06:53 +0200">	
    	<forecast> 
    		<day date="2009-03-12" hour="21"> 
    			<cloud>30</cloud> 
    			<pict>_3_pasmurno.gif</pict> 
    			<ppcp>45</ppcp> 
    			<t> 
    				<min>4</min> 
    				<max>6</max> 
    			</t> 
    			<p> 
    				<min>759</min> 
    				<max>762</max> 
    			</p> 
    			<wind> 
    				<min>2</min> 
    				<max>4</max> 
    				<rumb>134</rumb> 
    			</wind> 
    			<hmid> 
    				<min>73</min> 
    				<max>79</max> 
    			</hmid> 
    			<wpi>85</wpi> 
    		</day> 
    	</forecast> 
    </forecast> 
    
    В программировании не силен, вернее мои знания стремятся к нулю:ah:.
    Немного погуглил и нашел вот такую ссылочку:
    http://www.providerz.ru/articles/php/xml-sax-dom-intro.html.
    Сделал по аналогии следующее:
    Код:
    <?php
    $day = array();        // В этом массиве будут храниться новости,
                            // полученные из XML файла
    $currentDay = null;    // Текущая новость. Используется в процессе
                            // импорта данных
    $index = null;          // Текущий индекс в массиве новостей.
                            // Используется в процессе импорта данных
    
    // Функции, описанные ниже, являются обработчиками различных типов
    // XML-данных и будут вызываться парсером в процессе разбора.
    
    // Функция для обработки начальных тегов XML
    // На входе:
    //   - указатель на SAX парсер
    //   - имя XML тега
    //   - массив аттрибутов
    function saxStartElement($parser,$name,$attrs)
    {
        global $currentDay,$index;
    
        switch($name)
        {
            case 'forecast':
    // Тег newsLine содержит все новости. Мы должны подготовить
    // массив $news для приема новостей из XML файла.
                $news = array();
                break;
                case 'day':
    // Каждая новость находится в теге news. Подготавливаем массив
    // $currentNews для приема этой новости
                $currentNews = array();
    // Если у новости есть дата - сохраняем ее в массиве
                if (in_array('date',array_keys($attrs)))
                    $currentDay['date'] = $attrs['date'];
               	if (in_array('hour',array_keys($attrs)))
                    $currentDay['hour'] = $attrs['hour'];
                break;
            default:
    
    // Все остальные теги, которые могут встретиться в XML файле
    // находятся внутри тега <news>, поэтому мы просто запоминаем
    // их название с тем, чтобы знать, какие именно данные мы
    // обрабатываем.
                $index = $name;
                break;
        };
    }
    
    // Функция для обработки конечных тегов XML
    // На входе:
    //   - указатель на SAX парсер
    //   - имя XML тега
    function saxEndElement($parser,$name)
    {
        global $day,$currentDay,$index;
    
        if ((is_array($currentDay)) && ($name=='day'))
    // Если в данный момент у нас есть массив $currentNews (т.е.
    // мы обрабатываем содержимое новости) и имя закрывающего
    // тега - "news", то это значит, что данные для этой новости
    // кончились и мы можем поместить готовую новость в массив
    // новостей.
        {
            $day[] = $currentDay;
    // Уничтожаем массив текущей новости, чтобы показать, что
    // в данный момент мы не занимаемся получением данных для
    // новости.
            $currentDay = null;
        };
    // В любом случае закрытие тега означает, что символьные
    // данные, получаемые парсером не нужно помещать куда-либо.
        $index = null;
    }
    
    // Функция для обработки символьных данных
    // На входе:
    //   - указатель на SAX парсер
    //   - символьные данные XML
    function saxCharacterData($parser,$data)
    {
        global $currentDay,$index;
    
    // Мы принимаем только данные для новостей, помещенные в
    // какой-нибудь тег. Все остальные символьные данные
    // (как правило это пустое пространство, использованное
    // для форматирования) мы опускаем за ненадобностью.
        if ((is_array($currentDay)) && ($index))
            $currentDay[$index] = $data;
    }
    
    // Создаем SAX парсер, который будет использоваться для
    // обработки XML-данных.
    $parser = xml_parser_create();
    // Регистрируем функции для обработки различных типов
    // XML-данных:
    //  - начальный и конечный тэги XML
    xml_set_element_handler($parser,'saxStartElement','saxEndElement');
    //  - символьные данные
    xml_set_character_data_handler($parser,'saxCharacterData');
    // Также существуют аналогичные функции для регистрации
    // обработчиков других типов XML-данных.
    // Убираем case folding, в этом случае имена тэгов будут
    // передаваться обработчикам в оригинальном виде. Если case
    // folding включен, то все имена тегов будут переведены
    // в верхний регистр.
    xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,false);
    // Получаем содержимое XML-файла с новостями.
    $xml = join('',file('http://xml.weather.co.ua/1.2/forecast/72?dayf=5&lang=ru'));
    // Производим парсинг (разбор) полученного XML-файла.
    // В процессе разбора парсер будет вызывать описанные нами
    // функции и в результате мы получим массив $news,
    // содержащий новости из XML-файла.
    if (!xml_parse($parser,$xml,true))
    // Парсер возвращает значение FALSE, если произошла
    // какая-либо ошибка. В этом случае мы также прекращаем
    // выполнение скрипта и возвращаем ошибку.
        die(sprintf('Ошибка XML: %s в строке %d',
            xml_error_string(xml_get_error_code($parser)),
            xml_get_current_line_number($parser)));
    // Уничтожаем парсер, освобождая занятые им ресурсы
    xml_parser_free($parser);
    print_r($day);
    ?>
    
    Но эти строки из XML не идентифицируются, т.к. данные в них заключены в одинаковые теги (min и max:(

    Код:
    <t> 
    				<min>4</min> 
    				<max>6</max> 
    			</t> 
    			<p> 
    				<min>759</min> 
    				<max>762</max> 
    			</p> 
    			<wind> 
    				<min>2</min> 
    				<max>4</max> 
    				<rumb>134</rumb> 
    			</wind> 
    			<hmid> 
    				<min>73</min> 
    				<max>79</max> 
    			</hmid> 
    Подскажите, что и как нужно сделать, буду премного благодарен.
     
  2. _AlexSK_

    _AlexSK_ Постоялец

    Регистр.:
    30 окт 2008
    Сообщения:
    59
    Симпатии:
    8
  3. amxm

    amxm Создатель

    Регистр.:
    25 июл 2008
    Сообщения:
    18
    Симпатии:
    0
    на SimpleXML это делается легко, просто и красиво!
     
  4. EveryNEXT

    EveryNEXT Писатель

    Регистр.:
    24 авг 2008
    Сообщения:
    6
    Симпатии:
    0
    А у кого есть на SimpleXML? Я его не понимаю:bc:
     
  5. medvoodoo

    medvoodoo Постоялец

    Регистр.:
    28 мар 2007
    Сообщения:
    89
    Симпатии:
    19
    PHP:
    $xml = <<<HTML
    <forecast version="1.2" last_updated="Thu, 12 Mar 2009 19:06:53 +0200">
        <forecast>
            <day date="2009-03-12" hour="21">
                <cloud>30</cloud>
                <pict>_3_pasmurno.gif</pict>
                <ppcp>45</ppcp>
                <t>
                    <min>4</min>
                    <max>6</max>
                </t>
                <p>
                    <min>759</min>
                    <max>762</max>
                </p>
                <wind>
                    <min>2</min>
                    <max>4</max>
                    <rumb>134</rumb>
                </wind>
                <hmid>
                    <min>73</min>
                    <max>79</max>
                </hmid>
                <wpi>85</wpi>
            </day>
        </forecast>
    </forecast>
    HTML;
    $dom = new DOMDocument();//новый дом
    $dom->loadXML($xml);//для загрузки из файла ->load($namefile)
    $domxp = new DOMXPath($dom);//новый xpatch
    $result $domxp->query("//day/cloud");//запрос нода cloud
    echo $result->item(0)->nodeValue;//вывод первого,если значение не единично то через foreach
    $result $domxp->query("//day/@date");//вывод атрибута
    echo $result->item(0)->nodeValue;
    вот пример, дальше по аналогии. Здесь DOMXML используется
     
    VandJ нравится это.
  6. homes77

    homes77 Писатель

    Регистр.:
    27 мар 2009
    Сообщения:
    4
    Симпатии:
    1
    у меня так сделана, может пригодится кому, где нашел код непомню
     
    Nedikoff нравится это.
  7. bik20007

    bik20007 Читатель

    Заблокирован
    Регистр.:
    11 апр 2008
    Сообщения:
    455
    Симпатии:
    46
    а где нужно подправить, чтобы был прогноз на неделю, а не на один день??
     
  8. alexz15

    alexz15

    Регистр.:
    3 окт 2008
    Сообщения:
    394
    Симпатии:
    189
    не знаю, нужно смотреть на informer.gismeteo.ru, может там есть в формате xml на неделю.
     
  9. NoN

    NoN Постоялец

    Регистр.:
    25 ноя 2008
    Сообщения:
    79
    Симпатии:
    33
    На неделю, гисметео халявно экспорт не дают..., да и впрочем никто наверно из русских это не дает...
    Нужно пасить сайт...
     
  10. VandJ

    VandJ

    Регистр.:
    8 апр 2008
    Сообщения:
    318
    Симпатии:
    113
    weather.co.ua - Отличный сервис. Импорт в XML. Бесплатно. И не требуют размещения ссылки!!!