Sprawdzanie czy wyszukiwany Node istnieje

problemy z funkcjonowaniem bibliotek, komponentów itp.

Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez marekgajewski » środa, 24 marca 2010, 09:46

Witam!
Mam następujący problem: piszę program obsługujący pliki XML, które będzie mógł edytować każdy użytkownik, dlatego zależy mi na dobrej obsłudze błędów podczas wczytywania wartości z plików XML przez program.
Powiedzmy że mam taki kod:
Kod: Zaznacz cały
AnsiString Test;
Form1->XMLDocument1 = new TXMLDocument(Form1);
Form1->XMLDocument1->Name = "Configuration";
Test = Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode("Settings")->ChildNodes->FindNode("JakiesUstawienie")->NodeValue;

I teraz jeśli np: nie będzie istniał Node "JakiesUstawienia" to program wywali błąd i na tym skończy się zabawa. Można to rozwiązać poprzez porównanie Node'a do NULL:
Kod: Zaznacz cały
if (Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode("Settings")->ChildNodes->FindNode("JakiesUstawienie") != NULL)

Program znajdzie wtedy błąd i będzie możliwe ominięcie pojawienia się okienka informującego o błędzie, ale nie wtedy, gdy np: nie będzie istniał poprzedni Node, w tym przypadku "Settings".
Musiałbym więc sprawdzać poprzedni, poprzedni i tak dłuugo, jeśli nastąpi taka potrzeba.
Czy ma ktoś pomysł, jak powinna wyglądać funkcja sprawdzająca istnienie wszystkich Node'ów, żebym nie musiał pisać kilku bezsensownych linijek przez próbą wczytania każdej wartości z pliku XML?
Avatar użytkownika
marekgajewski
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): środa, 10 marca 2010, 05:19
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Pro x64
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Opera

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez polymorphism » środa, 24 marca 2010, 10:07

(...) żebym nie musiał pisać kilku bezsensownych linijek przez próbą wczytania każdej wartości z pliku XML?

Jak to bezsensownych? :shock: Jeśli sytuacja tego wymaga, to nie są bezsensowne.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez marekgajewski » środa, 24 marca 2010, 10:24

Bezsensownych, czyli takich, które można zastąpić funkcją, która sprawdzi, czy dany Node istnieje i nie będę musiał rozpisywać się przed każdym wczytywaniem wartości z pliku XML (gdzie już na starcie programu jest tego może ze 100, więc można spokojnie policzyć sobie, ile to może być bezsensownie pisanego kodu, jeśli istnieje funkcja, które te kilka linijek zastąpi i zapewne sprawdzi o wiele szybciej).
Avatar użytkownika
marekgajewski
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): środa, 10 marca 2010, 05:19
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Pro x64
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Opera

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez polymorphism » środa, 24 marca 2010, 10:27

No to napisz taką funkcję. Nie bardzo rozumiem w czym problem?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez marekgajewski » środa, 24 marca 2010, 10:41

W tym problem, że widocznie nie jestem alfą i omegą jak co niektórzy i nie wiem czy zauważyłeś że proszę o pomoc w napisaniu takowej.
Ale rozumiem że osobiście wolisz czepiać się szczegółów, niż pomagać, więc nie ma o czym rozmawiać, bo pewnie autor nie życzy sobie wojny na swoim forum, więc nie będę odpowiadał na Twoje głupie zaczepki.
Avatar użytkownika
marekgajewski
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): środa, 10 marca 2010, 05:19
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Pro x64
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Opera

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez Cyfrowy Baron » środa, 24 marca 2010, 10:43

Jeżeli program wymaga sprawdzenia wszystkich Nod'ów to nie widzę sposobu jak to ominąć. Wczytaj wszystkie Nod'y do listy, a potem sprawdzaj je w pętli, albo opisz dokładniej istotę problemu, gdyż odnoszę wrażenie, iż sądzisz, że osoby czytające Twój post dokładnie wiedzą o co Tobie chodzi?!
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez marekgajewski » środa, 24 marca 2010, 10:54

Powiedzmy że mam taki plik XML:
Kod: Zaznacz cały
<ProgramName>
<Settings>
<Language>[b]english[/b]</Language>
</Settings>
</ProgramName>


gdzie english to nazwa pliku językowego. Jeśli ktoś dla zabawy otworzy plik XML i usunie powiedzmy <Settings> oraz </Settings>, to program podczas wczytywania wartości <Language> wyświetli błąd, dlatego chciałbym najpierw sprawdzić, czy <Language> znajduje się na swoim miejscu.

Niestety nie mogę tego zrobić przyrównując do NULL'a całość, czyli:
Kod: Zaznacz cały
if (Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode("Settings")->ChildNodes->FindNode("Language") != NULL)


bo jeśli nie będzie istniało <Settings>, to i tak program wywali błąd. Wydaje mi się, że jedynym rozwiązaniem będzie napisanie czegoś takiego:
Kod: Zaznacz cały
if (Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode("Settings") != NULL)
  if (Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode("Settings")->ChildNodes->FindNode("Language") != NULL)
    ShowMessage("Teraz wiem że istnieje");


Lecz gdy wczytuję setki takich wartości, pisanie tylu funkcji warunkowych wydaje mi się jakimś nieporozumieniem i domyślam się, że istnieje jakaś możliwość, aby to trochę "zautomatyzować".
I moje pytanie brzmi, czy ktoś wie jak to zrobić?
Avatar użytkownika
marekgajewski
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): środa, 10 marca 2010, 05:19
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Pro x64
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Opera

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez polymorphism » środa, 24 marca 2010, 10:56

Głupie zaczepki?! Jesteś w stanie napisać taką wiązankę:
Kod: Zaznacz cały
Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode("Settings")->ChildNodes->FindNode("JakiesUstawienie")->NodeValue; 

później jesteś w stanie wydedukować, że może jakiś warunek rozwiązałby problem:
Kod: Zaznacz cały
if (Form1->XMLDocument1->DocumentElement->ChildNodes (...) != NULL) 

dalej wyciągasz słuszny wniosek, że:
Musiałbym więc sprawdzać poprzedni, poprzedni i tak dłuugo, jeśli nastąpi taka potrzeba.

To co, chcesz mi powiedzieć, że nie jesteś wstanie napisać jakiejkolwiek funkcji? Funkcji, która chociaż pozwoliłaby zrozumieć o co Tobie dokładnie chodzi, bo to:
Czy ma ktoś pomysł, jak powinna wyglądać funkcja sprawdzająca istnienie wszystkich Node'ów

niewiele mówi. Co to znaczy wszystkich node'ów? Na podstawie czego mam je weryfikować? I nie pisz mi, że czepiam się szczegółów, bo te akurat są tutaj ważne.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez Cyfrowy Baron » środa, 24 marca 2010, 11:02

Jeśli ktoś dla zabawy otworzy plik XML i usunie powiedzmy <Settings> oraz </Settings>,


To nie powinno mieć miejsca, czyli użytkownik nie powinien ręcznie modyfikować ustawień plików programu. W takiej sytuacji program powinien zgłosić błąd, czyli wyświetlić informację, że pliki zostały ręcznie zmodyfikowane co wywołuje ogólny błąd programu, lub inny podobny komunikat. By jednak program mógł dalej działać prawidłowo, powinien on mieć funkcję, która naprawi błąd, lub przywróci plik do stanu domyślnego i niech to będzie nauczką dla użytkownika, który tak nieodpowiedzialnie obchodzi się z programem.



Lecz gdy wczytuję setki takich wartości, pisanie tylu funkcji warunkowych


Trochę tego nie rozumiem. Czy chodzi o to, że te wartości mogą być różne, czy są to jakieś wartości losowe, bliżej nieokreślone, czyli wymyślane przez użytkownika, czy jest to raczej lista stałych wartości? O jakie dokładnie wartości chodzi?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez marekgajewski » środa, 24 marca 2010, 11:10

Cyfrowy Baron napisał(a):Trochę tego nie rozumiem. Czy chodzi o to, że te wartości mogą być różne, czy są to jakieś wartości losowe, bliżej nieokreślone, czyli wymyślane przez użytkownika, czy jest to raczej lista stałych wartości? O jakie dokładnie wartości chodzi?


Wymyślane przez użytkownika.
Niestety mój program odbiega od reguły i bardziej zaawansowani użytkownicy będą mogli edytować pliki konfiguracyjne.

polymorphism napisał(a):Co to znaczy wszystkich node'ów? Na podstawie czego mam je weryfikować? I nie pisz mi, że czepiam się szczegółów, bo te akurat są tutaj ważne.


Chodzi o to, że muszę sprawdzić najpierw element główny, później ten znajdujący się w nim, np: <Settings>, następnie ten znajdujący się w <Settings>, np: <Language>, bo jeśli sprawdziłbym jedynie element <Language> a nie istniałby element, w którym się znajduje, lub miałby on inną nazwę, program wywaliłby błąd, a w moim przypadku chcę, aby poprawił użytkownika i go utworzył, prosząc o podanie wartości.
Avatar użytkownika
marekgajewski
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): środa, 10 marca 2010, 05:19
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Pro x64
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Opera

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez Cyfrowy Baron » środa, 24 marca 2010, 11:43

Chodzi o to, że muszę sprawdzić najpierw element główny, później ten znajdujący się w nim, np: <Settings>, następnie ten znajdujący się w <Settings>, np: <Language>...


Jeżeli element główny jak i element pośredni, czyli ten następujący po głównym są losowe, czyli wymyślane przez użytkownika, to by to sprawdzać w momencie tworzenia Nod'a przez użytkownika, musi być on dodawany do listy Nodów, jeżeli lista ma być wspólna dla wielu użytkowników to musi to być pojedyncza lista dla wszystkich, jak sądzę na serwerze.
Wymaga to utworzenia listy Nodów głównych i pośrednich, czyli można to zrealizować w pliku INI, użytkownik tworząc Noda głównego tworzy w pliku INI sekcję o takiej nazwie, a przypisując Nody pośrednie do głównego zapisuje je w tej sekcji. Plik może mieć taką postać:


[Settings]
1=Language
2=Opcja 1
3=Opcja 2
4=itd...



By sprawdzić Nody trzeba najpierw wczytać sekcje z pliku INI, a potem sprawdzić czy istnieją np:

Kod: Zaznacz cały

 TIniFile 
*Ini = new TIniFile("Plik.ini");
 TStringList *BaseNod = new TStringList;
 Ini->ReadSections( BaseNod );

 bool error = false;
 for(int i = 0; i < BaseNod->Count; i++)
 {
  if (Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode(BaseNod->Strings[i]) == NULL) error = true;
 }

 if(error)
 {
  ShowMessage("Błąd pliku! Dalsze przetwarzanie niemożłiwe");
  return;
 }
 


Jeżeli wystąpił błąd sekcji Nodów głównych to dalsze sprawdzanie nie ma sensu, więc nie trzeba już sprawdzać Nodów pośrednich. W przeciwnym razie postępujesz podobnie sprawdzając Nody pośrednie, czyli powyższy kod można przerobić tak:


Kod: Zaznacz cały


 
/* sprawdzanie Nodów głównych */
 TIniFile *Ini = new TIniFile("Plik.ini");
 TStringList *BaseNod = new TStringList;
 Ini->ReadSections( BaseNod );

 bool error = false
 for
(int i = 0; i < BaseNod->Count; i++)
 {
  if(Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode(BaseNod->Strings[i]) != NULL)
  {
    /* sprawdzanie Nodów pośrednich */ 
    TStringList 
*IndirectNod = new TStringList;
    Ini->ReadSection(BaseNod->Strings[i], IndirectNod);
     
    for
(int p = 0; p < IndirectNod->Count; p++)
    {
       String ChildNodName = Ini->ReadString(BaseNod->Strings[i], IndirectNod->Strings[p], "");
       if(ChildNodName.IsEmpty())
       {
         error = true;
         return;
       }
       if(Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode(BaseNod->Strings[i])->ChildNodes->FindNode(ChildNodName) == NULL)
       {
        error = true;
        return;
       } 
    
}

   delete  IndirectNod;
  }
  else
  
{
   error = true
   return
;
  } 
   if
(error) return;
 }
 
 delete BaseNod
;
 if(error)
 {
  ShowMessage("Błąd pliku! Dalsze przetwarzanie niemożliwe");
  return;
 }
 


To tak na szybkiego, nie sprawdzałem, może być błąd, poprawie jeżeli go znajdziesz i sam nie będziesz umiał.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez marekgajewski » środa, 24 marca 2010, 12:36

Cyfrowy Baron - wysłałem Ci PW w związku z tematem. Liczę że odpowiesz :)
Avatar użytkownika
marekgajewski
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): środa, 10 marca 2010, 05:19
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Pro x64
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Opera

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez Cyfrowy Baron » środa, 24 marca 2010, 12:53

To co napisałeś mi w PW. nie wnosi niczego nowego do tematu, gdyż przeznaczenie programu nie jest tutaj istotne.

Istota problemu opiera się na ty, że użytkownik ma możliwość tworzenia Nodów o dowolnej niezdefiniowanej nazwie, więc w sposób losowy. By przetwarzać dane program musi te dane skądś pobrać. Jeżeli pomysł z zapisywaniem Nodów do listy nie stanowi rozwiązania problemu, to nic innego nie przychodzi mi do głowy. Skąd program ma pobrać dane do sprawdzania? Skąd ma wiedzieć jakie Nody sprawdzić? Program nie sprawdzi tego o czym nic nie wie! Zastanów się chwilę na logiką tego programu.

Jedyne rozwiązanie jakie przychodzi mi do głowy to wykluczyć możliwość ręcznej edycji plików XML.
Inne rozwiązanie może opierać się na tym, że tylko Nody pośrednie, czyli w twoim przykładzie Nod Language są losowe, pozostałe są z góry ustalone, lub wybierane z jakiejś zdefiniowanej listy.

Nic więcej nie poradzę, gdyż to co proponujesz jest nielogiczne, opiera się na samych niewiadomych, więc równania nie da się rozwiązać.



Do celów o których mi napisałeś możesz równie dobrze posłużyć się plikami INI, zadanie będzie prostsze, a efekt identyczny.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Sprawdzanie czy wyszukiwany Node istnieje

Nowy postprzez marekgajewski » środa, 24 marca 2010, 13:15

OK, w każdym bądź razie dzięki za pomoc.
Wydaje mi się że wpadłem na rozwiązanie mojego problemu - sprawdzę go jak tylko wrócę z uczelni i jeśli będzie działać zamieszczę tutaj rozwiązanie.
Avatar użytkownika
marekgajewski
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): środa, 10 marca 2010, 05:19
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Pro x64
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Opera


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Biblioteki i komponenty

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 6 gości

cron