AGB  ·  Datenschutz  ·  Impressum  







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

XML-Struktur in Objekte verwalten

Ein Thema von Yheeky · begonnen am 23. Aug 2008 · letzter Beitrag vom 25. Aug 2008
Antwort Antwort
Seite 2 von 2     12   
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#11

Re: XML-Struktur in Objekte verwalten

  Alt 24. Aug 2008, 01:14
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.
Gruß
Hansa
  Mit Zitat antworten Zitat
Pfoto

Registriert seit: 26. Aug 2005
Ort: Daun
541 Beiträge
 
Turbo Delphi für Win32
 
#12

Re: XML-Struktur in Objekte verwalten

  Alt 24. Aug 2008, 09:18
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:
type
  TOrdner = class(TObject)
    Ordnername : String;
    Expanded: Boolean;
  end;
In dem Fall würden ja alleine die Infos im gefüllten TreeView
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:
NewTreeNode:= aTreeView.Items.AddChildObject(aParent, 'Nodename', Pointer); Du könntest also beim Füllen des TreeViews ein Ordner-Objekt
erstellen und dessen Pointer an den Knoten dranhängen, etwa so:

Delphi-Quellcode:
     
      { 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);
Dabei habe ich das Ordner-Objekt so deklariert:

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 TVirtualStringTree
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:
  
  { 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);
Im obigen Fall würde jetzt beides mal das gleiche angezeigt,
aber du kannst ja dein Objekt wie gewünscht aufbauen.



Grüße
Jürgen
Jürgen Höfs
  Mit Zitat antworten Zitat
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#13

Re: XML-Struktur in Objekte verwalten

  Alt 24. Aug 2008, 15:54
Hallo Jürgen,
danke für den Code - hast dir richtig Mühe gegeben! Ich habe deinen Ansatz nun auch verstanden, ABER

Zitat von Pfoto:
Nehmen wir an, diese Infos soll Dein Objekt halten:
Delphi-Quellcode:
type
  TOrdner = class(TObject)
    Ordnername : String;
    Expanded: Boolean;
  end;
In dem Fall würden ja alleine die Infos im gefüllten TreeView
aussreichen, d.h. du bräuchtest eigentlich nicht noch Objekte anlegen,
sondern könntest bei Bedarf direkt auf den Node des TreeViews zugreifen.
Stimmt, bei diesem Aufbau nicht, aber nach genauerer Überlegung müsste der Aufbau ja wiefolgt sein:

Delphi-Quellcode:
type
  TOrdner = class(TObject)
    Ordnername : String;
    Expanded: Boolean;
    Unterordner : TOrdner;
    Dateien : TDatei;
  end;
Die Dateien müssen ja noch bedacht werden und deswegen glaube ich wäre ein objektorientierter Ansatz nicht schlecht.
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:
+ Fahrzeug
-- Auto
---- Verkäufe
-- Fahrrad
---- Verkäufe
Soweit mein Problem - vielleicht hast du oder auch jemand anderes noch eine Idee für die Umsetzung (egal ob objektorientiert oder nicht).

Wäre super!
  Mit Zitat antworten Zitat
Pfoto

Registriert seit: 26. Aug 2005
Ort: Daun
541 Beiträge
 
Turbo Delphi für Win32
 
#14

Re: XML-Struktur in Objekte verwalten

  Alt 24. Aug 2008, 17:12
Hallo Christian,

Ich versuche, dir zur folgen, aber ganz komme ich nicht mit.

Alle diese Eigenschaften des Objektes...
Delphi-Quellcode:
type
  TOrdner = class(TObject)
    Ordnername : String;
    Expanded: Boolean;
    Unterordner : TOrdner;
    Dateien : TDatei;
  end;
... wären ja nicht nötig, wenn du die Struktur, also die
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:
type
  TFile = class(TObject)
    Name : String;
    Expanded: Boolean;
    IsFolder: Boolean;
  end;
Soweit ich weiß, sind in Windows eigentlich ja alles
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
Jürgen Höfs
  Mit Zitat antworten Zitat
Benutzerbild von thkerkmann
thkerkmann

Registriert seit: 7. Jan 2006
Ort: Pulheim Brauweiler
464 Beiträge
 
Delphi 2010 Professional
 
#15

Re: XML-Struktur in Objekte verwalten

  Alt 24. Aug 2008, 18:22
Hi,

ich glaube Yheeky will das nicht in der Treeview speichern, sondern unabhängig.

@Yheeky
Delphi-Quellcode:
type
  TOrdner = class(TObject)
    Ordnername : String;
    Expanded: Boolean;
    Unterordner : TOrdner;
    Dateien : TDatei;
  end;
aber das ist nicht richtig, denn dein Unterordner ist ja nicht nur einer, sondern eine Liste, genauso wie deine Dateien.

also
Delphi-Quellcode:
type
  TOrdner = class(TObject)
    Ordnername : String;
    Expanded: Boolean;
    Unterordner : TOrdnerListe;
    Dateien : TDateiListe;
  end;
d.h. Du hast für die Ordnergeschichten 2 Objekte nötig

Delphi-Quellcode:
type
  TOrdnerliste = class;

  TOrdner = class
    ...
    UnterOrdner: tOrdnerliste;
  end;

  TOrdnerListe = class
    ...
  end;
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.
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
Thomas Kerkmann
Ich hab noch einen Koffer in Borland.
http://thomaskerkmann.wordpress.com/
  Mit Zitat antworten Zitat
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#16

Re: XML-Struktur in Objekte verwalten

  Alt 25. Aug 2008, 08:18
Zitat von thkerkmann:
Hi,

ich glaube Yheeky will das nicht in der Treeview speichern, sondern unabhängig.
Richtig! Ich möchte die Nachrichten dann in einer ListView anzeigen lassen.

Habe jetzt gerade mal deinen Code getestet und bin zu folgendem Ergebnis gekommen:

Delphi-Quellcode:
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 = 'Ordnerthen
      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 = 'Namethen
              newFolder.Ordnername := XMLText.Items[I].Properties[J].Value;
            if XMLText.Items[I].Properties[J].Name = 'Expandedthen
              if XMLText.Items[I].Properties[J].Value = 'Truethen
                newFolder.Expanded := True
              else
                newFolder.Expanded := False;
            if XMLText.Items[I].Properties[J].Name = 'Iconthen
              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 = 'Ordnerthen
          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.
Funktioniert alles soweit. Mein Beispiel-XML-Code war folgender (und das hat funktioniert):

XML-Code:
<?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>
Ich frage mich gerade nur, warum das schon funktioniert, obwohl ich in GetItems noch garnichts stehen habe? Wofür brauche ich es dann bzw. warum erwartet property Items ein read?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 06:09 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