Interfejs XML w Delphi - dynamiczne tworzenie dzieci

0

Witam,
Mam problem z dynamicznym tworzeniem dzieci w mojej bazie xml.

<?xml version="1.0" encoding="ISO 8859-2"?>
<dziennik>
	<uczniowie>
		<u1>
			<id></id>
			<imie></imie>
			<imie2></imie2>
			<nazwisko></nazwisko> 
			<nr_ewidencyjny></nr_ewidencyjny>
			<data_ur></data_ur>
			<miejsce_ur></miejsce_ur>
			<wojewodctwo></wojewodctwo>
			<pesel></pesel>
			<opiekun1></opiekun1> 
			<opiekun2></opiekun2>
			<kontakt1></kontakt1>
			<kontakt2></kontakt2>
			<zamieszkanie1></zamieszkanie1>
			<zamieszkanie2></zamieszkanie2>
			<plec></plec>
			<frekwencja>
				<m1_u></m1_u> <!--miesiąc 1, godz usprawiedliwione-->
				<m1_n></m1_n>
				<m1_s></m1_s>
				<m2_u></m2_u>
				<m2_n></m2_n>
				<m2_s></m2_s>
				<m3_u></m3_u>
				<m3_n></m3_n>
				<m3_s></m3_s>
				<m4_u></m4_u>
				<m4_n></m4_n>
				<m4_s></m4_s>
			        <m5_u></m5_u>
				<m5_n></m5_n>
				<m5_s></m5_s>
				<m6_u></m6_u>
				<m6_n></m6_n>
				<m6_s></m6_s>
				<m7_u></m7_u>
				<m7_n></m7_n>
				<m7_s></m7_s>
				<m8_u></m8_u>
				<m8_n></m8_n>
				<m8_s></m8_s>
				<m9_u></m9_u>
				<m9_n></m9_n>
				<m9_s></m9_s>
				<m10_u></m10_u>
				<m10_n></m10_n>
				<m10_s></m10_s>
			</frekwencja>
			
			<oceny>  <!-- string oceny np: 3,4,3,2,6-->
				<o1></o1> 
				<o2></o2>
				<o3></o3>
				<o4></o4>
				<o5></o5>
				<o6></o6>
				<o7></o7>
				<o8></o8>
				<o9></o9>
				<o10></o10>
				<o11></o11>
				<o12></o12>
				<o13></o13>
				<o14></o14>
				<o15></o15>
				<o16></o16>
				<o17></o17>
				<o18></o18>
				<o19></o19>
				<o20></o20>
			</oceny>
		</u1>
	</uczniowie>

	<przedmioty>
		<p1>
			<nazwa></nazwa>
			<nauczyciel></nauczyciel>
		</p1>
	</przedmioty>
	
	<kryteria_frek><!--ile godz do upomnienie/..-->
		<upom_wych></upom_wych> 
		<upom_wych2></upom_wych2>
		<nagan_wych></nagan_wych>
		<upom_dyra></upom_dyra>
		<nagan_dyra></nagan_dyra>
	</kryteria_frek>

</dziennik>

Wygenerowałem interfejs dla mojej pustej bazy i dzięki poradnikom i książce wiem jak
odczytać daną wartość :

 
var
edziennik : IXMLDziennikType;     // nasz ROOT
...
begin
...
XML.Active := True;
edziennik := Getdziennik(XML);
...
showmessage(edziennik.uczniowie.u1.id);

używamy funkcji GetNazwa(nazwa_parsera); do pobierania naszych elemętów... i set do zmiany
wartości.
Ale potrzebuję stworzyć np nowego ucznia i w tedy pasowało by mi
dodawać do xml np <u2>,<u3> itd... ale zarazem z wszystkimi polami/dziećmi które posiadają
w środku czyli <id>,<imie> itd... Czy da się to zrobić korzystając z interfejsu? Prosił bym o kawałek kodu bo przeszukałem google i książki ale nie ma info na ten temat :( , a jeśli się nie da
to będę musiał stworzyć puste znaczniki na konkretną liczbę osób ale chciał bym tego uniknąć :)
Z góry dziękuję,
Rafał

1
<?xml version="1.0" encoding="ISO 8859-2"?>
<dziennik>
    <uczniowie>
        <uczeń>
         .....
        </uczeń>

        <uczeń>
         .....
        </uczeń>

        <uczeń>
         .....
        </uczeń>
    </uczniowie>
 
    <przedmioty>
        <p1>
            <nazwa></nazwa>
            <nauczyciel></nauczyciel>
        </p1>
    </przedmioty>
 
    <kryteria_frek><!--ile godz do upomnienie/..-->
        <upom_wych></upom_wych> 
        <upom_wych2></upom_wych2>
        <nagan_wych></nagan_wych>
        <upom_dyra></upom_dyra>
        <nagan_dyra></nagan_dyra>
    </kryteria_frek>
 
</dziennik>

taka struktura XML będzie lepsza , w interfejsie będziesz miał dynamiczną tablicę uczniów, a w celu dodania kolejnego ucznia nie dopisujesz kolejnych węzłów u2,u2,u3 ... tylko ustawiasz odpowiednio wymiar tablicy

0

W sumie dobry pomysł.. tylko mam parę pytań których sam nie potrafię sobie wytłumaczyć:

Załóżmy że tworzę sobie obiekt a później używam metody Get....

var
edziennik : IXMLDziennikType;  
...
edziennik  := Getdziennik(XML);
...

czyli żeby wypisać imię ucznia 1 według struktury xml kolegi @grzegorz_so muszę (???) wywołać metodę Get... a później zapis:

 
dziennik.uczniowie.uczen[n].imie := '';// <-- mogę zastosować tablicę ?!?!

cały czas mam błędy przy kompilacji jak próbuję uzywać interfejsu do zapisu... Da się to zrobić?

1

Ja bym to tak zrobił:

var
    edziennik : IXMLDziennikType;     // nasz ROOT
    i:integer;
...
begin
...
    XML.Active := True;
    edziennik := Getdziennik(XML);
    edziennik.uczniowie.add;
    i:=edziennik.uczniowie.count-1;
    edziennik.uczniowie[i].imie:='Jasiu';
    ......
    ......

sprawdzone i działa .

w pierwszy poście wyraziłem się trochę nieprecyzyjnie , to nie tablica a lista uczniów

0

OK.. dzięki wielkie :D Wykminiłem że aby użyć interfejsu musimy wskazać XML Data Binding'owi baze z pełną strukturą , potem wywaliłem strukturę dotyczącą ucznia
i przedmiotu

<uczen>
            <id></id>
            <imie></imie>
            <imie2></imie2>
            <nazwisko></nazwisko> 
            <nr_ewidencyjny></nr_ewidencyjny>
            <data_ur></data_ur>
            <miejsce_ur></miejsce_ur>
            <wojewodctwo></wojewodctwo>
            <pesel></pesel>
            <opiekun1></opiekun1> 
            <opiekun2></opiekun2>
            <kontakt1></kontakt1>
            <kontakt2></kontakt2>
            <zamieszkanie1></zamieszkanie1>
            <zamieszkanie2></zamieszkanie2>
            <plec></plec>
            <frekwencja>
....
</uczen>

i dopiero teraz możemy używać

edziennik.Uczniowie.AddChild('uczen');
edziennik.Uczniowie.Uczen.AddChild('id');
...

nawet jeśli w pliku .xml jeszcze nie ma węzła uczen czy id bo go wywaliłem po wygenerowaniu żeby nie zawadzał...

Zostaje pytanie jak teraz odwołać się do konkretnego ucznia...

edziennik.Uczniowie.Uczen[1].imie:='jasi'; // - error

tak się nie da!!! :(

zamiana znacznika <code class="delphi"> na <code class="xml"> - furious programming

1

Po pierwsze nie wywalaj całej struktury węzła uczeń
Bez tej informacji XML Data Binding nie wie (bo i skąd) co to ma być np.

edziennik.Uczniowie.Uczen[1].imie

.
stąd próba przypisania

 edziennik.Uczniowie.Uczen[1].imie:='jasi'  

generuje error

edziennik.Uczniowie.AddChild('uczen')

tworzy nowy węzeł potomny 'uczeń' ale pewnie jest on pusty

edziennik.uczniowie.add 
 tworzy nowy węzeł potomny 'uczeń' wraz z całą wewnętrzną strukturą węzłów i błędu nie ma

Generalnie , plik XML użyty do tworzenia interfejsu powinien mieć maksymalnie kompletną strukturę, wtedy jest pewność że utworzony
na tym wzorze interfejs zagwarantuje dostęp do wszystkich węzłów.
A najlepiej jeśli masz tzw. plik 'shema'.
U Ciebie we wzorcu brakło struktury węzła <uczen>, stąd w interfejsie brakuje węzła <id> czy <imie>.

0

Oooo... Dziękuję Ci pięknie Grzegorzu!!!!
Rzeczywiście istneje metoda add ale tylko jeśli przy generowaniu było więcej niż jeden węzeł potomny :) a mi go brakowało.
Wszystko śmiga elegancko i patrząc na to wszystko to jest to najprostszy sposób na przechowywanie małej ilości danych.
Jeszcze raz dziękuję za pomoc i życzę Wesołych Świąt!!!!

0

A jak wygląda usuwanie całego węzła uczen[n]? Nie ma nigdzie metody delete dla węzła potomnego

<uczen>

Jest na to sposób? :)

0

OkOK :) już mam... wystarczy:

edziennik.Uczniowie.Delete(0);
XML.SaveToFile(XML.FileName);

:)

1 użytkowników online, w tym zalogowanych: 0, gości: 1