Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi OmniXML TOmniXMLReader / TOmniXMLWriter (https://www.delphipraxis.net/170278-omnixml-tomnixmlreader-tomnixmlwriter.html)

Adrenalin 9. Sep 2012 10:18

OmniXML TOmniXMLReader / TOmniXMLWriter
 
Morgen :)
Ich hab da noch einmal eine kleine Frage.
Ich hab da bei Stackoverflow mal gelesen gerade, dass man mit dem TOmniXMLReader / TOmniXMLWriter Anwendungsdaten in eine XML schreiben bzw lesen kann. Was ich schon mal Prima fand, weil man anscheinend sich um nichts kümmern muss OmniXML soll das wohl über ein TPersistent lösen was man zuvor anlegt und er schreibt / liest das ganze dann quasi in einem Rutsch.

Das hab ich gerade mal versucht. Allerdings war das nicht so ganz von Erfolg gegrönt.
Also das Problem tritt eigentlich nur an einer Stelle auf und zwar dann wenn ich die XML spaeter wieder lesen möchte...

Mein Problem scheint wohl zu sein das der Writer wohl die Daten schreibt (Es befindet sich ein Memo auf meinem Formular der Inhalt soll in die XML was auch gemacht wird allerdings sieht das ganze etwas seltsam aus:shock:

Ich bin da so vorgegangen Anhand des Beispiels hab ich ein Persistent angelegt was über 2 Stringlisten verfügt. Die eine Stringliste soll halt mit dem Text aus dem Memo gefüllt werden.

Ich hoffe mal ich hab das halbwegs Korrekt gemacht :oops:
Delphi-Quellcode:
type
  TTestType = (ttEins, ttZwei);

type
  TAppConf = class(TPersistent)
  private
    FFileName: string;
    FTestPropName: string;
    FTestPropType: TTemplateType;
    FMemoInhalt: TStringList;
  published
     constructor Create(const FileName: string); overload;
     destructor Destroy; override;
     procedure LoadConf(const Filename: string);
     procedure SaveConf(const Filename: string);
     property TestPropName: string read FTestPropName write FTestPropName;
     property TestType: TTestType read FTestType write FTestType;
     property MemoInhalt: TStringList read FMemoInhalt write FMemoInhalt;
     property Filename: string read FFilename write FFilename;
  end;
Gespeichert hab ich das ganze dann über:

Delphi-Quellcode:
  TOmniXMLWriter.SaveToFile(self, FFilename, pfNodes, ofIndent);

Und so geladen:
Delphi-Quellcode:
  TOmniXMLReader.LoadFromFile(self, FFilename);
Jetzt sieht der Inhalt meiner XML gespeichert so aus:
Code:
<data PropFormat="node">
  <TAppConf>
    <TestPropName>MoinMoin</TestPropName>
    <TestType>ttEins</TestType>
    <MemoInhalt Count="4">
      <l0>IchKommausDemMemo</l0>
      <l1>IchAuch</l1>
      <l2>IchSowieso/</l2>
      <l3>IchBinDerLetzte</l3>
    </MemoInhalt>
  </TAppConf>
</data>
Wenn ich das XML wieder einlesen möchte, geht das ganz gut bis zu dem Punkt wenn ich auf MemoInhalt zugreife und den Inhalt halt dem richtigen Memo auf der Form zuweisen will dann, knallts ($C0000 irgendwas)...:?

Jetzt war meine Überlegung das das Format da in dem XML in dem Knoten MemoInhalt nicht passt und somit nicht gelesen werden kann? Bzw. das OmniXMLPersistent Teil damit nichts anzufangen weiß.

Nur wie stell ich das jetzt an das ich nicht nur Knoten erstellen kann die einzeilig sind, da ich unter Umstaenden einen laengeren Text schreiben und lesen muss?

Hier mal der Link wo ich das gelesen hatte:
http://stackoverflow.com/questions/2...-xml-file?rq=1

Viele Grüsse

mirage228 9. Sep 2012 11:01

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Ist MemoInhalt vielleicht = nil?
Könnte sein, dass Du das Objekt manuell intialisieren musst...

stOrM 9. Sep 2012 11:11

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von mirage228 (Beitrag 1182163)
Ist MemoInhalt vielleicht = nil?
Könnte sein, dass Du das Objekt manuell intialisieren musst...

Wenn MemoInhalt nil ist kann dann MemoInhalt gespeichert werden in der XML?
Wobei ich seh ja nicht ob er die Sachen erstellt aber ich geh einfach mal davon aus :)

mirage228 9. Sep 2012 11:30

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von stOrM (Beitrag 1182166)
Wenn MemoInhalt nil ist kann dann MemoInhalt gespeichert werden in der XML?
Wobei ich seh ja nicht ob er die Sachen erstellt aber ich geh einfach mal davon aus :)

Delphi-Quellcode:
Objekt.MemoInhalt := Memo1.Lines as TStringList;
:P

Er hat ja nicht gesagt, ob das auslesen direkt danach erfolgt oder erst beim Programmstart, wo das Objekt dann ja vielleicht wirklich "nil" sein könnte...

Adrenalin 9. Sep 2012 11:35

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Hallo :)
Gut das ich da bin...

Nein ich erstelle Natürlich vorher das Objekt und greife Danach erst darauf zu, ich dachte das ergibt sich daraus das ich schrieb, das alle anderen Sachen ausgelesen werden können nur nicht wenn ich auf das Feld MemoInhalt zugreife... Deshalb bin ich davon ausgegangen das Omni mit von sich selbst gespeichertem Format nicht klar kommt.

Gruss

mirage228 9. Sep 2012 12:13

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Dann zeig mal bitte den Code, wie Du auf MemoInhalt genau zugreifst.

Konnte im OmniXML Code keinen Fehler erkennen, auch nicht im erzeugten XML...

Adrenalin 9. Sep 2012 20:04

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Conf ist Public

Speichern:

Delphi-Quellcode:
procedure TMainForm.Button4Click(Sender: TObject);
var ConfPath: String;
begin
  ConfPath := TPath.Combine(ExtractFilePath(Application.ExeName), 'data\');
  Conf := TAppConf.Create;
  Conf.MemoInhalt.Text := Memo1.Lines.Text;
  try
    Conf.SaveConfig(ConfPath + 'data.xml');
  finally
     Conf.Free;
  end;
end;
Laden:
Delphi-Quellcode:
var ConfPath: String;
begin
  ConfPath := TPath.Combine(ExtractFilePath(Application.ExeName), 'data\');
  Conf := TAppConf.Create();
  try
    Conf.LoadTemplate(ConfPath + 'data.xml');
    Memo1.Lines.Text := Conf.MemoInhalt.Text;
  finally
     Conf.Free;
  end;

mirage228 9. Sep 2012 20:18

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Also hier bei dem Code sehe ich kein Problem.

Ich muss nochmal nachfragen:
Führst Du wirklich selbst ein
Delphi-Quellcode:
MemoInhalt := TStringList.Create;
im constructor von TAppConfig durch? (Und dann ein .Free() im destructor...)

Du kannst auf alle anderen Properties ohne Initialisierung zugreifen, da es ja keine Klassen bzw. Objekte sind...
Der Reader erzeugt das TStringList-Objekt nicht von selbst, sondern lädt nur die Sachen aus dem XML in ein vorhandenes rein. Und der OmniReader prüft auch auf <> nil, bevor er das Objekt anfasst und die Sachen aus der XML reinlädt (daher auch keine Exception an der Stelle)...

Adrenalin 9. Sep 2012 20:19

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von mirage228 (Beitrag 1182223)
Also hier bei dem Code sehe ich kein Problem.

Ich muss nochmal nachfragen:
Führst Du wirklich selbst ein
Delphi-Quellcode:
MemoInhalt := TStringList.Create;
im constructor von TAppConfig durch? (Und dann ein .Free() im destructor...)

Du kannst auf alle anderen Properties ohne Initialisierung zugreifen, da es ja keine Klassen bzw. Objekte sind...
Der Reader erzeugt das TStringList-Objekt nicht von selbst, sondern lädt nur die Sachen aus dem XML in ein vorhandenes rein. Und der OmniReader prüft auch auf <> nil, bevor er das Objekt anfasst und die Sachen aus der XML reinlädt (daher auch keine Exception an der Stelle)...

Ja ich create die Stringlist im Constructor

mirage228 9. Sep 2012 20:29

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Und wenn Du mit Lines.Assign() arbeitest?

Delphi-Quellcode:
Memo1.Liens.Assign(Conf.MemoInhalt);

Adrenalin 9. Sep 2012 20:34

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von mirage228 (Beitrag 1182230)
Und wenn Du mit Lines.Assign() arbeitest?

Delphi-Quellcode:
Memo1.Liens.Assign(Conf.MemoInhalt);

Knallts ebenfalls schon probiert

Lemmy 9. Sep 2012 20:36

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Und hast du schon mal den Debugger angeworfen und geschaut, warum es denn knallt? Es kann nur knallen, wenn was nicht initialisiert ist, versuch rauszufinden was nicht existiert und schau dann warum es nicht existiert...

Adrenalin 9. Sep 2012 20:49

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von Lemmy (Beitrag 1182234)
Und hast du schon mal den Debugger angeworfen und geschaut, warum es denn knallt? Es kann nur knallen, wenn was nicht initialisiert ist, versuch rauszufinden was nicht existiert und schau dann warum es nicht existiert...

Ich hoffe ich habs richtig gemacht aber so wirklich schlau, werd ich daraus auch nicht weil initialisiert ist die Stringliste laut Debuggger weiss jetzt auch nicht mehr weiter:oops:

Lemmy 9. Sep 2012 20:55

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
mach mal vor das

Delphi-Quellcode:
Memo1.Lines.Text := Conf.MemoInhalt.Text;
das hier:

Delphi-Quellcode:
  ShowMessage(Memo1.Name);
  ShowMessage(Conf.ClassName);
  ShowMessage(Conf.Memoinhalt.ClassName);
wo kommt die Fehlermeldung?

Adrenalin 9. Sep 2012 21:05

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von Lemmy (Beitrag 1182245)
mach mal vor das

Delphi-Quellcode:
Memo1.Lines.Text := Conf.MemoInhalt.Text;
das hier:

Delphi-Quellcode:
  ShowMessage(Memo1.Name);
  ShowMessage(Conf.ClassName);
  ShowMessage(Conf.Memoinhalt.ClassName);
wo kommt die Fehlermeldung?

Ich glaub nun wirds ganz komisch weil es Knallt in der Zeile:

Delphi-Quellcode:
ShowMessage(Conf.Memoinhalt.ClassName);
Also doch wieder nicht Initialisiert bzw Nil?

Versteh ich nicht da:

Delphi-Quellcode:
published
  constructor Create(const FileName: string); overload;


constructor TAppConf.Create(const FileName: string);
begin
  inherited create;
  FMemoInhalt := TStringList.Create;
end;

destructor TAppConf.Destroy;
begin
  FreeAndNil(FMemoInhalt);
  inherited;
end;
Delphi-Quellcode:
  private
    FMemoInhalt: TStringList;

  published
     constructor Create(const FileName: string); overload;
     destructor Destroy; override;
     property MemoInhalt: TStringList read FMemoInhalt write FMemoInhalt;
Tha scheint zu stimmen, FMemoInhalt ist nil.

Lemmy 9. Sep 2012 21:13

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Hi,

Änder mal deine Klasse so ab:

Delphi-Quellcode:
type
  TAppConf = class(TPersistent)
  private
    FFileName: string;
    FTestPropName: string;
    FTestPropType: TTemplateType;
    FMemoInhalt: TStringList;
  public
     constructor Create(const FileName: string); overload;
     destructor Destroy; override;
     procedure LoadConf(const Filename: string);
     procedure SaveConf(const Filename: string);
     property MemoInhalt: TStringList read FMemoInhalt;
  published
     property TestPropName: string read FTestPropName write FTestPropName;
     property TestType: TTestType read FTestType write FTestType;
     property Filename: string read FFilename write FFilename;
     property MemoText: String read GetMemoText write SetMemoText;
  end;
und in GetMemoText udn SetMemoText gibts Du den Inhalt von FMemoInhalt zurück bzw. setzt diesen

Welche Delphiversion verwendest Du?

Grüße

Adrenalin 9. Sep 2012 21:19

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von Lemmy (Beitrag 1182251)
Hi,

Änder mal deine Klasse so ab:

Delphi-Quellcode:
type
  TAppConf = class(TPersistent)
  private
    FFileName: string;
    FTestPropName: string;
    FTestPropType: TTemplateType;
    FMemoInhalt: TStringList;
  public
     constructor Create(const FileName: string); overload;
     destructor Destroy; override;
     procedure LoadConf(const Filename: string);
     procedure SaveConf(const Filename: string);
     property MemoInhalt: TStringList read FMemoInhalt;
  published
     property TestPropName: string read FTestPropName write FTestPropName;
     property TestType: TTestType read FTestType write FTestType;
     property Filename: string read FFilename write FFilename;
     property MemoText: String read GetMemoText write SetMemoText;
  end;
und in GetMemoText udn SetMemoText gibts Du den Inhalt von FMemoInhalt zurück bzw. setzt diesen

Welche Delphiversion verwendest Du?

Grüße

Wie in beiden?

Lemmy 9. Sep 2012 21:29

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Delphi-Quellcode:
procedure SetMemoText(Value: String);
begin
  FMemoInhalt.Text := Value;
end;

function GetMemotext: String;
begin
  result := FMemoInhalt.Text;
end;
einmal lesen, einmal schreiben....

Adrenalin 9. Sep 2012 21:39

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von Lemmy (Beitrag 1182254)
Delphi-Quellcode:
procedure SetMemoText(Value: String);
begin
  FMemoInhalt.Text := Value;
end;

function GetMemotext: String;
begin
  result := FMemoInhalt.Text;
end;
einmal lesen, einmal schreiben....

:?Gleicher Fehler also nil

mirage228 9. Sep 2012 21:40

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Du rufst den falschen Konstruktor in Deinem Code auf.

Du erstellst das Objekt nur im constructor Create(String). In Deinem Code rufst Du aber Create() auf. Das lädt nur den Konstruktor der Parent-Klasse. Dort wird nix erstellt.

Änder Deinen Code ab, sodass auch im Create die StringList erzeugt wird, z.B. über eine Helfer-Methode. Alternativ kannst Du auch Deinen Konstruktur-Aufruf ändern. Dann läufts ;)

Adrenalin 9. Sep 2012 21:45

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von mirage228 (Beitrag 1182256)
Du rufst den falschen Konstruktor in Deinem Code auf.

Du erstellst das Objekt nur im constructor Create(String). In Deinem Code rufst Du aber Create() auf. Das lädt nur den Konstruktor der Parent-Klasse. Dort wird nix erstellt.

Änder Deinen Code ab, sodass auch im Create die StringList erzeugt wird, z.B. über eine Helfer-Methode. Alternativ kannst Du auch Deinen Konstruktur-Aufruf ändern. Dann läufts ;)

Wie meinst du Constructor aendern jetzt genau?
Filename raus und nur Create und Filename dann als Property?

Ok habs gesehen, du hast vollkommen Recht, mit Übergabe des Filenamens gehts.
Vielen Dank!

mirage228 9. Sep 2012 21:48

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von Adrenalin (Beitrag 1182257)
Zitat:

Zitat von mirage228 (Beitrag 1182256)
Du rufst den falschen Konstruktor in Deinem Code auf.

Du erstellst das Objekt nur im constructor Create(String). In Deinem Code rufst Du aber Create() auf. Das lädt nur den Konstruktor der Parent-Klasse. Dort wird nix erstellt.

Änder Deinen Code ab, sodass auch im Create die StringList erzeugt wird, z.B. über eine Helfer-Methode. Alternativ kannst Du auch Deinen Konstruktur-Aufruf ändern. Dann läufts ;)

Wie meinst du Constructor ndern jetzt genau?
Filename raus und nur Create und Filename dann als Property?

Beispielsweise. Das wäre die einfachste Lösung.
Oder Du machst zwei Konstruktoren explizit in der Klasse.
Der eine ruft dann nur den anderen Konstruktor auf (auch kein "inherited Create"!) und setzt die FileName-Property. Aber auch die Lösung über eine dritte Methode in der Klasse ist möglich, diese übernimmt dann die Erstellung der Objekte und wird von beiden Konstruktoren benutzt.

Adrenalin 9. Sep 2012 21:55

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
[QUOTE=mirage228;1182259]
Zitat:

Zitat von Adrenalin (Beitrag 1182257)

Beispielsweise. Das wäre die einfachste Lösung.
Oder Du machst zwei Konstruktoren explizit in der Klasse.
Der eine ruft dann nur den anderen Konstruktor auf (auch kein "inherited Create"!) und setzt die FileName-Property. Aber auch die Lösung über eine dritte Methode in der Klasse ist möglich, diese übernimmt dann die Erstellung der Objekte und wird von beiden Konstruktoren benutzt.

Ich könnte wenn ich das richtig verstehe soviele Constructoren bauen wie ich will, z.B. einmal mit Filename einmal ohne jedoch alle beinhalten dann im Create die Stringliste?

mirage228 9. Sep 2012 22:12

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Ja, also Hauptsache Du erzeugst die StringList irgendwie in jedem Deiner Konstruktoren. Wenn Du das TStringList.Create allerdings nur zentral an einer Stelle hast (bzw. generell solche Initialisierungs-Sachen) erhöht das die Wartbarkeit ungemein :)

Adrenalin 9. Sep 2012 22:15

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von mirage228 (Beitrag 1182264)
Ja, also Hauptsache Du erzeugst die StringList irgendwie in jedem Deiner Konstruktoren. Wenn Du das TStringList.Create allerdings nur zentral an einer Stelle hast (bzw. generell solche Initialisierungs-Sachen) erhöht das die Wartbarkeit ungemein :)

Verstehe danke nochmal für die Hilfe und Zusatzerklärungen.

mirage228 9. Sep 2012 22:17

AW: OmniXML TOmniXMLReader / TOmniXMLWriter
 
Zitat:

Zitat von Adrenalin (Beitrag 1182265)
Verstehe danke nochmal für die Hilfe und Zusatzerklärungen.

Gern :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:52 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz