Autor Beitrag
Christian R.
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 05.03.09 20:35 
Für mein XML-Handling erstelle ich gerade folgende Klassenstruktur (mal schematisch)

ausblenden Quelltext
1:
2:
3:
4:
5:
DatabaseXML
  CategoriesCollection  // ArrayList of Category
    Category
      EntriesCollection  // ArrayList of Entry
        Entry

Zwei Möglichkeiten:

  1. Bisherige Herangehensweise: In der Klasse DatabaseXML wird nun die XML geladen. Wenn ich dabei bleibe, dann müsste ich die Referenz auf die XML bei jeder untergeordneten Klasse über die Konstruktoren oder dafür implementierte Eigenschaften weiterreichen.

  2. Ich kann die XML auch über eine generische Klasse laden und im entsprechenden Namespace für alle abrufbar machen.

Was haltet Ihr für sinnvoller? Da mir die Erfahrung fehlt, kenne ich die Vor- und Nachteile beider Varianten nicht so gut wie Ihr. Ein Nachteil für Variante 1 ist auf jeden Fall das umständliche Herumreichen der Referenz. Allerdings weiß ich wiedrum nicht, ob es so gut ist mit einer generischen Klasse zu arbeiten, weil dann wieder die Instanzierung einer weiteren XML flach fällt. Und ein Singleton mit öffentlichem Konstruktor hat auch seine Nachteile.
Christian R.
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 05.03.09 21:32 
Vllt. wird es so anschaulicher. Ich habe folgende Klasse DatabaseXml (gekürzt)

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
class DatabaseXml
{
  public CategoryCollection Categories;

  public DatabaseXml(String pPath)
  {
    this.Path = pPath;
    this.Categories = new CategoryCollection();
    this._xmlData = new System.Xml.XmlDocument();
    try
    {
      this._xmlData.Load(this.SourceFile);
    }
    catch(Exception)
    {
      MessageBox.Show("Datenbank nicht gefunden ...\n\n" + this.SourceFile, "Datenfehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
  }
}

In der DatabaseXml werden bereits erste Operationen auf die XML ausgeführt. In CategoryCollection soll aber auch auf die XML zugegriffen werden können. Ist es jetzt günstiger die XML weiterhin in der DatabaseXml zu öffnen und die Referenz an die CategoryCollection weiterzureichen, welche diese dann wiederum an in ihr enthaltene Instanzen weiterreicht? Oder gibt es einen empfehlenswerteren Weg, wie z. B. statische Klassen?
Christian R.
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 05.03.09 22:29 
Ich denke ich habe die Lösung. Und die ist besser als mein bisheriges Konzept.

Die XML-Deklaration bleibt in der DatabaseXml. Allerdings wird nicht mehr mit der Referenz auf die XML weitergearbeitet. Sondern ich werde die XML direkt als einzelne Klassen abbilden. Dafür werde ich die entsprechenden XmlNodes an die Konstruktoren der Instanzen weiterreichen, welche wieder entsprechende childNodes Ihrer vorhandenen XML-Daten an Ihre enthaltenen Instanzen weiterreichen, usw..
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Do 05.03.09 22:48 
Was willst Du mit dieser Klassenstruktur genau machen? Willst Du nur Kategorien und Elemente in einer Collection-Hierarchie speichern und diese in XML lad- und speicherbar machen?
Christian R.
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 05.03.09 23:14 
Das Programm ist eine Adress-Verwaltung für div. Kunden. Mit Fax, Memo, etc.. Ziel ist die Erweiterbarkeit des ganzen Projektes, je nach Kundenwunsch. Als ich noch mit Delphi programmiert habe, habe ich zwar objektorientiert programmiert, aber nicht OBJEKTorientiert programmiert. Durch PHP habe ich eigentlich erst angefangen mit DesignPatterns zu arbeiten und habe das Konzept der OOP erst so richtig angefangen zu durchschauen. Nun versuche ich davon so viel wie möglich in die Praxis umzusetzen.

Die XML ist die Adress-Datenbank. Unter dem Root-Element sitzen die Kategorien, d. h. die Gruppen, in denen die Adressen eingeteilt werden können. In jeder Kategorie sind die Einträge, welche wiederum in einzelne Gruppen von Daten unterteilt sind.

Ist zwar ein bissl lang, aber verdeutlicht die abzubildenden Daten.
ausblenden volle Höhe XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
<?xml version="1.0" encoding="ISO-8859-1"?>
<AdDresser version="1.0" created="2009-02-11 13:00:00" changed="2009-02-11 13:00:00">
  <database name="Privat" customize="no" nextIndex="2">
    <entry index="1" created="2009-02-11 13:00:00" changed="2009-02-11 13:00:00">
      <general>
        <salutation>Herr</salutation>
        <nameFore>Jon</nameFore>
        <nameLast>Doe</nameLast>
      </general>
      <sector>IT, </sector>
      <company>
        <item>Teletext AG</item>
        <item></item>
      </company>
      <contactPerson>Herr Jon Doe</contactPerson>
      <addressData>
        <address>Parkstraße 7</address>
        <zipCode>00000</zipCode>
        <city>Dresden</city>
        <state>Germany</state>
        <media>
          <phone>
            <item></item>
            <item></item>
          </phone>
          <telefax>
            <item></item>
            <item></item>
          </telefax>
          <mobile>
            <item>+49 (0)351 1234567</item>
            <item></item>
          </mobile>
          <email>
            <item>Jon.Doe@teletext.de</item>
            <item></item>
          </email>
          <web>
            <item>teletext.com</item>
            <item></item>
          </web>
        </media>
        <notes></notes>
        <correspondence>
          <letters>
            <item name="Erster" date="2009-02-11 13:00:00">20090211130000.rtf</item>
          </letters>
          <telefaxes>
          </telefaxes>
          <memos>
          </memos>
          <emptySites>
          </emptySites>
        </correspondence>
      </addressData>
    </entry>
  </database>
  <database name="Kunden" customize="no" nextIndex="1">
  </database>
  <database name="Lieferanten" customize="no" nextIndex="1">
  </database>
  <database name="" customize="yes" nextIndex="1">
  </database>
</AdDresser>

Diese Struktur will ich nun als Objektmodell verfügbar machen. Dann kommen noch ein paar Methoden für die Interaktion dazu und ... ja. Mir kam eben erst der Gedanke, die Abbildung sukzessive ablaufen zu lassen.

Ich erstelle die DatabaseXml-Instanz, übergebe Ihr den Pfad auf die XML. Diese Instanz liest nur die Attribute des Root-Elements <AdDresser ...>.

Anschließend wird die CategoryCollection erzeugt und dem Konstruktor (schematisch) "Xml.RootElement.childNodes" übergeben. Und aus diesen childNodes werden dann die einzelnen Category-Instanzen in der Liste erzeugt. Diesen Category-Instanzen wird dem Konstruktor wiederum "childNodes[I].childNodes" übergeben, um in der Category-Instanz wieder eine EntryCollection zu erzeugen. Und da das gleiche Spiel wie bei den Kategorien. Bis ich dann im letzten Zipfel der XML angekommen bin. So kann ich dann in Zukunft ohne weiteres neue Elemente in der Datenstruktur aufnehmen und muss nur jeweils eine Klasse dafür implementieren und diese an entsprechender Stelle im Objektmodell "einhängen".

Jetzt verstehe ich erstmals den Gedanken der objektrelationalen Abbildung, ob nun in Datenbanken oder in einer XML ist ja egal.

Dieses Konzept sollte doch jetzt soweit funktionieren, oder? Ist es überhaupt klar, worauf ich hinaus will?

P.S.: Der Gedanke ist, dass genau diese Objektstruktur auch soweit erweitert / verwendet werden kann, dass sie z. B. in einer MySQL-Datenbank abgespeichert werden kann.
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Do 05.03.09 23:22 
Also ich würde das mal unabhängig von der XMl-Speicherung realisieren. Erstell Dir mal Deine Klassen mit den notwendigen Eigenschaften, um Deine Adressen zu verwalten. Danach beschäftige Dich mit dem XmlSerializer, der nimmt Dir die Speicherung der gesamten Struktur in XML ab. Alternativ solltest Du nur in Deiner Database-Klasse die XML-Speicherung vornehmen und die die einzelnen Elemente nur jeweils z.B. ein XmlElement erstellen lassen, dann brauchst Du das nicht.

Die dritte Möglichkeit (die auch Dein P.S. mit einschließen würde) wäre, ein DataSet oder LINQ-To-SQL-Klassen zu erstellen. Ersteres kann auch direkt aus XML auslesen, bei Letzterem bin ich nicht so ganz sicher, weil ich nur noch in DBs speichere ;).
Christian R.
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 05.03.09 23:53 
user profile iconUGrohne hat folgendes geschrieben Zum zitierten Posting springen:
Also ich würde das mal unabhängig von der XMl-Speicherung realisieren. Erstell Dir mal Deine Klassen mit den notwendigen Eigenschaften, um Deine Adressen zu verwalten.

Beim nächsten Mal mache ich das bestimmt so. Ganz ehrlich, da die XML vorher schon ausgearbeitet wurde, konnte mir dadurch erst der Zusammenhang zwischen meinen jetzt entstehenden Daten-Objekten und dem resultierenden Ausgabeformat klar werden. Aber grundsätzlich habe ich falsch herum angefangen. Das ist richtig.

user profile iconUGrohne hat folgendes geschrieben Zum zitierten Posting springen:
Danach beschäftige Dich mit dem XmlSerializer, der nimmt Dir die Speicherung der gesamten Struktur in XML ab. Alternativ solltest Du nur in Deiner Database-Klasse die XML-Speicherung vornehmen und die die einzelnen Elemente nur jeweils z.B. ein XmlElement erstellen lassen, dann brauchst Du das nicht.

An den XmlSerializer werde ich denken. Danke. Ich sehe das auch so, dass ich im jetzigen konzept die gesamte Speicherung der DatabaseXml überlassen kann. Und dann stimmt auch der ganze Kontext der Struktur wieder.

user profile iconUGrohne hat folgendes geschrieben Zum zitierten Posting springen:
Die dritte Möglichkeit (die auch Dein P.S. mit einschließen würde) wäre, ein DataSet oder LINQ-To-SQL-Klassen zu erstellen. Ersteres kann auch direkt aus XML auslesen, bei Letzterem bin ich nicht so ganz sicher, weil ich nur noch in DBs speichere ;).

Mmh. Gar nicht mal so übel. Habe es zwar grad erst im neuen Handbuch aufgeschlagen, aber werde da mal weiterlesen. Danke.

Ja. Das war's erstmal. Danke für's zuhören und für die Tips. :)
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Do 05.03.09 23:57 
user profile iconChristian R. hat folgendes geschrieben Zum zitierten Posting springen:
[...]da die XML vorher schon ausgearbeitet wurde[...]
Kleiner Tipp (fürs nächste Mal ;) ): Mit Xsd.exe kannst du aus einem XML-Schema direkt die entsprechenden C#-Klassen erstellen lassen :D .

_________________
>λ=
Christian R.
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 06.03.09 00:25 
Danke für den Tip. Ich hab's gefunden. Schaue ich mir das WE mal an.