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

Форум Регулярные Выражения

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

 

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

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

тема: Разобрать informer.gismeteo.ru
 
 автор: Лена   (27.08.2009 в 21:04)   письмо автору
 
 

Нужно разобрать вот этот файл - http://informer.gismeteo.ru/getcode/xml.php?id=27612

То, что мне нужно из этого выбрать, я указала в своем паттерне.
Сейчас у меня вот что:

  $pattern = "|<FORECAST day=\"([\d]+)\" month=\"([\d]+)\".*
<PHENOMENA cloudiness=\"([\d]+)\" .*<PRESSURE max=\"([\d]+)\".*
<TEMPERATURE max=\"([^\"]+)\" "."min=\"([^\"]+)\".*<WIND .* max=\"([^\"]+)\" .*<RELWET max=\"(\d+)\" min=\"(\d+)\"|isU";

  Ответить  
 
 автор: Trianon   (27.08.2009 в 21:21)   письмо автору
 
   для: Лена   (27.08.2009 в 21:04)
 

и есть существенные причины не сделать это честно (через xml_parse или simplexml_load_...)?

  Ответить  
 
 автор: Лена   (27.08.2009 в 21:40)   письмо автору
 
   для: Trianon   (27.08.2009 в 21:21)
 

>и есть существенные причины не сделать это честно
Нет. И если уже совсем честно делать, тогда придется на них ссылку давать.
А в чем выгода xml_parse?

  Ответить  
 
 автор: Trianon   (27.08.2009 в 21:45)   письмо автору
 
   для: Лена   (27.08.2009 в 21:40)
 

я имел в виду не источник информации, а метод её обработки.

А в чем выгода preg?

  Ответить  
 
 автор: heed   (27.08.2009 в 22:04)   письмо автору
 
   для: Trianon   (27.08.2009 в 21:45)
 

думаю возможно даже в скорости, применительно к конкретному данному случаю
<? 
header
('content-type:text/plain');

$txt '<?xml version="1.0" encoding="utf-8"?>
<MMWEATHER>
    <REPORT type="frc3">
        <TOWN index="27612" sname="%CC%EE%F1%EA%E2%E0" latitude="56" longitude="38">
            <FORECAST day="28" month="08" year="2009" hour="03" tod="0" predict="0" weekday="6">
                <PHENOMENA cloudiness="3" precipitation="4" rpower="0" spower="0"/>
                <PRESSURE max="747" min="745"/>
                <TEMPERATURE max="16" min="14"/>
                <WIND min="1" max="3" direction="4"/>
                <RELWET max="95" min="93"/>
                <HEAT min="14" max="16"/>
            </FORECAST>
            <FORECAST day="28" month="08" year="2009" hour="09" tod="1" predict="0" weekday="6">
                <PHENOMENA cloudiness="3" precipitation="4" rpower="0" spower="0"/>
                <PRESSURE max="747" min="745"/>
                <TEMPERATURE max="16" min="14"/>
                <WIND min="0" max="2" direction="0"/>
                <RELWET max="97" min="95"/>
                <HEAT min="14" max="16"/>
            </FORECAST>
            <FORECAST day="28" month="08" year="2009" hour="15" tod="2" predict="0" weekday="6">
                <PHENOMENA cloudiness="3" precipitation="10" rpower="0" spower="0"/>
                <PRESSURE max="747" min="745"/>
                <TEMPERATURE max="23" min="21"/>
                <WIND min="0" max="2" direction="7"/>
                <RELWET max="56" min="54"/>
                <HEAT min="18" max="20"/>
            </FORECAST>
            <FORECAST day="28" month="08" year="2009" hour="21" tod="3" predict="0" weekday="6">
                <PHENOMENA cloudiness="1" precipitation="10" rpower="0" spower="0"/>
                <PRESSURE max="746" min="744"/>
                <TEMPERATURE max="15" min="13"/>
                <WIND min="1" max="3" direction="0"/>
                <RELWET max="85" min="83"/>
                <HEAT min="13" max="15"/>
            </FORECAST>
        </TOWN>
    </REPORT>
</MMWEATHER>'
;


$pattern '|<FORECAST day="(\d+)" month="(\d+)[^<]*'
    
.'<PHENOMENA cloudiness="(\d+)[^<]*'
    
.'<PRESSURE max="(\d+)[^<]*'
    
.'<TEMPERATURE max="([^"]+)" min="([^"]+)[^<]*'
    
.'<WIND[^<]*?max="([^"]+)[^<]*'
    
.'<RELWET max="(\d+)" min="(\d+)"|';




preg_match_all($pattern$txt$out2);
print_r($out);
?>

  Ответить  
 
 автор: Trianon   (27.08.2009 в 22:44)   письмо автору
 
   для: heed   (27.08.2009 в 22:04)
 

и если, к примеру, источник поменяет порядок следования элементов в теге FORECAST или тегов внутри, скрипт строевым шагом отправится куда?

Правильно - туда, каких слов я при дамах не произношу.

Туда же, кстати, отправится и претендент на собеседовании.

  Ответить  
 
 автор: heed   (27.08.2009 в 23:04)   письмо автору
 
   для: Trianon   (27.08.2009 в 22:44)
 

думаю претендент не отправится ,)
его туда просто вежливо попросят отправиться.

на юникс это место ,если не ошибаюсь, называется /dev/null

  Ответить  
 
 автор: Trianon   (27.08.2009 в 23:19)   письмо автору
 
   для: heed   (27.08.2009 в 23:04)
 

это человек не отправится (ибо уже не будет претендентом.)
А претендент - очень даже. :))

  Ответить  
 
 автор: Лена   (27.08.2009 в 22:06)   письмо автору
 
   для: Trianon   (27.08.2009 в 21:45)
 

>А в чем выгода preg?
В потраченном времени. С XML-разборщиками дела ранее не имела, чтобы попробовать, нужно время. Рег. выражения привычнее. Если есть смысл, сделаю с XML. Как сделаю, покажу. Просьба выложить решение с XML уже после того, как я напишу.
У меня библиотека expat даже не установлена, буду искать.

  Ответить  
 
 автор: Trianon   (27.08.2009 в 22:47)   письмо автору
 
   для: Лена   (27.08.2009 в 22:06)
 

Я тут как-то приводил пример... уж не помню, что он разбирал, то ли валюты центробанка, то ли чей-то каталог товаров, то ли какой-то RSS - несущественно. Инициатором темы был 1999 , если не ошибаюсь. А библиотека там, по-моему никакая и не нужна...

Ссылку не даю, коль так просите :)

  Ответить  
 
 автор: lgar   (28.08.2009 в 00:17)   письмо автору
 
   для: Trianon   (27.08.2009 в 22:47)
 

Любопытно стало, что за тема. Случайно, не эта http://softtime.ru/forum/read.php?id_forum=1&id_theme=34820?

  Ответить  
 
 автор: Trianon   (28.08.2009 в 00:26)   письмо автору
 
   для: lgar   (28.08.2009 в 00:17)
 

там было несколько сопряженных.
Вообще-то Лена просила не подсказывать.

  Ответить  
 
 автор: Лена   (28.08.2009 в 13:11)   письмо автору
 
   для: Trianon   (27.08.2009 в 22:47)
 

Библиотека действительно не нужна оказалась, все и так работает.

<?php
$tags 
='';

function 
startElement($parser$name$attrs) {
//print_r($name);
//print_r($attrs);

if ($name == 'TOWN') {
$tags .= '<strong>'mb_convert_encoding(urldecode($attrs['SNAME']),'UTF-8''windows-1251').'</strong><br />';
}

elseif (
$name == 'FORECAST') {
$tags .= '<div id = "' strtolower($name) . '">' $attrs['DAY']."/".$attrs['MONTH']."</div>";
}

elseif (
$name == 'PHENOMENA') {
$img_atr 'id = "weather_img" width="15" height="15" alt="" align ="left" valign="top"';
   switch(
$attrs['CLOUDINESS']){
     case 
0:
     
$path_to_img 'weather_0.jpg';
     
$tags .= '<img src="' $path_to_img '"' $img_atr ' />';
     break;
     case 
1:
     
$path_to_img 'weather_1.jpg';
     
$tags .= '<img src="' $path_to_img '"' $img_atr ' />';
     break;
     case 
2
     
$path_to_img 'weather_2.jpg';
     
$tags .= '<img src="' $path_to_img '"' $img_atr ' />';
     break;
     case 
3:
     
$path_to_img 'weather_3.jpg'
     
$tags .= '<img src="' $path_to_img '"' $img_atr ' />';
     break;
   }
}

elseif (
$name == 'TEMPERATURE') {
$tags .= '<div id = "' strtolower($name) . '">' $attrs['MAX'].' ... '.$attrs['MIN'].'</div>';
}

elseif (
$name == 'WIND') {
    
$tags .= '<div id = "' strtolower($name) . '"> С-'.$attrs['MAX'].'м/с</div>';
}

elseif (
$name == 'PRESSURE') {
$tags .= '<div id = "' strtolower($name) . '">' $attrs['MAX'].'мм.рт.ст.</div>';
}

return print 
$tags;
}
  
function 
endElement($parser$name) {

}
       
$data file_get_contents('http://informer.gismeteo.ua/xml/33345_1.xml');
if(!empty(
$data)) {
$XMLparser xml_parser_create();
xml_set_element_handler($XMLparser'startElement''endElement');
if (!
xml_parse($XMLparser$data)) {
        die(
sprintf("XML error: %s at line %d",
                    
xml_error_string(xml_get_error_code($xml_parser)),
                    
xml_get_current_line_number($xml_parser)));
    }
xml_parser_free($XMLparser);
}
?>


Но. Получаемые данные мне нужно запихнуть в таблицу - 2 столбца, 2 ряда, чтобы в верхнем ряду был сегодняшний день, в нижнем - завтрашний. Не приложу ума, как это сделать.
И еще одно. Возможно ли поменять порядок выводимых данных: мне нужно сначала вывести температуру, а после - ветер и давление, но у меня выводится все в том порядке, какой в исходнике.
А теперь и ссылку посмотрю...

  Ответить  
 
 автор: Trianon   (28.08.2009 в 13:56)   письмо автору
 
   для: Лена   (28.08.2009 в 13:11)
 

если сперва подготовить данные (в ассоциативном массиве, очевидно) , и лишь на обработке endElement() из этого массива их вывести, то будет то что надо.

Можно собрать данные в массив вообще со всего потока.

Отступ вложенных операторов стоит поправить.

  Ответить  
 
 автор: Лена   (29.08.2009 в 14:00)   письмо автору
 
   для: Trianon   (28.08.2009 в 13:56)
 

я, наверное, что-то недопоняла.
Сейчас делаю так:

<?php
function startElement($parser$name$attrs) {
global 
$tags;
    if (
$name == 'TOWN') {
    
$tags['town'] = '<strong>'mb_convert_encoding(urldecode($attrs['SNAME']),'UTF-8''windows-1251').'</strong><br />';
    }
//другие теги
}

function 
endElement($parser$name) {
//а вот здесь уже вывод собранного массива
global $tags;
print_r($tags);
}
?>

У меня тег TOWN повторяется четыре раза. Как я отличу $tags['town'] - запишется четыре раза с этим индексом разная информация.

  Ответить  
 
 автор: Trianon   (29.08.2009 в 14:03)   письмо автору
 
   для: Лена   (29.08.2009 в 14:00)
 

Тег FORECAST тоже проходит через поток.
И позволяет фиксировать накопленную группу данных.

А где тег TOWN повторяется, я не вижу. Как минимум, не вижу на (27.08.2009 в 22:04)
Или это не оно?

  Ответить  
 
 автор: Лена   (30.08.2009 в 00:18)   письмо автору
 
   для: Trianon   (29.08.2009 в 14:03)
 

Сдаюсь.Не получается.

>Или это не оно?
Оно. Тег FORECAST повторяется 4 раза. Даже если он будет повторяться n-количество раз, пробовала через substr_count - найти вхождение FORECAST в $name внутри startElement(), - не ищет.
$s = substr_count($name,$str);
Счетчик тоже пробовала поставить:
$i = 0;
elseif ($name == 'FORECAST') {

$tags['day'][$i] ='<div id = "' . strtolower($name) . '">' . $attrs['DAY']."/".$attrs['MONTH']."</div>";
$i++;
} - и тоже без результата.

  Ответить  
 
 автор: Trianon   (30.08.2009 в 00:42)   письмо автору
 
   для: Лена   (30.08.2009 в 00:18)
 

>Сдаюсь.Не получается.

Собственно, Igar ссылку указал. Там в начале мой универсальный вариант, потом его 1999 тщетно пытается запихнуть в ООП-обертку.

Или Вы хотите специализированный вариант для Вашего случая?

  Ответить  
 
 автор: Лена   (30.08.2009 в 00:49)   письмо автору
 
   для: Trianon   (30.08.2009 в 00:42)
 

Хочу, чтоб было понятно, как можно поставить "метку", когда нам попадается тег FORECAST.
А универсальный вариант ваш поможет мне запихнуть в массив?

  Ответить  
 
 автор: Trianon   (30.08.2009 в 00:51)   письмо автору
 
   для: Лена   (30.08.2009 в 00:49)
 

мой вариант превращает в массив любой XML-файл, вообще не вдаваясь в конкретную структуру .
И его можно поглядеть <pre> <? print_r() ?> :-)

Ну а Ваш попробую набросать.

UPD.
Если шелуху выкинуть
   <pre><?php
   $heap 
$heap['ref']
       [
'sub']['MMWEATHER'][0]
       [
'sub']['REPORT'][0]
       [
'sub']['TOWN'][0];
   
$head $heap['atr'];
   
$heap $heap['sub']['FORECAST'];
   foreach(
$heap as $n => $set)
   {
       
$newset = array('date'=>$set['atr']);
       foreach(
$set['sub'] as $k => $v)
          
$newset[$k] = $v[0]['atr'];
       
$heap[$n] = $newset;
   }
   
print_r($heap);
   
print_r($head);


останутся ядрышки :)

  Ответить  
 
 автор: Лена   (30.08.2009 в 00:59)   письмо автору
 
   для: Trianon   (30.08.2009 в 00:51)
 

Уже иду спать, завтра на свежую голову разберусь в вашем коде. Так что ждите новых вопросов.

  Ответить  
 
 автор: Trianon   (30.08.2009 в 01:59)   письмо автору
 
   для: Trianon   (30.08.2009 в 00:51)
 

Собственно, парсер, прямо заточенный под эту структуру:
<pre><?php
   $set 
= array(); $cast 0;
   function 
start_element($par$name$atr)
   {
       global 
$heap$cast;
       if(
$name == 'FORECAST')
       {
           
$heap[] = array('date' =>$atr);
           
$cast 1;
       }
       else if(@
$cast)
           
$heap[count($heap)-1][$name]=$atr;
   }

   function 
end_element($par$name)
   {
       global 
$cast;
       if(
$name == 'FORECAST')
           
$cast 0;
   }

глядеть, яcен пень, $heap

Как видите, он сильно проще универсального. Но на него был потрачен час.
А на сепаратор для универсального (который в апдейте к 30.08.2009 в 00:51) - 10 минут.

  Ответить  
 
 автор: Лена   (30.08.2009 в 22:41)   письмо автору
 
   для: Trianon   (30.08.2009 в 01:59)
 

Спасибо.
Не понятно, почему вы поставили заглушку else if(@$cast) - $cast же все время будет иметь значение.

Если добавить еще и вывод, то получится то, что было надо:

<?php
$cast 
0;

function 
start_element($par$name$atr){
    global 
$heap$cast;
           if(
$name == 'FORECAST'){
                
$heap[] = array('date' =>$atr);
                
$cast 1;
                }
                else if(
$cast)
                
$heap[count($heap)-1][$name]=$atr;
    
/*print '<pre>';
    print_r($heap);
    print '</pre>';
    */
   
}

function 
end_element($par$name){
  global 
$cast,$heap;
    if(
$name == 'FORECAST')
    
$cast 0;

}


//$data = file_get_contents('http://informer.gismeteo.ua/xml/33345_1.xml');
$fp fopen('weather.xml',"r");
$data fread($fp,filesize('weather.xml'));

if(!empty(
$data)) {
$XMLparser xml_parser_create();
xml_set_element_handler($XMLparser'start_element''end_element');
if (!
xml_parse($XMLparser$data)) {
        die(
sprintf("XML error: %s at line %d",
                    
xml_error_string(xml_get_error_code($xml_parser)),
                    
xml_get_current_line_number($xml_parser)));
    }

$col 2;
$n count($heap); 
print 
'<table border = "1px">'
for (
$i=0$i<$n$i++){ 
    if (!(
$i%$col)) print '<tr>';
        print 
'<td><div id = "day">' $heap[$i]['date']['DAY'] . '/' $heap[$i]['date']['MONTH']; 
        print 
'</div>';

        
$img_atr 'id = "weather_img" width="15" height="15" alt="" align ="left" valign="top"';
                switch(
$heap[$i]['PHENOMENA']['CLOUDINESS']){
                       case 
0:
                       
$path_to_img 'weather_0.jpg';
                       print 
'<img src="' $path_to_img '"' $img_atr ' />';
                       break;
                       case 
1:
                       
$path_to_img 'weather_1.jpg';
                       print 
'<img src="' $path_to_img '"' $img_atr ' />';
                       break;
                       case 
2
                       
$path_to_img 'weather_2.jpg';
                       print 
'<img src="' $path_to_img '"' $img_atr ' />';
                       break;
                       case 
3:
                       
$path_to_img 'weather_3.jpg'
                       print 
'<img src="' $path_to_img '"' $img_atr ' />';
                      break;
                   }

            print 
'<div id = "tempr">' $heap[$i]['TEMPERATURE']['MAX'].' ... '.$heap[$i]['TEMPERATURE']['MIN'].'</div>';
        print 
'<div id = "wind"> С-'.$heap[$i]['WIND']['MAX'].'м/с</div>';
        print 
'<div id = "press">' $heap[$i]['PRESSURE']['MAX'].'мм.рт.ст.</div>';
        print 
'</td>';
      if (!(
$i+1%$col)) print '</tr>'

print 
"</table>";

xml_parser_free($XMLparser);
}
fclose($fp);

?>

  Ответить  
 
 автор: Trianon   (30.08.2009 в 23:42)   письмо автору
 
   для: Лена   (30.08.2009 в 22:41)
 

не осилил.
Из-за форматирования.

  Ответить  
 
 автор: Лена   (31.08.2009 в 13:35)   письмо автору
 
   для: Trianon   (30.08.2009 в 23:42)
 

>не осилил.
Не страшно. И так работает. Просто я к вашему коду прилепила свой вывод в таблицу.

  Ответить  
 
 автор: Trianon   (31.08.2009 в 13:44)   письмо автору
 
   для: Лена   (31.08.2009 в 13:35)
 

тем не менее.
Всё ж считаю, что между восприятием фрагмента
$fp = fopen('weather.xml',"r");
$data = fread($fp,filesize('weather.xml'));

if(!empty($data)) {
$XMLparser = xml_parser_create();
xml_set_element_handler($XMLparser, 'start_element', 'end_element');
if (!xml_parse($XMLparser, $data)) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }

$col = 2;
$n = count($heap); 
print '<table border = "1px">'; 

и им же, написанным в-квадратик, разница невелика.

  Ответить  
 
 автор: heed   (28.08.2009 в 20:20)   письмо автору
 
   для: Лена   (28.08.2009 в 13:11)
 

ещё такое сейчас встроили в php
<?
if(empty($data)) exit('<p>извинитес сегодня
 не будет свежей погоды :))</p></body></html>'
) ;
 
$xml = new SimpleXMLElement($data);
//print_r($xml->REPORT->TOWN->FORECAST);

foreach ($xml->REPORT->TOWN->FORECAST AS  $fc){ 
 
// print_r($fc); print "<hr/>\n"; 
 
echo '<div id = "forecast">' $fc['day'] .'/'$fc['month']
  . 
' '$fc['hour']. ' часа'"</div>";
//    $fc->PHENOMENA
 
$img_atr 'id = "weather_img" width="15" height="15"'
    
.' alt="" align ="left" valign="top"/>'
  echo 
'<img src="weather_'
  
$fc->PHENOMENA['cloudiness'] .'.jpg" ' .$img_atr;
//    $fc->TEMPERATURE') 
 
echo '<div id = "temperature">' $fc->TEMPERATURE['max']
  .
' ... '$fc->TEMPERATURE['min'] ."</div>\n"
//    $fc->WIND') { 
 
echo '<div id="wind"> С-'$fc->WIND['max']
 .
'м/с</div>' ."\n"
//    $fc->PRESSURE') { 
 
echo '<div id="pressure">'$fc->PRESSURE['max']
 .
'мм.рт.ст.</div>'
  
."\n" 
// print_r();
 
print "<hr/>\n";
}
?>
интересно что print_r() не показывает что ['max'] это
непосредственный элемент $fc->WIND
, однако $fc->WIND['max'] содержит параметр

  Ответить  
 
 автор: @ndry   (05.09.2009 в 13:01)   письмо автору
 
   для: heed   (28.08.2009 в 20:20)
 

Встроили давно уже...

P.S.: можно ещё использовать XSLT преобразование.

  Ответить  
 
 автор: Trianon   (05.09.2009 в 13:50)   письмо автору
 
   для: @ndry   (05.09.2009 в 13:01)
 

привели бы пример.

  Ответить  
 
 автор: @ndry   (06.09.2009 в 11:42)   письмо автору
 
   для: Trianon   (05.09.2009 в 13:50)
 

Для такого примера нужно писать xsl шаблон и PHP код, который всё будет обрабатывать, слишком много работы ради простого совета... =)

Если вам так интересно:
- http://xmlsoft.org/XSLT/
- http://www.w3.org/TR/xslt
- http://www.w3schools.com/xsl/xsl_languages.asp

  Ответить  
Rambler's Top100
вверх

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