AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Objekte in XML speichern

Ein Thema von EConvertError · begonnen am 19. Apr 2006 · letzter Beitrag vom 4. Mai 2006
Antwort Antwort
Seite 3 von 4     123 4      
EConvertError

Registriert seit: 29. Sep 2003
Ort: Österreich
230 Beiträge
 
#21

Re: Objekte in XML speichern

  Alt 28. Apr 2006, 18:39
Danke!

Zitat:
eine clevere Frage
Ich gebe zu, dass ich schon in der Dokumentation über IStream gelesen habe. Ich wusste nur noch nicht genau wo ich einen IStream herbekomme und wie ich diesen dem MXXMLWriter übergebe.

Ansonsten ist jetzt Alles klar, danke!

Bei Bedarf melde ich mich wieder, wenn das OK ist.

Vielen Dank,
Andreas

PS: Ich habe mich jetzt für SAX entschieden.
Andreas N.
  Mit Zitat antworten Zitat
EConvertError

Registriert seit: 29. Sep 2003
Ort: Österreich
230 Beiträge
 
#22

Re: Objekte in XML speichern

  Alt 29. Apr 2006, 14:08
Hallo noch einmal!

Ich habe noch eine Frage bzgl. Lesen mit SAX.

In der Demo gibt es ja die Funktion:
procedure TDemoClass.Deserialize(cnth: ISAXContentHandler); Ich habe mir einige Delphi-SAX Beispiele angesehen und da wurde immer das Interface ISAXContentHandler selbst implementiert. Mit den Funktionen des Interfaces wird man praktisch wie bei ganz normalen Delphi-Events informiert, was sich in der XML-Datei befindet.

Wäre es in diesem Fall nicht sinnvoller, wenn die Funktion einen ISAXXMLReader als Parameter nimmt und die zu deserialisierende Klasse ISAXContentHandler selbst implementiert?

Noch praktischer wäre es für mich, wenn man mit MSXML so etwas Ähnliches machen könnte wie mit dem XmlReader in .net:
Dort kann ich nämlich das Pull-Modell verwenden, sodass ich nicht auf Events reagieren muss, sondern ähnlich wie aus einem FileStream lesen kann:
Code:
while (MyXmlReader.Read())
{
  string mystring = MyXmlReader.ReadElementString();
}
Oder noch allgemeiner gefragt: Wie würdest du/würdet ihr das Herauslesen mit SAX organisieren?

Vielen Dank,
Andreas
Andreas N.
  Mit Zitat antworten Zitat
EConvertError

Registriert seit: 29. Sep 2003
Ort: Österreich
230 Beiträge
 
#23

Re: Objekte in XML speichern

  Alt 30. Apr 2006, 12:28
Hallo!

Ich habe jetzt etwas bzgl. Pull-Modell nachgeforscht und leider Hinweise gefunden, dass es so etwas in MSXML nicht gibt, sondern eben erst seit .net.

Jetzt frage ich mich natürlich, wie ich das Herauslesen mit SAX managen soll. Muss wirklich jede zu deserialisierende Klasse ISAXContentHandler implementieren?
Das würde aber auch ganz andere Probleme nach sich ziehen:
Denn mit der Rückkehr der Methode Deserialize() wäre noch nicht sichergestellt, dass ich mit dem Deserialisieren fertig bin (da ja über Callback-Methoden/Events gearbeitet) wird.

Wie würdet ihr/würdest du also das Herauslesen organisieren?

Vielen Dank,
Andreas
Andreas N.
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#24

Re: Objekte in XML speichern

  Alt 30. Apr 2006, 22:07
Hallo Andreas,

mit dem Hinweis auf das in MS SAX2 implementierte push model legst du den Finger in eine Wunde. In meiner Demo arbeite ich mit EINEM root object - nur so macht die gezeigte Methode Serialize() überhaupt Sinn. Die Signatur der Methode Deserialize() in meinem Beispiel ist übrigens durch Copy & Paste entstanden und sollte kein versteckter Hinweis auf eine Machbarkeit sein. Selbst wenn wir eine einzige Objekt-Verwaltungsinstanz als gegeben annehmen, würde ich angesichts der MS SAX2 Implementierung wohl eher auf zwei externe Funktionen setzen:

Delphi-Quellcode:
type
  TObjectManager = class; // to be coded

var
  root: TObjectManager;
  s: TStream;
  fn: TFileName;

begin
  fn := ChangeFileExt(ParamStr(0), '.xml');
  s := TFileStream.Create(fn, fmCreate or fmShareDenyWrite);
  root := TObjectManager.Create;
  // ... fill me up
  Serialize(root, s);
  root.Free;
  s.Free;
  s := TFileStream.Create(fn, fmOpenRead or fmShareDenyWrite);
  root := Deserialize(s);
  // ... dump root
  root.Free;
  s.Free;
end;
Gute Nacht

marabu
  Mit Zitat antworten Zitat
EConvertError

Registriert seit: 29. Sep 2003
Ort: Österreich
230 Beiträge
 
#25

Re: Objekte in XML speichern

  Alt 1. Mai 2006, 13:25
Danke für die Antwort!

Dann bin ich also genau richtig gelegen mit der Vermutung, dass es keinen SAX-Parser mit Pull-Modell gibt.

Ganz habe ich deinen Code noch nicht verstanden. Ist ObjectManager die zu serialisierende Klasse, die die Unterobjekte enthält?

Wie soll das Serialize() als externe Funktion funktionieren? Normalerweise weiß doch das Objekt am Besten, wie es gespeichert werden soll. Das Selbe frage ich mich was Deserialize() betrifft. Oder meinst du, dass ich mit published Elementen & Typinformationen arbeiten soll?

Könntest du mir da ein ganz kurzes Beispiel schreiben (nur kurz um den Grundgedanken etwas ausführlicher zu erkären; muss nicht funktionsfähig sein)?


Sonst fällt mir nur diese Möglichkeit ein, dass die zu deserialisierenden Klassen selbst die Interfaces implementieren (oder irgendwie anders mittels Events Daten erhalten) und dann über ein OnDeserialized-Event sagen, wenn sie fertig sind. Was meinst du?

Noch besser wäre es, wenn man irgendwie erreichen könnte, dass Deserialize() erst zurückkehrt, wenn alles fertig ist.

Vielen Dank,
Andreas

PS: Im ärgsten Notfall muss ich doch auf DOM zurückgreifen, was ich aber verhindern möchte.
Andreas N.
  Mit Zitat antworten Zitat
EConvertError

Registriert seit: 29. Sep 2003
Ort: Österreich
230 Beiträge
 
#26

Re: Objekte in XML speichern

  Alt 3. Mai 2006, 17:54
Hallo!

Ich habe mich weiterhin mit diesem Problem beschäftigt.
So wie ich das sehe, bekomme ich die Events von SAX an eine zentrale Stelle, weshalb sich die einzelnen Objekte nicht wirklich selbst deserialisieren können (wie sollen sich sonst untergeordnete Objekte die Daten holen können?).

D.h., dass ich die Objekte "von außen" (also erzeugen und dann die Eigenschaften von außen zuweisen) zusammenbauen muss. Das scheint mir reichlich "unelegant" und unsauber zu sein, wenn man bedenkt, dass ich einfach nur ein paar Objekte in XML speichern (und wieder von dort laden will).

Womöglich ist es klüger, wenn ich doch auf DOM setze.

Wobei sich hierbei die Frage stellt, ob es nicht besser wäre, die Properties direkt auf ein XML-Dokument zu mappen. Zumindest dort, wo es um primär um die Speicherung von Daten geht (z.B. Anwendungseinstellungen).

Was meinst du/meint ihr dazu?

Vielen Dank,
Andreas
Andreas N.
  Mit Zitat antworten Zitat
Benutzerbild von mschaefer
mschaefer

Registriert seit: 4. Feb 2003
Ort: Hannover
2.029 Beiträge
 
Delphi XE3 Enterprise
 
#27

Re: Objekte in XML speichern

  Alt 3. Mai 2006, 18:12
Moin zusammen,

Auch wenn wenn es nicht hart am aktuellen Problem liegt: Eigentlich geht es doch meist nicht darum alle Eigenschaften in XML zu giesen, sondern nur solche, die auch im Programm änderungen erfahren und damit Nutzereinstellungen speichern. Folglich müßte man an einem Object auch eine Namensliste mit den zu speichernden Properties haben. Jedenfalls scheint mir da noch ein Zwischenschritt sinnvoll.

Grüße // Martin
Martin Schaefer
  Mit Zitat antworten Zitat
EConvertError

Registriert seit: 29. Sep 2003
Ort: Österreich
230 Beiträge
 
#28

Re: Objekte in XML speichern

  Alt 3. Mai 2006, 18:25
Vielen Dank für diese Idee!

Das ist eine interessante Anregung, die ich mir gründlich durch den Kopf gehen lassen muss - auch wenn es nicht, wie du schon geschrieben hast, mein direktes Problem ist.
Allerdings möchte ich anmerken, dass ich nicht nur Anwendungsdaten speichern möchte, sondern auch alle möglichen anderen Objekte. Wenn ich diesbezüglich mehr Informationen geben soll, bitte nur Bescheid geben - meine Vorhaben sind nicht geheim.

Mein Problem ist sozusagen: Bei DOM werden die gesamten Daten nochmal in den Speicher geladen, wodurch sie dann dort doppelt vorhanden sind: 1) in dem Objekten selbst und 2) in dem DOM-Objekt.
Freilich wäre bei den allermeisten Objekten diese Ineffektivität verkraftbar, aber wenns besser geht...

Mit SAX habe ich das oben beschriebene Problem, dass das Herauslesen (Schreiben ginge ja bereits pefekt) sehr schwierig wird.

Wenn ich also bei DOM bleibe wäre es durchaus denkbar, dass ich die Daten gleich auf ein XML-Objekt mappe, da dann die Daten nur 1-mal vorhanden sind. Bei Objekten, bei denen es hauptsächlich um die Daten geht (deshalb habe ich die Anwendungsdaten angesprochen), wäre dies vielleicht eine Möglichkeit. Bei anderen, normalen Objekten, ist das wahrscheinlich wieder Ressourcenverschwendung.

*bereits vollkommen verzweifelt bin*

Hoffentlich könnt ihr mir helfen,
Andreas
Andreas N.
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#29

Re: Objekte in XML speichern

  Alt 3. Mai 2006, 21:17
Hallo Andreas,

ich habe noch ein wenig über deinem Problem meditiert und bin für mich zu dem Schluß gekommen, dass eigentlich alle wichtigen Aspekte in deinem thread schon einmal angesprochen worden sind.

Dass dir die Serialisierung via SAX gefällt kann ich nachvollziehen. Dass du die Deserialisierung gerne auf die gleiche Weise realisieren möchtest auch. Wenn du weiterhin mit SAX die Persistenz über Methoden der persistenten Klassen bzw. Objekte realisieren willst, dann wird die TDemoClass so oder ähnlich aussehen müssen:

Delphi-Quellcode:
type
  TDemoClass = class(TInterfacedObject, IDispatch, IVBSAXContentHandler)
  private
    // IVBSAXContentHandler
    procedure _Set_documentLocator(const Param1: IVBSAXLocator); safecall;
    procedure startDocument; safecall;
    procedure endDocument; safecall;
    procedure startPrefixMapping(var strPrefix: WideString; var strURI: WideString); safecall;
    procedure endPrefixMapping(var strPrefix: WideString); safecall;
    procedure startElement(var strNamespaceURI: WideString; var strLocalName: WideString;
                           var strQName: WideString; const oAttributes: IVBSAXAttributes); safecall;
    procedure endElement(var strNamespaceURI: WideString; var strLocalName: WideString;
                         var strQName: WideString); safecall;
    procedure characters(var strChars: WideString); safecall;
    procedure ignorableWhitespace(var strChars: WideString); safecall;
    procedure processingInstruction(var strTarget: WideString; var strData: WideString); safecall;
    procedure skippedEntity(var strName: WideString); safecall;
    // IDispatch
    function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
    function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
    function GetIDsOfNames(const IID: TGUID; Names: Pointer;
      NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
    function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
      Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
    // other
    // ...
  public
    SomeInteger: Integer;
    SomeString: String;
    DemoClass: TDemoClass;
    procedure Serialize(writer: IMXWriter);
    procedure Deserialize(reader: IVBSAXXMLReader);
    // class function Deserialize(reader: IVBSAXXMLReader): TDemoClass; //
    destructor Destroy; override;
    procedure Show; // for debugging purposes
  end;
Eventuell brauchst du dann noch eine ähnlich aufgebaute HelperClass um das Henne-Ei-Problem zu umgehen oder die Methode Deserialize() muss als class function implementiert werden. Außerdem wird ein Stack für die Umschaltung des ContentHandler in der Methode Deserialize() benötigt.

Ob eine Implementierung auf Basis von DOM insgesamt weniger Lines-Of-Code aufweist, dass kann ich im Augenblick noch garnicht erkennen. Implementieren würde ich beides. Hinterher weiß man mehr.

Gute Nacht

marabu
  Mit Zitat antworten Zitat
Benutzerbild von mschaefer
mschaefer

Registriert seit: 4. Feb 2003
Ort: Hannover
2.029 Beiträge
 
Delphi XE3 Enterprise
 
#30

Re: Objekte in XML speichern

  Alt 3. Mai 2006, 22:46
Very Spätmoin,

Bin immer wieder beeindruckt, was Marabu hier zu Tage zaubert. Mag aber trotzdem mal eine vielleicht etwas naive Frage stellen. Wieso geht für sowas nicht eine von den sagen wir noch schlanken kleinen XML-Komponenten. Kenne mich aktuell weder mit SAX noch DOM sonderlich gut aus, deshalb würde ich dies zunächst mal mit der TGmXML-Komponente angehen (was vielleicht auch viel zu trivial ist).

TgmXML bei Torry

Beispielanwendung


Tja was spricht dagegen?


// Viele Grüße in die Runde // Martin
Martin Schaefer
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:39 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz