![]() |
Re: XML-Struktur in Objekte verwalten
Guck doch mal in Richtung "Objects", wie beim Stringgrid. Zumindest der VST kann das auch. Verstehe zwar jetzt das konkrete Problem nicht, aber unterbringen kann man da alles.
|
Re: XML-Struktur in Objekte verwalten
Hallo Christian,
ich frage nochmal nach, was genau der Zweck dieses objektorientierten Aufbaus ist. Nehmen wir an, diese Infos soll Dein Objekt halten:
Delphi-Quellcode:
In dem Fall würden ja alleine die Infos im gefüllten TreeView
type
TOrdner = class(TObject) Ordnername : String; Expanded: Boolean; end; aussreichen, d.h. du bräuchtest eigentlich nicht noch Objekte anlegen, sondern könntest bei Bedarf direkt auf den Node des TreeViews zugreifen. Falls das Objekt größer werden soll, hier noch mal eine genauere Beschreibung meiner Umsetzung: Dem TreeView kannst du anstatt nur einer Beschreibung auch eine Beschreibung mit einem Pointer mit auf den Weg geben, also so:
Delphi-Quellcode:
Du könntest also beim Füllen des TreeViews ein Ordner-Objekt
NewTreeNode:= aTreeView.Items.AddChildObject(aParent, 'Nodename', Pointer);
erstellen und dessen Pointer an den Knoten dranhängen, etwa so:
Delphi-Quellcode:
Dabei habe ich das Ordner-Objekt so deklariert:{ Ordner-Objekt erstellen } NewFolder:= TFolder.Create(aXmlNode.Nodes[i].AttributeByName['Name']); { Pointer des Ordner-Objektes dem erstellten Knoten übergeben, sowie den oben bereits übergebenen Ordnernamen } NewTreeNode:= aTreeView.Items.AddChildObject(aParent, NewFolder.Foldername, NewFolder);
Delphi-Quellcode:
type
TFolder = class(TObject) private fFoldername : String; fExpanded: Boolean; public constructor Create(const aFoldername: string); property FolderName: string read fFoldername write fFoldername; end; Ganz wichtig zu sagen ist jedoch, dass der TreeView nicht automatisch auch die Freigabe dieser erstellen Ordner-Objekte durchführt. Löschst du also einen Knoten aus dem Baum, bist du auch für die Freigabe des Ordner-Objektes verantwortlich. Es gibt eine stark erweiterte Tree-Komponente, die sich ![]() nennt (oft auch unter VST hier im Forum zu finden). Dieser ist von Grund auf neu programmiert und besitzt u.a. auch eine automatische Speicherverwaltung der übergebenen Objekte. Nun zum Abrufen des Knotens mit Objekt:
Delphi-Quellcode:
Im obigen Fall würde jetzt beides mal das gleiche angezeigt,{ Normaler Text des Knotens } ShowMessage(TreeView1.Selected.Text); { Über casten mit TFolder kannst du den Pointer des Knotens gezielt ansprechen und die Eigenschaft Foldername abfragen } ShowMessage(TFolder(TreeView1.Selected.Data).FolderName); aber du kannst ja dein Objekt wie gewünscht aufbauen. Grüße Jürgen |
Re: XML-Struktur in Objekte verwalten
Hallo Jürgen,
danke für den Code - hast dir richtig Mühe gegeben! Ich habe deinen Ansatz nun auch verstanden, ABER ;-) Zitat:
Delphi-Quellcode:
Die Dateien müssen ja noch bedacht werden und deswegen glaube ich wäre ein objektorientierter Ansatz nicht schlecht.
type
TOrdner = class(TObject) Ordnername : String; Expanded: Boolean; Unterordner : TOrdner; Dateien : TDatei; end; Im nächsten Schritt müsste man sich Gedanken machen, wie man die einzelnen Dateien mit einem bestimmten Ordner verknüpft. Nur anhand des Ordnernamens funktioniert da ja nicht, weil ein Ordnername ja mehrfach vorkommen kann (wenn auch nicht innerhalb der gleichen Struktur). Beispiel: Zitat:
Wäre super! |
Re: XML-Struktur in Objekte verwalten
Hallo Christian,
Ich versuche, dir zur folgen, aber ganz komme ich nicht mit. Alle diese Eigenschaften des Objektes...
Delphi-Quellcode:
... wären ja nicht nötig, wenn du die Struktur, also die
type
TOrdner = class(TObject) Ordnername : String; Expanded: Boolean; Unterordner : TOrdner; Dateien : TDatei; end; Art der Gliederung von Ordnern und Dateien separat verwaltest, also etwa im TreeView selbst. Das Verknüpfen der Dateien zu einem Ordner wäre zu vergleichen mit Blättern an einem Ast. Welches Blatt zu welchem Ast gehört, ist ja letztendlich in deiner Datei gespeichert. Würdest du es in eine Datenbank legen, wäre die Vergabe einer ID und einer ParentID nötig, um den Baum wieder korrekt zusammenzusetzen. Auch das Zuordnen bzw. Unterscheiden, ob es sich um eine Datei oder einen Ordner handelt, könntest du unkompliziert innerhalb einer einzigen Klasse mittels eines Flags händeln.
Delphi-Quellcode:
Soweit ich weiß, sind in Windows eigentlich ja alles
type
TFile = class(TObject) Name : String; Expanded: Boolean; IsFolder: Boolean; end; nur Dateien -- auch die Ordner. Diese Datein werden nur als Ordner gekennzeichnet und entsprechend gehandhabt. Mit der obigen Klasse kannst du also wie ich schon im Thread davor beschrieben habe, das Objekt TFile erstellen und ihm zum Zeitpunkt der Erstellung sagen, ob es als Ordner oder Datei fungieren soll. Einzelne Eigenschaften könntest du mit festen Integer-Werten belegen und separat zuordnen. Oder willst du generell eine real existierende Ordnerstuktur einlesen? In Deinem Beispiel mit Fahrzeug / Auto / Verkäufe etc. wird für mich noch nicht deutlich, wo und warum es sich um Ordner und Dateien handelt. Für mich ist dass nur eine Liste von Kategorieren, oder verstehe ich dich da falsch? Grüße Jürgen |
Re: XML-Struktur in Objekte verwalten
Hi,
ich glaube Yheeky will das nicht in der Treeview speichern, sondern unabhängig. @Yheeky
Delphi-Quellcode:
aber das ist nicht richtig, denn dein Unterordner ist ja nicht nur einer, sondern eine Liste, genauso wie deine Dateien.
type
TOrdner = class(TObject) Ordnername : String; Expanded: Boolean; Unterordner : TOrdner; Dateien : TDatei; end; also
Delphi-Quellcode:
d.h. Du hast für die Ordnergeschichten 2 Objekte nötig
type
TOrdner = class(TObject) Ordnername : String; Expanded: Boolean; Unterordner : TOrdnerListe; Dateien : TDateiListe; end;
Delphi-Quellcode:
dann musst Du die TOrdnerliste als Klasse bekanntmachen, dann kannst Du sie erst mal im TOrdner verwenden. Das ist eine Forward-Deklaration. Nach der Definition von TOrdner kommt dann die vollständige Definition von TOrdnerliste.
type
TOrdnerliste = class; TOrdner = class ... UnterOrdner: tOrdnerliste; end; TOrdnerListe = class ... end; Damit das klappt, müssen allerdings beide Klassen in einer Unit untergebracht sein. Sie gehören ja auch irgendwie zusammen, und sollten sich daher nicht soweit voneinander weg bewegen ;-) Gruss |
Re: XML-Struktur in Objekte verwalten
Zitat:
Habe jetzt gerade mal deinen Code getestet und bin zu folgendem Ergebnis gekommen:
Delphi-Quellcode:
Funktioniert alles soweit. Mein Beispiel-XML-Code war folgender (und das hat funktioniert):
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, JvSimpleXml, StdCtrls, ComCtrls, JclSimpleXml, Contnrs; type TOrdnerSammlung = class; TOrdner = class(TObject) public Ordnername, Icon: string; Expanded: Boolean; Unterordner: TOrdnerSammlung; constructor Create; overload; end; TOrdnerSammlung = class(TObjectlist) function GetItems: TOrdner; public property Items: TOrdner read getItems; end; type TForm1 = class(TForm) TreeView1: TTreeView; XML: TJvSimpleXML; Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private public OrdnerListe: TOrdnerSammlung; procedure WriteNode(Node: TTreeNode; Liste: TOrdnerSammlung); procedure ReadInObjects(XMLText: TJclSimpleXMLElem; OrdnerSammlung: TOrdnerSammlung); end; var Form1: TForm1; implementation {$R *.dfm} function TOrdnerSammlung.GetItems: TOrdner; begin end; constructor TOrdner.Create; begin Unterordner := TOrdnersammlung.Create(True); end; procedure TForm1.WriteNode(Node: TTreeNode; Liste: TOrdnerSammlung); var I: Integer; newTreeNode: TTreeNode; begin if Liste.Count > 0 then for I := 0 to Liste.Count - 1 do begin newTreeNode := TreeView1.Items.AddChild(Node, TOrdner(Liste[I]).Ordnername); newTreeNode.ImageIndex := StrToInt(TOrdner(Liste[I]).Icon); if TOrdner(Liste[I]).Unterordner.Count > 0 then WriteNode(newTreeNode, TOrdner(Liste[I]).Unterordner); end; end; procedure TForm1.ReadInObjects(XMLText: TJclSimpleXMLElem; OrdnerSammlung: TOrdnerSammlung); var I, J: Integer; newFolder: TOrdner; begin // Wenn die XML-Struktur noch Daten enthält if XMLText.Items.Count > 0 then for I := 0 to XMLText.Items.Count - 1 do begin // Wenn es sich um einen Ordner handelt if XMLText.Items[I].Name = 'Ordner' then begin if XMLText.Items[I].Properties.Count > 0 then begin // Neues Ordnerobjekt erstellen newFolder := TOrdner.Create; for J := 0 to XMLText.Items[I].Properties.Count - 1 do begin // Der Ordnername wird ausgelesen if XMLText.Items[I].Properties[J].Name = 'Name' then newFolder.Ordnername := XMLText.Items[I].Properties[J].Value; if XMLText.Items[I].Properties[J].Name = 'Expanded' then if XMLText.Items[I].Properties[J].Value = 'True' then newFolder.Expanded := True else newFolder.Expanded := False; if XMLText.Items[I].Properties[J].Name = 'Icon' then newFolder.Icon := XMLText.Items[I].Properties[J].Value; end; end; end; // Fügt der Liste das Ordnerobjekt hinzu OrdnerSammlung.Add(TOrdner(newFolder)); // Auf Unterordner prüfen if XMLText.Items[I].Items.Count > 0 then // Wenn es sich um einen Ordner handelt if XMLText.Items[I].Name = 'Ordner' then ReadInObjects(XMLText.Items[I], newFolder.Unterordner); end; end; procedure TForm1.Button1Click(Sender: TObject); begin XML.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Test.xml'); Ordnerliste := TOrdnerSammlung.Create(True); ReadInObjects(XML.Root, Ordnerliste); Button2.Enabled := True; end; procedure TForm1.Button2Click(Sender: TObject); begin TreeView1.Items[1].DeleteChildren; WriteNode(TreeView1.Items[1], Ordnerliste); end; end.
XML-Code:
Ich frage mich gerade nur, warum das schon funktioniert, obwohl ich in GetItems noch garnichts stehen habe? :gruebel: Wofür brauche ich es dann bzw. warum erwartet property Items ein read?
<?xml version="1.0" encoding="ISO-8859-1"?>
<Daten> <Ordner Name="Autos" Expanded="True" Icon="15"> <Ordner Name="Meine Autos" Icon="16"/> <Ordner Name="Andere Autos" Icon="17"/> </Ordner> </Daten> |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:40 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-2025 by Thomas Breitkreuz