XML dodawanie kolejnych obiektów
-
Witam!
Od ostatniego tematu przyswoiłem sobie(względnie) dużo materiału, kilka rzeczy zrozumiałem lepiej i pozbyłem się kolejnych kilku złych nawyków.
Postawiłem sobie prosty cel. Zapisywanie danych do XML'a. Na poziomie totalnej łatwości (chociaż jednak nie do końca).
Jeśli plik XML nie istnieje, otwieram sobie nowe okno i z label'ki pobieram tekst będący rootem i ustawiam go jako zmienną globalną.
Wracam do okna głównego w którym pobieram różnej maści dane i przy użyciu metody .toString zapisuję jako łańcuch znaków.
Przy użyciu DOM tworzę z tego drzewko wyglądające jakoś tak:
@
<root>
<Wyjazdy>
<Wyjazd ID="1">
<Czasy Godzina_wyjazdu="23:00:00" Godzina_zaalarmowania="23:00:00" Godzina_powrotu="23:00:00"/>
<Adres Adres=""/>
</Wyjazd>
</Wyjazdy>
<root>
@Moją lamerską logiką pomyślałem, że stworzę do celu zapisu do tego do pliku funkcję:
@void MainWindow::ZapisWyjazduDoXML()
{
LapanieZWyjazdow(); //co by przed zapisem przeliczyło czasy/*zmienne razem*/ QTime godzinaWyjazdu = ui->godzinaWyjazduEdit->time(); QTime godzinaPowrotu = ui->godzinaPowrotuEdit->time(); QTime godzinaZaalarmowania = ui->godzinaZaalarmowaniaEdit->time(); QDate dataZdarzenia = ui->dataZdarzeniaEdit->date(); QString rodzajInterwencji = ui->comboBox_2->currentText(); QString adresZdarzenia = ui->miejsceZdarzeniaEdit->text(); /*----------------------------------*/ QString dataZdarzeniaA = dataZdarzenia.toString(); QString godzinaZaalarmowaniaA = godzinaZaalarmowania.toString(); QString godzinaWyjazduU = godzinaWyjazdu.toString(); QString godzinaPowrotuU = godzinaPowrotu.toString(); QDomDocument document; //root QDomElement root = document.createElement(NazwaOSP); //Do dokumentu dodaję roota, tak naprawde to troche fikcja, bo najpierw tworze dokument, a potem tworze element ROOT i dodaje go do dokumentu document.appendChild(root); QDomElement wyjazdy = document.createElement("Wyjazdy"); root.appendChild(wyjazdy); QDomElement wyjazd = document.createElement("Wyjazd"); wyjazd.setAttribute("ID", QString::number(i)); //wyjazd.setAttribute("Data", dataZdarzeniaA); //wyjazd.setAttribute("Rodzaj", rodzajInterwencji); wyjazdy.appendChild(wyjazd); QDomElement czasWBoju = document.createElement("Czasy"); czasWBoju.setAttribute("Godzina_zaalarmowania", godzinaZaalarmowaniaA ); czasWBoju.setAttribute("Godzina_wyjazdu", godzinaWyjazduU); czasWBoju.setAttribute("Godzina_powrotu", godzinaPowrotuU ); wyjazd.appendChild(czasWBoju); QDomElement adresZdarzeniaA = document.createElement("Adres"); adresZdarzeniaA.setAttribute("Adres", adresZdarzenia); wyjazd.appendChild(adresZdarzeniaA); i++; //zapis do pliku QFile file(Filename); if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) { ui->statusBar->showMessage("ERROR :(",2000); } QTextStream stream(&file); stream << document.toString(); file.close(); ui->statusBar->showMessage("Zapisano", 2000);
}@
Żadna filozofia. Jedna cała gałąź się zapisuje. Niestety niezgodnie z moją logiką, kolejne naciśnięcia buttona (bo tam wywołuję tę funkcję) nie powoduje stworzenia kolejnego dziecka dla Wyjazdów. Dlaczego skoro int i, zadefiniowałem globalnie i inkrementuję po każdym kliknięciu? Efekt jest dla mnie trochę nieoczekiwany gdyż każde kolejne naciśniecie buttona inkremenruje ID ale zamiast tworzyć kolejne dziecko nadpisuje wciąż to samo.
W rozszerzonej rzeczywistości ma to działać tak: otwieram plik XML->wczytuję dane do QTableView->zapisuję wszystko z okna jako nowe dziecko -> wracam na początek tego algorytmu.Wpadło mi do głowy, że może muszę napisać całą klasę na potrzebę tego pomysłu lub też pójść z myśleniem jakoś bardziej obiektowo. Any ideas?
-
a nie jest to zwyczajny problem z inkrementacją? z tego co widze uzyłes postinkrementacji a wiec tak jakby najpierw wykonaj a nastepnie dodaj a nie na odwrót i dlatego nadpisuje, po za tym wydaje mi sie ze najpierw program powinien "sprawdzic" czy root juz istnieje jednak moge sie mylic nie jestem nawet początkujacym :)
-
Nie sądzę. Sprawdziłem empirycznie i zmienna 'i' inkrementuje się tak jak powinna bo każde kolejne kliknięcie modyfikuje atrybut(tag) ID.
-
Wg mnie problem leży po stronie takiej ze klikając w button po prostu cały czas nadpisujesz ten sam plik z jednym wjazdem, raczej nic nie da tu inkrementowanie tego( bo sam jak napisałeś zmienia tylko ID ale wjazd jest ciągle jeden).
Wyjaśnienie jak jest teraz u Ciebie:
----1 klikniecie---- tworzysz nowy dokument.
- root element.
3.dodajesz child do roota czyli Wyjazdy. - dodajesz child do Wyjazdy i ID ustawiasz na wartość i(czyli 1).
- i inkrementujesz. czyli juz mamy np. warttosc i =2
- zapisujesz plik.
---2 klikniecie---
1.tworzysz znow nowy dokument. - root element.
3.dodajesz child do roota czyli Wyjazdy. - dodajesz child do Wyjazdy i ID ustawiasz na wartość i(juz 2).
- i inkrementujesz. czyli juz mamy np. warttosc i =3
- zapisujesz plik.
Zrób pare funkcji na taki wzór:
-funkcja tworząca nowy dokument xml jeśli żadnego nie masz.
-funkcja która wczyta istniejący dokument xml.
-funkcja która znajdzie w instniejacym dokumencie tag "Wyjazdy" i doda do tego kolejny child czyli "Wyjazd" z innym ID( ID_ostatniego childa + 1).
-funkcja która zapisze cały dokument w danym pliku. -
Na mój gust nadpisujesz plik. Zmień linię gdzie otwierasz plik na taki kod:
@
if( ! file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append ) )
@ -
Generalnie najprostszym rozwiazaniem okazało się wczytywanie całości danych, dopis/edycja i zapis wszystkiego.