|
|
|
| Нужно разобрать вот этот файл - 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";
|
| |
|
|
|
|
|
|
|
для: Лена
(27.08.2009 в 21:04)
| | и есть существенные причины не сделать это честно (через xml_parse или simplexml_load_...)? | |
|
|
|
|
|
|
|
для: Trianon
(27.08.2009 в 21:21)
| | >и есть существенные причины не сделать это честно
Нет. И если уже совсем честно делать, тогда придется на них ссылку давать.
А в чем выгода xml_parse? | |
|
|
|
|
|
|
|
для: Лена
(27.08.2009 в 21:40)
| | я имел в виду не источник информации, а метод её обработки.
А в чем выгода preg? | |
|
|
|
|
|
|
|
для: 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, $out, 2);
print_r($out);
?>
|
| |
|
|
|
|
|
|
|
для: heed
(27.08.2009 в 22:04)
| | и если, к примеру, источник поменяет порядок следования элементов в теге FORECAST или тегов внутри, скрипт строевым шагом отправится куда?
Правильно - туда, каких слов я при дамах не произношу.
Туда же, кстати, отправится и претендент на собеседовании. | |
|
|
|
|
|
|
|
для: Trianon
(27.08.2009 в 22:44)
| | думаю претендент не отправится ,)
его туда просто вежливо попросят отправиться.
на юникс это место ,если не ошибаюсь, называется /dev/null | |
|
|
|
|
|
|
|
для: heed
(27.08.2009 в 23:04)
| | это человек не отправится (ибо уже не будет претендентом.)
А претендент - очень даже. :)) | |
|
|
|
|
|
|
|
для: Trianon
(27.08.2009 в 21:45)
| | >А в чем выгода preg?
В потраченном времени. С XML-разборщиками дела ранее не имела, чтобы попробовать, нужно время. Рег. выражения привычнее. Если есть смысл, сделаю с XML. Как сделаю, покажу. Просьба выложить решение с XML уже после того, как я напишу.
У меня библиотека expat даже не установлена, буду искать. | |
|
|
|
|
|
|
|
для: Лена
(27.08.2009 в 22:06)
| | Я тут как-то приводил пример... уж не помню, что он разбирал, то ли валюты центробанка, то ли чей-то каталог товаров, то ли какой-то RSS - несущественно. Инициатором темы был 1999 , если не ошибаюсь. А библиотека там, по-моему никакая и не нужна...
Ссылку не даю, коль так просите :) | |
|
|
|
|
|
|
|
|
для: lgar
(28.08.2009 в 00:17)
| | там было несколько сопряженных.
Вообще-то Лена просила не подсказывать. | |
|
|
|
|
|
|
|
для: 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 ряда, чтобы в верхнем ряду был сегодняшний день, в нижнем - завтрашний. Не приложу ума, как это сделать.
И еще одно. Возможно ли поменять порядок выводимых данных: мне нужно сначала вывести температуру, а после - ветер и давление, но у меня выводится все в том порядке, какой в исходнике.
А теперь и ссылку посмотрю... | |
|
|
|
|
|
|
|
для: Лена
(28.08.2009 в 13:11)
| | если сперва подготовить данные (в ассоциативном массиве, очевидно) , и лишь на обработке endElement() из этого массива их вывести, то будет то что надо.
Можно собрать данные в массив вообще со всего потока.
Отступ вложенных операторов стоит поправить. | |
|
|
|
|
|
|
|
для: 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'] - запишется четыре раза с этим индексом разная информация. | |
|
|
|
|
|
|
|
для: Лена
(29.08.2009 в 14:00)
| | Тег FORECAST тоже проходит через поток.
И позволяет фиксировать накопленную группу данных.
А где тег TOWN повторяется, я не вижу. Как минимум, не вижу на (27.08.2009 в 22:04)
Или это не оно? | |
|
|
|
|
|
|
|
для: 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++;
} - и тоже без результата. | |
|
|
|
|
|
|
|
для: Лена
(30.08.2009 в 00:18)
| | >Сдаюсь.Не получается.
Собственно, Igar ссылку указал. Там в начале мой универсальный вариант, потом его 1999 тщетно пытается запихнуть в ООП-обертку.
Или Вы хотите специализированный вариант для Вашего случая? | |
|
|
|
|
|
|
|
для: Trianon
(30.08.2009 в 00:42)
| | Хочу, чтоб было понятно, как можно поставить "метку", когда нам попадается тег FORECAST.
А универсальный вариант ваш поможет мне запихнуть в массив? | |
|
|
|
|
|
|
|
для: Лена
(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);
|
останутся ядрышки :) | |
|
|
|
|
|
|
|
для: Trianon
(30.08.2009 в 00:51)
| | Уже иду спать, завтра на свежую голову разберусь в вашем коде. Так что ждите новых вопросов. | |
|
|
|
|
|
|
|
для: 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 минут. | |
|
|
|
|
|
|
|
для: 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);
?>
|
| |
|
|
|
|
|
|
|
для: Лена
(30.08.2009 в 22:41)
| | не осилил.
Из-за форматирования. | |
|
|
|
|
|
|
|
для: Trianon
(30.08.2009 в 23:42)
| | >не осилил.
Не страшно. И так работает. Просто я к вашему коду прилепила свой вывод в таблицу. | |
|
|
|
|
|
|
|
для: Лена
(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">';
|
и им же, написанным в-квадратик, разница невелика. | |
|
|
|
|
|
|
|
для: Лена
(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'] содержит параметр | |
|
|
|
|
|
|
|
для: heed
(28.08.2009 в 20:20)
| | Встроили давно уже...
P.S.: можно ещё использовать XSLT преобразование. | |
|
|
|
|
|
|
|
для: @ndry
(05.09.2009 в 13:01)
| | привели бы пример. | |
|
|
|
|
|
|
|
для: 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 | |
|
|
|