Autor Beitrag
sintec
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Do 02.08.07 10:16 
Hallo an alle,

Ich habe ein Tool geschrieben und möchte meine Konfigurationen als XML-Datei speichern.

dazu habe ich zwei Fragen:

1)
Die Konfigurationen werden erstmal in ein Record geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
type Daten = record
  jobname :String[255];
  trennzeichen :String[5];
  trennzeichenanz :Integer;
  newindexwrite :Boolean;
  namemaske :String[255];
  noziechen : Array[0..255of String[255];
  oldname :String[255];
  indexfelds : Array[0..255of String[255];
  extension :String[5];
  type suchenersetzen = record
    bezeichnung :String[50];
    suchen :String[20];
    ersetzen :String[20];
  end;
end;
var
  config :Daten;


jetzt soll alles in XML-Datei geschrieben werden, dazu habe ich für den Anfang folgende Procedure geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
Procedure saveconfig();
var XML: tXMLDocument;
    Node: IXMLNode;
begin
  XML := TXMLDocument.Create(MainWindow);
  try
    XMl.Active := true;
    Node := XML.AddChild('jobname');
    Node.NodeValue := config.jobname;

    Node := XML.AddChild('trennzeichen');
    Node.NodeValue := config.trennzeichen;

    Node := XML.AddChild('trennzeichenanz');
    Node.NodeValue := config.trennzeichenanz;

    Node := XML.AddChild('newindexwrite');
    Node.NodeValue := config.newindexwrite;
  finally
    XML.SaveToFile('jobs\' + config.jobname + '.xml');
    XML.free;
  end;
end;


Compilieren klappt soweit, aber wenn ich die Konfigurationen schreiben lassen will, bekomme ich einen Fehler:
ausblenden Quelltext
1:
Erste Gelegenheit für Exception bei $7C812A5B. Exception-Klasse EOleException mit Meldung 'In einem XML-Dokument ist nur ein Element höchster Ebene zugelassen'.					

in folgender Zeile:
ausblenden Delphi-Quelltext
1:
Node.NodeValue := config.trennzeichen;					

Die Meldung ist eigentlich klar, ich weiß nur nicht wie ich es anders machen kann.


2)
Wie kann man am besten so ein Record speichern lassen (wegen array und Record im Record)??

!!! Bin Anfänger was arbeiten mit XML angeht. !!!
noidic
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 851

Win 2000 Win XP Vista
D7 Ent, SharpDevelop 2.2
BeitragVerfasst: Do 02.08.07 11:14 
Du musst erstmal einen root-knoten anlegen, wo deine record-knoten unterknoten sind.

ausblenden Delphi-Quelltext
1:
2:
3:
XML.DocumentElement := XML.Addchild('root');
XML.DocumentElement.AddChild('jobname')
etc

_________________
Bravery calls my name in the sound of the wind in the night...
sintec Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Do 02.08.07 14:09 
soweit so gut, ich habe einiges hingekriegt, bekomme aber das array nicht in die XML

Kann mir bitte jemand helfen?
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Do 02.08.07 14:24 
Du erzeugst einfach ein Unterelement für jedes Array-Element:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
var
  elem : IXMLNode;
  i    : Integer;
begin
  ...

  node := XMLDocument.DocumentElement.AddChild('indexfields');
  for i := 0 to 255 do
  begin
    elem := node.AddChild('field');
    elem.NodeValue := config.indexfelds[i];
  end
  ...
end;


Stefan

_________________
Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
sintec Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Di 07.08.07 08:37 
So das Array unterzubringen habe ich auch geschafft.

Jetzt sieht die komplette XML-Datei so aus:
ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
- <config>
  <jobname>Fibu</jobname
  <trennzeichen>;</trennzeichen
  <trennzeichenanz>1</trennzeichenanz
  <newindexwrite>false</newindexwrite
  <namemaske>!(Feld1)</namemaske
  <extension>.TIF</extension
  <nozeichen>:;.;/;ü;</nozeichen
- <suchenersetzen>
  - <set>
      <bezeichnung>ue->ü</bezeichnung
      <suchen>ue</suchen
      <ersetzen>ü</ersetzen
    </set>
  - <set>
      <bezeichnung>.->_</bezeichnung
      <suchen>.</suchen
      <ersetzen>_</ersetzen
    </set>
  </suchenersetzen>
</config>


das Problem ist jetzt das auslesen von Array.
Habe es so Probiert bekomme aber immer ein Fehler:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
for I := 0 to XML.ChildNodes['config'].ChildNodes['suchenersetzen'].ChildNodes['set'].ChildNodes.Count - 1 do
    begin
      sr[i].bezeichnung := XML.ChildNodes['config'].ChildNodes['suchenersetzen'].ChildNodes['set'].ChildNodes[i].ChildNodes['bezeichnung'].NodeValue;
    end;


Wie funktioniert es genau?
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Di 07.08.07 08:53 
Du musst ja die einzelnen Unterknoten von suchenersetzen durchlaufen. Das würde ich so machen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
var
  suchenErsetzen : IXMLNode;
  setNode        : IXMLNode;
  i              : Integer;
begin
  suchenErsetzen := XML.DocumentElement.ChildNodes['suchenersetzen'];
  for i := 0 to suchenErsetzen.ChildNodes.Count - 1 do
  begin
    setNode := suchenErsetzen.ChildNodes[i];
    sr[i].bezeichnung := setNode.ChildValues['bezeichnung'];
    sr[i].suchen := setNode.ChildValues['suchen'];
    sr[i].ersetzen := setNode.ChildValues['ersetzen'];
  end;
end;


Stefan

_________________
Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
noidic
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 851

Win 2000 Win XP Vista
D7 Ent, SharpDevelop 2.2
BeitragVerfasst: Di 07.08.07 08:53 
Du iterierst eine Ebene zu tief. Versuchs mal so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
 TempNode := XML.DocumentElement.ChildNodes.Nodes['suchenersetzen'].ChildNodes.Nodes['set'];
 While Assigned(TempNode) do
 begin
   sr[i].bezeichnung := TempNode.ChildNodes.Nodes['bezeichnung'].NodeValue;  
   TempNode := TempNode.NextSibling;
 end;


Zur Sicherheit solltest du allerdings auf jeder Ebene prüfen, ob der Knoten da ist.

_________________
Bravery calls my name in the sound of the wind in the night...
sintec Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Di 07.08.07 09:58 
user profile iconStefan.Buchholtz hat folgendes geschrieben:
Du musst ja die einzelnen Unterknoten von suchenersetzen durchlaufen. Das würde ich so machen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
var
  suchenErsetzen : IXMLNode;
  setNode        : IXMLNode;
  i              : Integer;
begin
  suchenErsetzen := XML.DocumentElement.ChildNodes['suchenersetzen'];
  for i := 0 to suchenErsetzen.ChildNodes.Count - 1 do
  begin
    setNode := suchenErsetzen.ChildNodes[i];
    sr[i].bezeichnung := setNode.ChildValues['bezeichnung'];
    sr[i].suchen := setNode.ChildValues['suchen'];
    sr[i].ersetzen := setNode.ChildValues['ersetzen'];
  end;
end;


Stefan


Produziert ein Fehler in der Zeile:
ausblenden Delphi-Quelltext
1:
sr[i].bezeichnung := setNode.ChildValues['bezeichnung'];					


EDIT: Variante des Typs (Null) konnte nicht in Typ (String) konvertiert werden

und der:

user profile iconnoidic hat folgendes geschrieben:
Du iterierst eine Ebene zu tief. Versuchs mal so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
 TempNode := XML.DocumentElement.ChildNodes.Nodes['suchenersetzen'].ChildNodes.Nodes['set'];
 While Assigned(TempNode) do
 begin
   sr[i].bezeichnung := TempNode.ChildNodes.Nodes['bezeichnung'].NodeValue;  
   TempNode := TempNode.NextSibling;
 end;


Zur Sicherheit solltest du allerdings auf jeder Ebene prüfen, ob der Knoten da ist.


Produziert den Fehler in der:
ausblenden Delphi-Quelltext
1:
sr[i].bezeichnung := TempNode.ChildNodes.Nodes['bezeichnung'].NodeValue;					


ausblenden Quelltext
1:
Zugriffsverletzung bei Adresse 00404A30 in Modul [..].exe					


Zuletzt bearbeitet von sintec am Di 07.08.07 10:17, insgesamt 1-mal bearbeitet
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Di 07.08.07 10:13 
Meine Glaskugel ist grad in Reparatur, ich kann leider nicht sehen, welchen Fehler du kriegst. :wink:

Stefan

_________________
Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
sintec Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Di 07.08.07 10:40 
Bei beiden kommt der Fehler:
ausblenden Quelltext
1:
Zugriffsverletzung bei Adresse 00404A30 in Modul [..].exe					
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Di 07.08.07 10:49 
Ist sr ein dynamisches Array? Dann solltest du vorher die Länge festlegen:

ausblenden Delphi-Quelltext
1:
SetLength(sr, suchenErsetzen.ChildNodes.Count);					


Stefan

_________________
Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
sintec Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Di 07.08.07 11:13 
gg
stimmt

Danke für eure Hilfe.