Problem z wczytaniem XML

Problem z wczytaniem XML
djmentos
  • Rejestracja:prawie 18 lat
  • Ostatnio:ponad 2 lata
0

Witam

Mam plik XML:

Kopiuj
<?xml version="1.0" encoding="UTF-8"?>
<btio>
	<funkcja nazwa="cin" opis="Wczytanie danych do zmiennej">cin << %z;</funkcja>
	<funkcja nazwa="cout" opis="Wypisanie danych ze zmiennej">cout >> %z;</funkcja>
</btio>

i kod programu:

Kopiuj
NodeGowna:= XML.ChildNodes.FindNode('btio');
  if Assigned(NodeGowna) then
  begin
	XMLNode:= NodeGowna.ChildNodes.FindNode('funkcja');
	while XMLNode <> nil do
	begin
	  l:= ListView1.Items.Add;
	  l.Caption:= XMLNode.AttributeNodes['nazwa'].Text;
	  l.SubItems.Add(XMLNode.AttributeNodes['opis'].Text);
	  ShowMessage(XMLNode.NodeValue);
	  //l.SubItems.Add(XMLNode.NodeValue);
	  XMLNode:= XMLNode.NextSibling;
	end;
  end;

wysypuje się na ShowMessage()

Element does not contain a single text node

Chciałbym odczytać wartość gałęzi czyli "cin << %z;"

edytowany 1x, ostatnio: flowCRANE
olesio
  • Rejestracja:prawie 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

Odpiszę Tobie to samo co na innym forum:

Nie znam się dobrze na TXMLDocument. Ponieważ mam Delphi 7 - Personal i jak się da to w
swoim kodzie używam zewnętrznego parsera XML. A konkretnie modułu spkxmlparser jest do
pobrania z http://spook.freshsite.pl/files/download/spkxmlparser.zip ten kod poniżej działa ok:

Kopiuj
//...
uses
  spkxmlparser;

var
  XML : TSpkXMLParser;
  MainNode, XMLNode : TSpkXMLNode;

procedure TForm1.Button1Click(Sender: TObject);
var
  I : integer;
  ListItem : TListItem;
begin
  XML := TSpkXMLParser.Create;
  XML.LoadFromFile('test.xml');
  MainNode := XML.NodeByName['btio', False];
  if MainNode = nil then
  begin
    MessageBox(Application.Handle, PChar('Nieprawidłowy format pliku XML!'),
    PChar(Application.Title), MB_OK or MB_ICONERROR);
    XML.Free;
    Exit;
  end;
  ListView1.Items.Clear;
  for I := 0 to MainNode.Count - 1 do
  begin
    ListItem := ListView1.Items.Add;
    XmlNode := MainNode.NodeByIndex[I];
    Listitem.Caption := XMLNode.Parameters.ParamByName['nazwa', False].Value;
    ListItem.SubItems.Add(XMLNode.Parameters.ParamByName['opis', False].Value);
  end;
  XML.Free;
end;

Pozdrawiam.
TO
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 4 lata
0

Ja bym to napisał tak:

Kopiuj
var XML : TXMLDocument;
    NodeGowna : IXMLNode;
    XMLNode : IXMLNode;
begin
    try
        XML:=TXMLDocument.Create(Self);
        XML.FileName:=ExtractFilePath(ParamStr(0))+'plik.xml';
        XML.Active:=TRUE;
        NodeGowna:= XML.ChildNodes.FindNode('btio');
        if Assigned(NodeGowna) then begin
            XMLNode:= NodeGowna.ChildNodes.FindNode('funkcja');
            while XMLNode <> nil do begin
              //l:= ListView1.Items.Add;
              //l.Caption:= XMLNode.AttributeNodes['nazwa'].Text;
              //l.SubItems.Add(XMLNode.AttributeNodes['opis'].Text);
              ShowMessage(XMLNode.Text);
              //l.SubItems.Add(XMLNode.NodeValue);
              XMLNode:= XMLNode.NextSibling;
            end;
        end;
    finally
        XML.Free;
    end;
end;
GA
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 13 lat
0
<?xml version="1.0" encoding="UTF-8"?> <btio> <funkcja nazwa="cin" opis="Wczytanie danych do zmiennej">cin << %z;</funkcja> <funkcja nazwa="cout" opis="Wypisanie danych ze zmiennej">cout >> %z;</funkcja> </btio>

To nie zadziała bo nie ma prawa zadziałać.
Powyższy tekst nie jest prawidłowym XML-em. Tagi są źle zamknięte i wstąpił w wartości cudzysłów.
Nazwy sekcji również powinny być unikalne
Odsyłam do http://www.w3schools.com/xmL/xml_syntax.asp

<?xml version="1.0" encoding="UTF-8"?> <btio> <funkcja nazwa="cin" opis="Wczytanie danych do zmiennej&quot;">cin << %z;" /> <funkcja2 nazwa="cout" opis="Wypisanie danych ze zmiennej&quot;">cout >> %z;" /> </btio>
Ktos
Moderator
  • Rejestracja:prawie 23 lata
  • Ostatnio:około 2 godziny
0

@gamestone:
Ten XML akurat jest prawidłowy. Twój też, ale ma zupełnie inną strukturę.
Jest pewna różnica pomiędzy <element attr="value" /> a <element>value</element>. I obydwa z tych sposobów zapisu są poprawne, ale inne. Nikt nie broni tez ich mieszać, do przechowywania pewnych danych lepiej nadają się węzły tekstowe po prostu, a nie atrybuty.

Nazwy sekcji również powinny być unikalne

Aha. Czyli w takim XHTML to nie mogę użyć dwóch elementów pod rząd. A w całym dokumencie XHTML może być tylko jedno ? XML przewiduje tylko jeden element główny (tutaj: btio), ale potem może już być wiele elementów o takiej samej nazwie, z takimi samymi albo i różnymi parametrami.

Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:3 minuty
0

gamestone, przeczytaj ze zrozumieniem jeszcze raz dokumentację do której linka dajesz.
Bo wszystko co napisałeś jest bzdurą.

TO
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 4 lata
0

Gamestone przyjacielu sympatyczny, natenczas, tudzież, aczkolwiek, jakoby, bynajmniej. A czy ty w ogóle uruchomiłeś kod, który wkleiłem ?

Bo ja muszę ci się przyznać w sekrecie zapisałem sobie ten XML, który podał djmentos do pliku tekstowego z rozszerzeniem XML, a nastepnie w Button1Click wprowadziłem kod taki, jaki podałem w poprzednim poście.

I tutaj niespodzanka. Podejrzewam, że cię zaskoczę. Ale o dziwo działa i jeszcze jedna niespodzianka - pokazuje dokładnie to, czego djmentos się spodziewa ;)

D1
  • Rejestracja:ponad 16 lat
  • Ostatnio:ponad 6 lat
0

A jak rozwiązać problem użycia ww. odczytu pliku XML w sterowniku DLL w Trubo Delphi? Przy użyciu

Kopiuj
XML:=TXMLDocument.Create(self);

otrzymuję komunikat błędu:

Kopiuj
[Pascal Error] ... There is no overloaded version of 'Create' that can be called with these arguments

Bardzo proszę o pomoc.

edytowany 1x, ostatnio: flowCRANE
flowCRANE
Po co odświeżasz 8-letni wątek?!
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 7 godzin
0

Metoda Create z klasy TXMDocument ma inną, być może pustą, listę parametrów.
Poszukaj w dokumentacji co ma być parametrem metody.

edytowany 2x, ostatnio: grzegorz_so
D1
  • Rejestracja:ponad 16 lat
  • Ostatnio:ponad 6 lat
0

W dokumentacji metody Create znalazłem:

Kopiuj
constructor TXMLDocument.Create(AOwner: TComponent);
begin
  { Need to have this to make this constructor visible to C++ classes }
  inherited;
end;

ale i tak nie wiem jak rozwiązać ten problem...

edytowany 1x, ostatnio: flowCRANE
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 7 godzin
0

zrób tak:

Kopiuj
XML:=TXMLDocument.Create(nil);

tylko że wtedy obiekt nie będzie miał ownera i sam musisz zadbać o jego zwolnienie.

Z dokumentacji wynika że ownerem może być obiekt klasy TComponent. Ty użyłeś self, nie wiadomo jaka klasa kryje się pod self

edytowany 1x, ostatnio: grzegorz_so
D1
  • Rejestracja:ponad 16 lat
  • Ostatnio:ponad 6 lat
0

Próbowałem już tego i aplikacja się zawiesza, przez co muszę ją zamykać w *Procesach *systemowych ;/ a jak mogę później go zwolnić gdy nie ma ownera?

GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 7 godzin
0

Wwklej kod całej metody albo i klasy, wtedy będzie łatwiej pomóc.
Sprawdź czy w Turbo Delphi istnieje interfejs IXMLDocument

edytowany 1x, ostatnio: grzegorz_so
D1
  • Rejestracja:ponad 16 lat
  • Ostatnio:ponad 6 lat
0
Kopiuj
var
  XML : TXMLDocument;
  NodeMain : IXMLNode;
  XMLNode : IXMLNode;
begin
    try
        XML:=TXMLDocument.Create(self);
        XML.FileName:='C:\prod.xml';
        XML.Active:=TRUE;
        NodeMain:= XML.ChildNodes.FindNode('product');
        if Assigned(NodeMain) then begin
            XMLNode:= NodeMain.ChildNodes.FindNode('id');
            while XMLNode <> nil do begin

              ShowMessage(XMLNode.Text);

              XMLNode:= XMLNode.NextSibling;
            end;
        end;
    finally
        FreeAndNil(XML);
        XML.Free;
    end;
end ;

Ten kod jest wcześniej podany i lekko przeze mnie przerobiony. Metoda jest wywoływana i dziedziczona po interfejsie, ale on nic tak naprawdę nie wnosi. Kod działa w aplikacji okienkowej (desktopowej), a w konsoli już nie. Więc czy to robimy w konsoli czy w sterowniku DLL to dzieje się to samo. Kodu interfejsu i jego method nie mogę tutaj wkleić, gdyż zajmuje za dużo miejsca.

edytowany 3x, ostatnio: diron16
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 7 godzin
2

spróbuj tak, intefrejsów nie musisz zwalniać

Kopiuj
var
  XML: IXMLDocument; //  <<< tutaj zmiana !!!!
  NodeMain: IXMLNode;
  XMLNode: IXMLNode;
begin
  XML := TXMLDocument.Create(nil);
  XML.FileName := 'C:\prod.xml';
  XML.Active := TRUE;
  NodeMain := XML.ChildNodes.FindNode('tft');
  if Assigned(NodeMain) then
  begin
    XMLNode := NodeMain.ChildNodes.FindNode('id');
    while XMLNode <> nil do
    begin
      ShowMessage(XMLNode.Text);
      XMLNode := XMLNode.NextSibling;
    end;
  end;
end;
edytowany 1x, ostatnio: grzegorz_so
D1
  • Rejestracja:ponad 16 lat
  • Ostatnio:ponad 6 lat
0

Jak ja Ci kurka dziękuję!!!! <browar> <browar> :D

Działa ;P Co było powodem błędu? Widzę, że zmieniłeś TXMLDocument na IXMLDocument. No tak... ;P Z literką te mamy obiekty okna, a tutaj deklarujemy element interfejsu :)
Jeszcze raz 1000-krotne dziękuję ;)

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:3 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
0
diron16 napisał(a):

Z literką te mamy obiekty okna, a tutaj deklarujemy element interfejsu :)

No nie za bardzo… Prefiks T informuje, że to zwykły typ danych (w tym przypadku klasa), a I że interfejs – nie ma mowy o żadnych elementach, a tym bardziej „obiektach okna”. Równie dobrze może być na odwrót:

Kopiuj
type
  TXMLDocument = interface
    {..}
  end;

type
  IXMLDocument = class
    {..}
  end;

bo prefiksy są umowne, opcjonalne. Ale w tym przypadku akurat są one poprawne.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 5x, ostatnio: flowCRANE
MY
  • Rejestracja:ponad 9 lat
  • Ostatnio:10 dni
  • Postów:1082
0
grzegorz_so napisał(a):

zrób tak:

Kopiuj
XML:=TXMLDocument.Create(nil);

tylko że wtedy obiekt nie będzie miał ownera i sam musisz zadbać o jego zwolnienie.

Z dokumentacji wynika że ownerem może być obiekt klasy TComponent. Ty użyłeś self, nie wiadomo jaka klasa kryje się pod self

Tylko, że wtedy można się baaaaardzo nadziać na dziwne błędy. Sam popełniłem coś takiego na produkcji i miałem AV i inne błędy w różnych miejscach. Czasem już nawet podczas wczytywania pliku. Tu jest porada co wtedy zrobić http://edn.embarcadero.com/article/29241 Jak jeszcze nie trafiłem na tego arta jako ownera przekazałem... obiekt Application i zaczęło działać.

MY
ups nie zauważyłem następnej strony wątku ;)
GS
też to przerabiałem, rozwiązanie z interfejesm jest najlepsze :)
MY
@grzegorz_so dokładnie. Tylko ile mi włosów posiwiało na głowie nie mam pojęcia. Kod w DataModule z położonym komponentem działa. Jako klasa bez DataModule sypie błędami...
GS
sypie błędami jeżeli owner jest nilem
MY
@grzegorz_so i tu było moje zdziwienie. Być może nie doczytałem czegoś w dokumentacji. Ale takie zachowanie jest mocno nieintuicyjne.
GS
@mr.Yahooo w podlinkowanym przez Ciebie artykule tez nie ma wyjaśniania dlaczego tak się dzieje, trochę to dziwne, ale widać tak jest
MY
@grzegorz_so a to nie jest wyjaśnieniem? it acts as a reference counted object that automatically frees itself when those references reach zero. This means that the next time you do something to Doc that causes a decrease in the reference count, you run the risk of destroying the object and invalidating your reference. Tylko nie wiem dlaczego tylko XMLDocumnent przy braku ownera zlicza referencje do obiektu i potrafi sam się zniszczyć.
GS
i do tego The problem is that so much happens to TXMLDocument behind the scenes, inside of the VCL, :)
MY
@grzegorz_so i mamy mieszankę wybuchową :D
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)