TBufDataset und xml [gelöst]

Rund um die LCL und andere Komponenten
Antworten
Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

TBufDataset und xml [gelöst]

Beitrag von Geronimo »

Moin zusammen,
ich möchte eine lokale DB im xml-Format mit TBufDataset realisieren.
Elementar ist dabei:
- Daten aus xml-Datei lesen
- Daten in xml-Datei speichern

Nach langem Experimentieren folgender Code, der zumindest bei mir funktioniert.

Einlesen:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
begin
  DBPfad := 'c:\lazarus-projekte\DB-Test\Stahlsorten.xml';

  //TBufDataset
  if FileExists(DBPfad) then
    cdStahlsorten.LoadFromFile(DBPfad,dfXML)
  else
    cdStahlsorten.CreateDataset;
end; 
und das Speichern:

Code: Alles auswählen

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
var
  AStream: TFileStream;
  DPReader: TXMLDatapacketReader;

begin
  try
    AStream := TFileStream.Create(DBPfad,fmCreate);
    DPReader := TXMLDatapacketReader.Create(cdStahlsorten,AStream);
    cdStahlsorten.SetDatasetPacket(DPReader);
    cdStahlsorten.SaveToStream(AStream,dfXML);
  finally
    AStream.Free;
    cdStahlsorten.Close;
  end;
end;   
Weiter habe ich gelernt:
- Weise TBufDataset.FileName nichts zu, schon gar nicht zur Design-Zeit.

Fragen an die Experten:
  • Warum muss ich beim Speichern diesen "Umweg" gehen, wo doch TBufDataset auch eine Methode SaveToFile hat, wo man
    das DataPacketFormat als Parameter übergeben kann? SaveToFile funktioniert bei mir mit dfXML nicht. Oder mache ich was falsch?
  • Was macht das TBufDataset, wenn man FileName zuweist?
Grüße aus Hamburg
Geronimo
Zuletzt geändert von Geronimo am So 23. Feb 2025, 21:19, insgesamt 1-mal geändert.

wp_xyz
Beiträge: 5188
Registriert: Fr 8. Apr 2011, 09:01

Re: TBufDataset und xml

Beitrag von wp_xyz »

FileName ist die Datei, unter der die Records gespeichert sind. Man lässt das leer, wenn man den Dataset für eine temporäre Tabelle nur im Speicher braucht. Aber man kann natürlich sehr wohl hier einen Dateinamen eintragen. Dann wird die Datei beim Öffnen des Dataset automatisch gelesen und bei Schließen automatisch geschrieben. Im Anhang findest du ein Beispiel.

Warum deine (ungenannte) Quelle gesagt hat, man solle Filename leer lassen, ist mir unklar. Möglicherweise ist es aber auch ein Missverständnis, denn wenn du Filename als relativen Pfad einträgst, dann bezieht dieser sich während der Designzeit auf das Lazarus-Verzeichnis, aber zur Laufzeit auf das Verzeichnis der Anwendung (in der Regel) - das heißt, die Datendatei wird evtl. nicht gefunden, wenn du den Dataset schon zur Designzeit angelegt hast! Und wenn du einen absoluten Pfad einträgst, hast du das Problem, dass dein Programm eine fest vorgegebene Verzeichnisstruktur voraussetzt - du kannst die Daten z.B. nicht auf ein anderes Verzeichnis verschieben ohne das Programm neu zu kompilieren.
Dateianhänge
bufdataset_beispiel.zip
(2.28 KiB) 53-mal heruntergeladen

Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

Re: TBufDataset und xml

Beitrag von Geronimo »

Hallo wp_xyz,

vielen Dank für die Antwort.
Dann wird die Datei beim Öffnen des Dataset automatisch gelesen und bei Schließen automatisch geschrieben.
Ja, genau das ist der Punkt! Das automatische Schreiben und Lesen passiert eben immer binär, what ever it takes!

Meine Aussage, man solle Filename leer lassen, sollte nicht als generelle Aussage verstanden werden, sondern
bezog sich lediglich auf mein Vorgaben, die Daten grundsätzlich in xml zu speichern.
Eine doppelte Buchhaltung (binär + xml) brauche ich an der Stelle nicht.

Wenn man das TBufDataset dazu bringen könnte, auch das automatische Schreiben und Lesen mit xml zu machen,
wäre alles bestens!

Gruß
Geronimo
Die Welt ist linear, rechteckig und gaussverteilt.

wp_xyz
Beiträge: 5188
Registriert: Fr 8. Apr 2011, 09:01

Re: TBufDataset und xml

Beitrag von wp_xyz »

Sorry, da habe ich mal wohl wieder nicht aufmerksam genug gelesen - da hattest ja alles richtig beschreiben.

Im Prinzip hast du recht: FileName ist für das standardmäßige binäre Format, und man braucht den xml-Packetreader. Die Verwendung ist aber doch etwas einfacher: Statt Bufdataset.Open einfach BufDataset.LoadfromFile(dateiname, dfXML) aufrufen. Und zum Schließen vor BufDataset.Close Bufdataset.SaveToFile(dateiname, dfXML). (der Reader wird automatisch erzeugt, wenn die Reader-Unit in der Uses-Zeile genannt ist, dein Code mit dem Stream wird nicht benötigt).

Dennoch hinterlässt das Ganze ein "schales" Gefühl: Warum kann man die BufDataset nicht so umkonfigurieren, dass ein BufDataset.Open und .Close den gewünschten Reader verwendet? Warum wird im Aufzählungstyp TDataPacketFormat ein dfXMLUTF8 erwähnt, ohne dass ein geeigneter Reader zur Verfügung gestellt wurde (denn bei Verwendung bekommt man die Fehlermeldung, dass das Format nicht erkannt wird).

Trotzdem hier im Anhang die xml-Variante des früher geposteten Demo-Programms
Dateianhänge
bufdataset_xml.zip
(2.38 KiB) 38-mal heruntergeladen

Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

Re: TBufDataset und xml [gelöst]

Beitrag von Geronimo »

Moin wp_xyz,
hurra, das Bufdataset.SaveToFile(dateiname, dfXML) funktioniert jetzt auch bei mir und produziert xml! :)
Vielen Dank für das Beispiel.
Das hatte mich gerade gewundert, warum das Bufdataset.SaveToFile(dateiname, dfXML) nicht funktionieren solle,
wenn das BufDataset.LoadfromFile(dateiname, dfXML) funktioniert.
Obwohl ich eigentlich alles so gemacht habe, wie in deinem Beispiel. Aber "eigentlich" ist kein Hauptwort.
Wahrscheinlich habe ich das Objekt zur Entwurfszeit mit meinen Experimenten komplett kaputt gemacht.
(Habe in der Tat das Dataset gelöscht und neu eingefügt.)

Zum Thema UTF8:
Da müsste man mal den xmlDataPacketReader klonen und UTF8 ready machen und entsprechend registrieren. Aber ob der Rest
dann auch UTF8 ready ist, I don't know.

Gruß
Geronimo
Die Welt ist linear, rechteckig und gaussverteilt.

Antworten