Witam szukałem na forum ale nie znalazłem odpowiedniej podpowiedzi jak zrobić aby dane z zewnętrznego pliku xml były zapisywane w bazie danych sql.
Chodzi mi o to że ze strony o pogodzie odczytuję dane z pliku xml. Dane te aktualizują się co jakiś czas (co 30 min) http://www.yr.no/place/Polen/Vest-Pommern/Choszczno/forecast.xml
Czy jest ajkiś sposób aby można było zapisać te dane w odpowiednich tabelach w mojej bazie danych. Import musiał by robić się automatycznie z możliwością zadpisywania danych jeśli były zmienione oraz z możliwością dodawania nowych id bo codziennie pojawiają się nowe prognozy na kolejne dni.
Mam nadzieję że wyjaśniłem o co mi chodzi nie potrafię sobie z tym poradzić. Proszę o jakieś wskazuówki lub przykładowy kod. Z góry dziękuję i pozdrawiam.
Napisz parser XML => twoja baza
Cronem odpalaj co 30min
Ah żeby to było takie proste jak piszesz to pewnie bym to zrobił. Możesz podać jakieś większe szczegóły. Nie znam się na tym.
Może coś takiego:
http://rpbouman.blogspot.com/2006/03/importing-xml-data-into-mysql-using.html
<time from="2014-08-25T10:00:00" to="2014-08-25T12:00:00" period="1"><!-- Valid from 2014-08-25T10:00:00 to 2014-08-25T12:00:00 --><symbol number="2" numberEx="2" name="Fair" var="02d"/><precipitation value="0"/><!-- Valid at 2014-08-25T10:00:00 --><windDirection deg="253.6" code="WSW" name="West-southwest"/><windSpeed mps="4.9" name="Gentle breeze"/><temperature unit="celsius" value="14"/><pressure unit="hPa" value="1014.9"/></time>
CREATE TABLE `choszczno` ( `id` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, `time_from` varchar(255) DEFAULT NULL, `time_to` varchar(255) DEFAULT NULL,, `symbol_var` int(255) DEFAULT NULL, `precipitation_value` int(255) DEFAULT NULL, `windDirection_code` int(255) DEFAULT NULL, `windSpeed_mps` int(255) DEFAULT NULL, `temperature_value` int(255) DEFAULT NULL, `pressure_value` int(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM;
Czas to ma byc DATETIME a nie zadne VARCHAR
Inne wartosci liczbowe to z tego co widze w XML to są liczby rzeczywiste a nie całkowite.
Jak odczytac XML? uzyj SimpleXML - patrz manual php.
Gdy odczytasz XML przejdziemy do zapisu w bazie
Dobra udało mi się ocdczytać plik xml
<?php $weatherdata = simplexml_load_file('http://www.yr.no/place/Polen/Vest-Pommern/Choszczno/forecast.xml'); $name = $weatherdata->location->name; $time = $weatherdata->forecast->tabular->time; $symbol = $weatherdata->forecast->tabular->time->symbol; $temperature = $weatherdata->forecast->tabular->time->temperature; $windDirection = $weatherdata->forecast->tabular->time->windDirection; $windSpeed = $weatherdata->forecast->tabular->time->windSpeed; $pressure = $weatherdata->forecast->tabular->time->pressure; ?> <style> .temp { background-color: #FEB100; color: #fff; font-family: arial; font-size: 12px; font-weight: bold; padding-bottom: 3px; padding-top: 3px; padding-left: 6px; padding-right: 6px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; text-align: center; } .wiatr { background-color: #464646; color: #fff; font-family: arial; font-size: 12px; font-weight: bold; padding-bottom: 3px; padding-top: 3px; padding-left: 6px; padding-right: 6px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; text-align: center; } .cisnienie { background-color: #e4e4e4; color: #444; font-family: arial; font-size: 12px; font-weight: bold; padding-bottom: 3px; padding-top: 3px; padding-left: 6px; padding-right: 6px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; text-align: center; } .data { background-color: #f5f5f5; color: #555; font-family: arial; font-size: 12px; font-weight: bold; padding-bottom: 3px; padding-top: 3px; padding-left: 5px; padding-right: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; border: 1px solid #e4e4e4; width: 350px; text-align: center; } .miejscowosc { background-color: #2bb853; color: #fff; font-family: arial; font-size: 12px; font-weight: bold; padding-bottom: 3px; padding-top: 3px; padding-left: 5px; padding-right: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; text-align: center; } .tekst { color: #fff; font-family: arial; font-size: 12px; font-weight: bold; padding-bottom: 3px; padding-top: 3px; padding-left: 8px; padding-right: 8px; text-align: center; } .brak { padding-bottom: 3px; padding-top: 3px; padding-left: 4px; padding-right: 4px; text-align: center; } </style> <?php http://www.php.net/echo "<table border='0'> <tr> <td class='miejscowosc'>$name</td> <td class='tekst'>Prognoza na najbliższe godziny</td> </tr> </table>\n"; foreach ($weatherdata->forecast as $time) { http://www.php.net/echo '<table border="0" cellpadding="0" cellspacing="0"> <tr> <td></td> </tr> </table>'; http://www.php.net/echo '<table border="0" cellpadding="0" cellspacing="0" width="300px"> <tr><td>'; http://www.php.net/echo '<table border="0" cellpadding="0" cellspacing="0" width="60px"> <tr> <td class="ikon"><img src="infusions/prognozy_panel/ikonki/'.$symbol['var'].'.png"</td> </tr> </table>'; http://www.php.net/echo '</td><td align="left">'; http://www.php.net/echo '<table border="0" cellpadding="0" cellspacing="5"> <tr> <td class="temp">'.$temperature['value'].' ?C</td> <td class="brak"> </td> <td class="wiatr">'.$windSpeed['mps'].' m/s</td> <td class="brak"> </td> <td class="cisnienie">'.$pressure['value'].' hPa</td> </tr> </table>'; http://www.php.net/echo '</td></tr></table>'; } ?>
Tym kodem pobierasz tylko po jednym rekordzie. A chyba ci chodzilo o pobranie wszystkich.
Tak dokładnie ale nie wiem jak to zrobić aby pobrał kolejne rekordy.
http://pl1.php.net/manual/en/simplexml.examples-basic.php
Przyklad Example #4 Accessing non-unique elements in SimpleXML
Masz tam pokazane jak pobrac wszystkie CHARACTER. Analogicznie masz zrobic u siebie
W jakim miejscu mam umieścić ten kod?
Ten kod pobiera dane z xml, więc masz go umieścić tam, gdzie chcesz pobrać dane z XML.
Coś nie mogę sobie z tym poradzić.
Daję taki kod.
foreach ($weatherdata->forecast->time as $time) { http://www.php.net/echo $time->time, ' played by ', $time->time, PHP_EOL;
foreach ($weatherdata->forecast->tabular as $time) { http://www.php.net/echo $time->time, ' played by ', $time->time, PHP_EOL;
Pyton ty tez źle napisales....
foreach ($weatherdata->forecast->tabular->time as $time) { //i dopiero teraz lecisz po kazdym znaczniku <time> twojego XML }
$weatherdata = simplexml_load_file('http://www.yr.no/place/Polen/Vest-Pommern/Choszczno/forecast.xml'); foreach ($weatherdata->forecast->tabular->time as $time) { http://www.php.net/echo 'od: '.$time['from'].' do:'.$time['to'].' temperatura: '.$time->temperature['value'].' itd. <br />'; }
Dałem tak
foreach ($weatherdata->forecast->tabular->time as $time) { //i dopiero teraz lecisz po kazdym znaczniku <time> twojego XML http://www.php.net/echo $time->symbol, ' played by ', $time->symbol, PHP_EOL; http://www.php.net/echo $time->temperature, ' played by ', $time->temperature, PHP_EOL; http://www.php.net/echo $time->windDirection, ' played by ', $time->windDirection, PHP_EOL; http://www.php.net/echo $time->windSpeed, ' played by ', $time->windSpeed, PHP_EOL; http://www.php.net/echo $time->pressure, ' played by ', $time->pressure, PHP_EOL;
foreach ($weatherdata->forecast as $time) {
Spojrz jeszcze raz na moj poprzedni post.... Masz tam podany cały poprawny kod...
Super wielkie dzięki teraz jeszcze pozostaje kwestia jak te dane zapisywać w bazie danych z możliwością nadpisywania i dodawania nowych rekordów.
No dobra, ale czego nie wiesz? Jak wlozyc dane do bazy? Z innego tematu wiem, że wpisywales już coś do bazy, wiec z czym problem?
W innym temacie dane piszę ręcznie i tam wszystko idzie do bazy danych.
A w tym muszę zapisać dane pobierane przez xml typu temperatura i inne do bazy danych chodzi mi o same wartoście i z tym mam problem.
Ale to nie ma zadnej roznicy czy wkladasz dane recznie czy ze zmiennych.
Poza tym w tamtym temacie tez nie wkladasz recznie tylko ze zmiennych.... O to
VALUES('$dzien', '$godzina', '$intensywnostmin', '$lat','$lng','$flaga','$miejsce')");
to jest wkladanie ze zmiennych.
Pewnie masz rację zwał jak zwał, ale możesz mi z tym pomóc? Nie wiem jak napisać kod, który doda mi rekordy z tymi danymi.
No weź napisz tego insserta i nie czaruj... Przeciez juz inserty umiesz pisac. Wysil sie troche wkoncu sam.
Jak cos napiszesz i nie bedzie dzialac, to pomoge dalej, ale zacznij chociaz sam.
W tej petli co masz teraz zrobioną przeze mnie, masz dodac INSERT do bazy. Niczym to sie nie rozni od inserta, ktorego robisz w innym temacie.
Dobra zmieniłem trochę bazę danych
Do pliku dodałem to
include ("db.php"); $time = $_POST['time']; $symbol = $_POST['symbol']; $temperature = $_POST['temperature']; $windDirection = $_POST['windDirection']; $windSpeed = $_POST['windSpeed']; $pressure = $_POST['pressure']; $add = http://www.php.net/mysql_query("INSERT INTO choszczno(time, symbol, temperature, windDirection, windSpeed, pressure) VALUES('$time', '$symbol', '$temperature', '$windDirection','$windSpeed','$pressure')");
Jaki post? A gdzie petla?
Przeciez napisalem wyraznie:
zapytanie masz wlozyć w petle, którą ci napisalem. A wartosci to są te wartosci, ktore w tej petli wyswietlales a nie jakies rzeczy niz gruszki ni z pietruszki z posta.
ok dałem to w tej pętli
include ("db.php"); $add = http://www.php.net/mysql_query("INSERT INTO choszczno('.$time['from'].', '.$time->symbol['var'].', '.$time->temperature['value'].', '.$time->windDirection['value'].', '.$time->windSpeed['mps'].', '.$time->pressure['value'].') VALUES('$time', '$symbol', '$temperature', '$windDirection','$windSpeed','$pressure')");
$add = http://www.php.net/mysql_query("INSERT INTO choszczno('.$time['from'].', '.$time->symbol['var'].', '.$time->temperature['value'].', '.$time->windDirection['value'].', '.$time->windSpeed['mps'].', '.$time->pressure['value'].') VALUES('$time', '$symbol', '$temperature', '$windDirection','$windSpeed','$pressure')");
Przepraszam, wlasnie stracilem cierpliwosc... Moze odzyskam za kilka godzin Byc moze w tym czasie pomoze ci ktos inny.
1. Poprawna składnia wygląda np. tak
INSERT INTO users(`id`, `login`) VALUES(1, 'Jan Kowalski')
Zrobiłem tak jak podałeś ale wyskakuje błąd
$add = http://www.php.net/mysql_query("INSERT INTO choszczno(`time` `symbol` `temperature` `windDirection` `windSpeed` `pressure`) VALUES('.$time['from'].', '.$time->symbol['var'].', '.$time->temperature['value'].', '.$time->windDirection['value'].', '.$time->windSpeed['mps'].', '.$time->pressure['value'].')");
Nazwy kolumn oddziela się przecinkiem a nie spacją
Jesli do łączenia tekstow uzywasz '..' to i tekst ma sie zaczynac i konczyc ' a nie "
A wartosci tekstowe w zapytaniu bierze się w apostrofy, czego nadal nie robisz.
@Turson a Ty jak podajesz jak ma wygladac poprawna składnia, to patrz czy sam nie robisz w niej bzdurnych literowek....
Dałem tak
$add = http://www.php.net/mysql_query('INSERT INTO choszczno(`time`,`symbol`,`temperature`,`windDirection`,`windSpeed`,`pressure`) VALUES('.$time['from'].', '.$time->symbol['var'].', '.$time->temperature['value'].', '.$time->windDirection['value'].', '.$time->windSpeed['mps'].', '.$time->pressure['value'].')');
A gdzie masz tekst w apostrofach? :/ Bo jedyne co zrobiłeś to zmieniłeś " na ' i łączysz zmienne...
"INSERT INTO tabela(dupa1, dupa2) VALUES('$dupa1', '$dupa2')"
to nie jest naprawde trudne
@down
Nie trzyma jednej, bo już sam zmienił na inną.
Super, zdecydowanie lepiej.
A wartosci tekstowe docelowo mają wygladac tak:
values ('wartosc tekstowa')
A u ciebie docelowo wygladaja tak
values (wartosc tekstowa)
Tak ma byc:
$add = http://www.php.net/mysql_query('INSERT INTO choszczno(`time`,`symbol`,`temperature`,`windDirection`,`windSpeed`,`pressure`) VALUES(\''.$time['from'].'\', \''.$time->symbol['var'].'\', '.$time->temperature['value'].', '.$time->windDirection['value'].', '.$time->windSpeed['mps'].', '.$time->pressure['value'].')');
Ok działa zapisuje się tylko jest jeden problem jak odświerzam stronę to robią się nowe rekordy a powinno jeśli jest zmiana tylko je nadpisywać. Jutro jak wejdę ponownie na stronę to powinien pojawić się nowy rekord z nowymi danymi na kolejny dzień.
Po pierwsze: zacznij w koncu uzywac znakow interpunkcyjnych... no wiesz: kropka, przecinek itp.
To zdanie:
Ok działa zapisuje się tylko jest jeden problem
powinno wygladac tak:
Ok, działa. Zapisuje się. Tylko jest jeden problem:
prawda ze czytelniej? Czytajacy nie musi sie zastanawiac gdzie konczy jedno a zaczyna drugie przez co czyta sie o wiele przyjemniej a nie jak u Ciebie wszystko ciurkiem i samemu trzeba wyłapywac kontekst :/
Co do problemu:
Mozesz to rozwiązac np. poprzez założenie unikalnych kluczy na wartosci, ktore będą mowic, ze dany zestaw danych moze pojawic sie tylko raz w tabeli
Odnosze wrazenie, ze w tym temacie to wielokrotnie Cię zastrzeliłem i powinienes juz dawno 5 razy umrzec
Manual mysql: UNIQUE KEY
Ale widzisz na raz wykonuje się kilkanaście rekordów z racji tego, że to jest prognoza na kilka dni. Parametry w tym czasie mogą się powtarzać. Chodzi o to że jak będę odświerzał stronę to pojawiają się aktualizacje prognozy z pliku xml
Przykładowo:
Dzisiaj o 18:00 temperatura ma być 17 stopni (i tak też zapisało się do bazy danych)
Jak wejdę np: za godzinę to temperatura na godzinę 18:00 może wynieść 14 stopni i tu powinno to się nadpisać.
Oczywiście po 3 godzinach pojawiają się prognozy na kolejne dni co powinno dawać nowe rekordy do bazy danych.
No dobrze, wszystko się zgadza.
Dlatego ci tlumacze, że masz zalozyc UNIQUE KEY a zamiast
INSERT masz dac
INSERT....ON DUPLICATE KEY UPDATE
i wszystko bedzie cacy
Jesli wiec to godzina jest wyznacza unikalnosc, to masz załozyc UNIQUE KEY na pole z data/godziną.
Ale jak zalozyc UNIQUE KEY?
Czy to robi się w bazie danych?
Tak.
PhpMyAdmin -> baza -> tabela -> struktura
Nie mam pojęcia jak to zmienić w bazie danych nie mam takiej opcji UNIQUE
W strukturze na dole jest "Indeksy" i tam dodajesz nowy
Jesteś LEŃ:
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
Przepraszam za odkopanie tematu ale dotyczy tej samej bazy i pliku xml więc nie zakładałem nowego.
Obecnie działa to na zasadzie, że po wywołaniu pliku php zostają zapisane dane z xml do bazy danych. Ponieważ te dane w pliku xml zmieniają się co 3 godziny potrzebne też są zmiany w bazie danych. Zależy mi na tym aby dane były nadpisywane bo nie potrzebne mi są kolejne rekordy. Tym bardziej, że rekordów jest zawsze tyle samo, zmieniają się tylko dane.
Próbowałem robić to przez UPDATE ale nie działa.
Proszę o pomoc.
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)