Toon posts:

[Delphi] XMLDocument geeft problemen

Pagina: 1
Acties:

Verwijderd

Topicstarter
We zijn bezig met een project voor school waarin we gebruik maken van XML. De bedoeling is dat we 2 applicaties maken die informatie uitwisselen met elkaar over sockets en waarbij gebruik wordt gemaakt van XML.

Nu heb ik een server draaien die tijdens het hele programma luistert of er wat binnenkomt op de TCPServer.

Dat werkt gewoon goed. Ik krijg ook een string waarin een XML document staat.

Alleen vervolgens wil ik die string parsen in een XMLDocument. Maar zodra ik de active property van het XMLDocument op True zet krijg ik een error (CoInitialize).

Ik kom er echt niet uit. Kan iemand mij hier mee helpen.

Dit is de code:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
uses
  Windows, Messages, SysUtils, Variants, Classes, Controls, Forms,
  Sockets, ScktComp, XMLDoc, XMLDom, MSXMLDom, XMLIntf;

type
  TClientDataThread = class(TThread)
  public
    ListBuffer: TStringList;
    constructor Create(CreateSuspended: Boolean);
    procedure Terminate;
  end;

  TXMLServer = class
  private
    TCPServer: TTcpServer;
    procedure TCPServerAccept(Sender: TObject; ClientSocket: TCustomIpClient);
  public
    constructor Create(Port: String);
    destructor Destroy; override;
  end;

{ TClientDataThread }

constructor TClientDataThread.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := True;
  ListBuffer := TStringList.Create;
end;

procedure TClientDataThread.Terminate;
begin
  ListBuffer.Free;
  inherited;
end;


{ TXMLServer }

constructor TXMLServer.Create(Port: String);
begin
  TCPServer := TTcpServer.Create(nil);
  TCPServer.OnAccept := TCPServerAccept;

  TCPServer.LocalPort := '999';
  TCPServer.Active := True;
end;

destructor TXMLServer.Destroy;
begin
  TCPServer.Free;
  inherited Destroy;
end;

procedure TXMLServer.TCPServerAccept(Sender: TObject; ClientSocket: TCustomIpClient);
var ReceivedText: String;
    DataThread: TClientDataThread;
    RootNode: String;
    XMLHandling: TXMLHandling;
    XMLDocument: TXMLDocument;
begin
  // Create Thread
  DataThread := TClientDataThread.Create(True);

  ReceivedText := ClientSocket.Receiveln;
  while ReceivedText <> '' do
  begin
    // Er is data ontvangen
    // Verwerk de string die ontvangen is naar een XML Document
    XMLDocument := TXMLDocument.Create(nil);
    try
      with XMLDocument do
      begin
       XML. Add(ReceivedText);
        Active := True;

        // Bepaal RootNode
        RootNode := DocumentElement.LocalName;
      end;

      XMLHandling := TXMLHandling.Create(ClientSocket.RemoteHost, '999');
      try
        if RootNode = 'RequestVluchtInfo' then
        begin
          XMLHandling.SendReplyVluchtInfo(XMLDocument);
          //SetRequestVluchtInfoReceived(True);
        end;
      finally
        XMLHandling.Free;
      end;

    finally
      XMLDocument.Free;
    end;

    DataThread.ListBuffer.Add(ReceivedText);
    ReceivedText := ClientSocket.Receiveln;
  end;

  // Call Resume which will execute and synch the ListBuffer with the TargetList
  DataThread.Resume;
end;

  • whoami
  • Registratie: December 2000
  • Laatst online: 19:34
't Zou handig zijn mocht je enkel de relevante code posten, en aangeven op welke regel je die error krijgt.
Misschien kun je ook het programma eens debuggen.

De fout ligt misschien ook wel bij het XML document. Misschien is er daar iets dat er niet goed uitziet. Misschien kun je daar ook eens een extract van posten.

https://fgheysels.github.io/


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 30-08 09:55

Creepy

Tactical Espionage Splatterer

Welke error krijg je precies? CoInitialize is namelijk een functie om wat ActiveX dingen te initialiseren (om COM zooi.. in elk geval om iets te initialiseren.

Kan het niet zo zijn dat een TXMLDOcument een filename property ingevuld moet hebben?

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
Fout ontstaat op regel 75 (Active := True)

CoInitialize is niet aangeroepen

Maar er valt niks terug te vinden in de help over CoInitialize.


De string die ik ontvang is:

<RequestVluchtInfo><Datum1>31-10-2002</Datum1><Datum2></Datum2><LandVertrek>1</LandVertrek><LandAankomst>6</LandAankomst></RequestVluchtInfo>


Dit is gewoon een goed XML Document.

Verwijderd

Topicstarter
Creepy schreef op 22 oktober 2002 @ 13:50:
Welke error krijg je precies? CoInitialize is namelijk een functie om wat ActiveX dingen te initialiseren (om COM zooi.. in elk geval om iets te initialiseren.
Ik gebruik geen ActiveX dingen
Kan het niet zo zijn dat een TXMLDOcument een filename property ingevuld moet hebben?
Nee maakt niks uit.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Bug1:
code:
1
2
3
4
5
6
7
procedure Terminate;
...
procedure TClientDataThread.Terminate;
begin
  ListBuffer.Free;
  inherited;
end;

Waarom roep je inherited aan? Je override niets. Je kan Terminatie ook helemaal niet overrideen want die is niet eens virtual. Gebruik hiervoor de destructor.

Bug2:
code:
1
2
3
4
5
6
7
8
9
10
{ TXMLServer }

constructor TXMLServer.Create(Port: String);
begin
  TCPServer := TTcpServer.Create(nil);
  TCPServer.OnAccept := TCPServerAccept;

  TCPServer.LocalPort := '999';
  TCPServer.Active := True;
end;

Waar roep je die default constructor aan hier?

Memory leak:
code:
1
2
3
4
5
6
7
8
9
10
11
12
constructor TClientDataThread.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := True;
  ListBuffer := TStringList.Create;
end;
...
procedure TClientDataThread.Terminate;
begin
  ListBuffer.Free;
  inherited;
end;

Terminate hoeft niet altijd aangeroepen te worden en dus zou de buffer nooit gefreed worden. Het kan zelfs voorkomen dat Terminate 2x aangeroepen wordt waarna je ListBuffer dus dubbel freeed. Gebruik de desctructor daarvoor.

Jij gebruik misschien niet direct ActiveX, maar het XML DOM ding is een ActiveX object. MS XML namelijk. Is die wel geinstalleerd?

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
LordLarry schreef op 22 oktober 2002 @ 16:08:
Bug1:
Waarom roep je inherited aan? Je override niets. Je kan Terminatie ook helemaal niet overrideen want die is niet eens virtual. Gebruik hiervoor de destructor.
Ik heb naar het vb NetChat bij de demos van Delphi 7 gekeken. Daar gebruiken ze inherited in de Thread.Terminate procedure.
Bug2:
Waar roep je die default constructor aan hier?
Er wordt in mijn Mainform een instantie gemaakt van TXMLServer('999');
Memory leak:
Terminate hoeft niet altijd aangeroepen te worden en dus zou de buffer nooit gefreed worden. Het kan zelfs voorkomen dat Terminate 2x aangeroepen wordt waarna je ListBuffer dus dubbel freeed. Gebruik de desctructor daarvoor.
Dit komt ook weer uit die demo.
Jij gebruik misschien niet direct ActiveX, maar het XML DOM ding is een ActiveX object. MS XML namelijk. Is die wel geinstalleerd?
Als ik ergens anders een XMLDocument aanmaakt gaat het wel goed.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 30-08 09:55

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 22 oktober 2002 @ 14:24:
[...]
Ik gebruik geen ActiveX dingen


[...]
Nee maakt niks uit.
Pssstt.. je XML Document komt van een COM Interface af ;)
Roep die CoInitialize eens aan, en kijk eens voor de gein of het dan wel werkt. CoInitialize zit in windows (uses windows)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Verwijderd schreef op 22 oktober 2002 @ 16:31:
[...]
Ik heb naar het vb NetChat bij de demos van Delphi 7 gekeken. Daar gebruiken ze inherited in de Thread.Terminate procedure.
[...]
Er wordt in mijn Mainform een instantie gemaakt van TXMLServer('999');
[...]
Dit komt ook weer uit die demo.
[...]
Dan staat het daar allemaal fout. En dat zijn geen grapjes.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
Creepy schreef op 22 oktober 2002 @ 16:38:Pssstt.. je XML Document komt van een COM Interface af ;)
Roep die CoInitialize eens aan, en kijk eens voor de gein of het dan wel werkt. CoInitialize zit in windows (uses windows)
Die functie heb ik niet. Ik gebruik Delphi 7 Enterprise.

[ edit ]
Oh ik heb hem toch ;) Hij staat in ActiveX
[ /edit ]

Verwijderd

Topicstarter
Met de functie CoInitialize werkt het.

Bedankt allemaal.
Pagina: 1