Autor Beitrag
devwatch
Hält's aus hier
Beiträge: 2

Win 7 64 Bit
VS-2010
BeitragVerfasst: Di 29.03.11 10:34 
Hallo, ich beschäftige mich gerade privat etwas mit C# und bin derzeit dabei zu Übungszwecken eine kleine Kfz-Verwaltung zu erstellen.
Klappt alles ganz gut, bis auf die Tatsache, dass ich Schwierigkeiten mit XML habe.

Ich Habe eine Klasse Auto (nur mal rudimentär angelegt) die ich bei Auswahl des Menüpunktes Speichern im Hauptmenü speichern und wieder laden möchten.
Das speichern habe ich hinbekommen, obwohl ich auch nicht weiß, ob die Routine so richtig ist?

Weiterhin bekomme ich meine Daten nicht mehr geladen aus der .XML, da häng ich gerade fest. Ich möchte die Klasse derzeit NOCH NICHT serialisieren sondern um erstmal so mit XML klar zu kommen alles zu Fuß erledigen.

Ich poste einfach mal kurz die Klasse und danach das Hauptprogramm. PS: Für Verbesserungsvorschläge oder das Entdecken grober Schnitzer, wäre ich Euch sehr dankbar!

Klasse Auto:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Fabrik
{
    //Wirklich nur rudimentär, da es hier nicht um Klassen gehen soll!
    class Auto
    {
        public int TankVolumen;
        public string Marke;
        public string Typ;
        public int Preis;
    }
}


Klasse Fabrik:
ausblenden volle Höhe C#-Quelltext
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:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace Fabrik
{
    class Program
    {
       
        static void Main(string[] args)
        {
            int item;
            List<Auto> car = new List<Auto>();

            //Abfangen von Fehlern beim Laden der Fahrzeuge
            try
            {
                Load(car);
            }

            catch (Exception ex)
            {
                //Keine XML, wir machen nix
            }

            //Menüschleife
            do
            {
                //Menüeingabe 
                try
                {
                    item = Int32.Parse(Menue());
                }

                catch(Exception ex)
                {
                    item = 0//ungültige Eingabe
                }
              
              //KFZ erfassen
              //
              if (item == 1)
              {
                  Auto kfz = new Auto();

                  Console.Clear();
                  Console.WriteLine("Fahrzeug erfassen" + "\n==================================\n");

                  Console.WriteLine("Bitte den Typ eingeben:");
                  kfz.Typ = Console.ReadLine();

                  Console.WriteLine("Bitte die Marke eingeben:");
                  kfz.Marke = Console.ReadLine();

                  Console.WriteLine("Bitte das Tank Volumen eingeben:");
                  kfz.TankVolumen = Int32.Parse(Console.ReadLine());

                  Console.WriteLine("Bitte den Preis in Euro eingeben:");
                  kfz.Preis = Int32.Parse(Console.ReadLine());

                  car.Add(kfz);
              }

              //Erfasste Fahrzeuge anzeigen
              //
              if (item == 2)
              {
                  if (car.Count > 0)
                  {
                      Console.Clear();
                      Console.WriteLine("Im System erfasste Fahrzeuge:" + "\n============================================");
                  }

                  foreach (Auto mobile in car)
                  {
                      Console.WriteLine("Typ: {0}, Marke: {1}, Tank Volumen: {2}, Preis in Euro: {3}", mobile.Typ, mobile.Marke, mobile.TankVolumen, mobile.Preis);
                  }

                  if (car.Count > 0)
                  {
                      Console.WriteLine("\n<Drücken Sie eine beliebige Taste zum Fortfahren!>");
                      Console.ReadKey();
                  }
              }

              //Fahrzeug aus dem System entfernen
              //
              if (item == 3)
              {
                  if (car.Count > 0)
                  {
                      Console.Clear();
                      Console.WriteLine("Fahrzeugübersicht:" + "\n===================================");
                      int i = 0;

                      foreach (Auto mobile in car)
                      {
                          Console.WriteLine( i.ToString() + ". Typ: {0}, Marke: {1}, Tank Volumen: {2}, Preis in Euro: {3}", mobile.Typ, mobile.Marke, mobile.TankVolumen, mobile.Preis);
                          i++;  
                      }

                      Console.WriteLine("\nBitte wählen Sie das Fahrzeug aus, welches aus dem System entfernt werden soll:");
                      i = 0;
                      i = Int32.Parse(Console.ReadLine());

                      try
                      {
                          car.RemoveAt(i);
                          Console.WriteLine("\nDas fahrzeug wurde erfolgreich aus dem System entfernt! <Taste drücken>");
                          Console.ReadKey();
                      }

                      catch (Exception ex)
                      {
                          Console.WriteLine("\nDas von Ihnen gewählte Fahrzeug existiert nicht mehr! <Taste drücken>");
                          Console.ReadKey();
                      }
                  }
              }

              //Speichern der Liste
              //
              if (item == 4)
              {
                  Save(car);
                  Console.WriteLine("\nKfz-Liste gespeichert! <Bitte eine beliebige Taste drücken!>");
                  Console.ReadKey();
              }

              //Laden der KFZ Liste
              //
              if (item == 5)
              {
                  car.Clear();
                  Load(car);

                  Console.WriteLine("\nKfz-Liste geladen! <Bitte eine beliebige Taste drücken!>");
                  Console.ReadKey();
              }
            } while (item != 6);

            //Beim beenden nochmal autom. speichern
            Save(car);
        }

        //Das Hauptmenü
        //
        static string Menue()
        {
            Console.Clear();
            Console.WriteLine("                   Hauptmenü:" +
                              "\n==========================================" +
                              "\n1. Auto anlegen" +
                              "\n2. Bisher angelegte Fahrzeuge anzeigen" +
                              "\n3. Fahrzeug entfernen" +
                              "\n4. Speichern" +
                              "\n5. Laden" +
                              "\n==========================================" +
                              "\n6. Ende\n\nEingabe Bitte:");
            return Console.ReadLine();
        }

        static void Save(List<Auto> car)
        {
            XmlWriter xml = XmlWriter.Create(Environment.CurrentDirectory + "\\Kfz.xml");
            xml.WriteStartDocument();
            xml.WriteStartElement("Kfz");

            foreach(Auto kfz in car)
            {
                try
                {
                    xml.WriteStartElement("Fahrzeug");

                    xml.WriteElementString("Typ", kfz.Typ);
                    xml.WriteElementString("Marke", kfz.Marke);
                    xml.WriteElementString("TankVolumen", kfz.TankVolumen.ToString());
                    xml.WriteElementString("Preis", kfz.Preis.ToString());

                    xml.WriteEndElement();
                }

                catch (Exception ex)
                {
                    Console.WriteLine("\nFehler! Speichervorgang abgebrochen {0} <Bitte eine beliebige Taste drücken!>", ex.Message);
                    Console.ReadKey();
                }
            }

            xml.WriteEndElement();
            xml.WriteEndDocument();
            xml.Close();
        }

        static void Load(List<Auto> car)
        {

                XmlReader xml = XmlReader.Create(Environment.CurrentDirectory + "\\Kfz.xml");
                Auto kfz = new Auto();
              
                while (xml.Read()) //Solange lesen bis ende
                {
                    xml.MoveToContent(); //Ignore Whitespace Header, Comments

                    if (xml.NodeType == XmlNodeType.Element && xml.Name == "Fahrzeug")
                    {
                        //Console.WriteLine("Typ: {0}, Marke: {1}, TankVolumen: {2}, Preis: {3}", xml.ReadElementString(), xml.ReadElementString(), xml.ReadElementString(), xml.ReadElementString());
                        
                        //Es wird ein Fehler ausgelöst wenn eine Node nicht existiert, da der Reader dann ins leere läuft (Exception)
                        kfz.Typ = xml.ReadElementString();
                        kfz.Marke = xml.ReadElementString();
                        kfz.TankVolumen = Int32.Parse(xml.ReadElementString());
                        kfz.Preis = Int32.Parse(xml.ReadElementString());

                        car.Add(kfz);
                    }
                }

                xml.Close();
           
        }
    }
}
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 29.03.11 10:54 
Hallo,

verschiebe mal die Zeile "xml.MoveToContent();" vor deine Schleife (in der Load-Methode).

Und wenn du mehrere Autos einlesen willst, dann mußt du auch die Auto-Instanz innerhalb der Read-Schleife jeweils mittels 'new' erzeugen (ansonsten bestünde deine Liste am Ende nur aus Kopien deines letzten Auto-Elements).

Und statt öffentlichen Feldern solltest du in der Auto-Klasse alles als Eigenschaften definieren mittels "{ get; set; }"...

Für diesen Beitrag haben gedankt: devwatch
devwatch Threadstarter
Hält's aus hier
Beiträge: 2

Win 7 64 Bit
VS-2010
BeitragVerfasst: Di 29.03.11 11:06 
Ja, super! Vielen Dank!

Das mit der Klasse ist mir klar, ich wollte nur nicht zu umfangreich werden. Der nächste Schritt (Neues Projekt ist dann eine saubere und serialisierbare Klasse!)

Ich hab noch ein-zwei Fragen zu meiner Anwendung:

1. Sollte man XMLReader eigentlich so verwenden, oder eher nicht? Macht es einen Unterschied, XMLReader oder XMLTextReader zu verwenden?
2. Wie gehe ich mit fehlenden <Tags> um, also wenn z.B. jemand die XML-Datei geändert hat, und z.B. der <Typ>-Tag fehlt?

Wäre schön wenn Du oder jemand sonst hier ein tolles Beispiel kennt einne Klasse so zu fuß zu laden und zu speichern....

Besten Dank!
SakeSushi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17

Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
BeitragVerfasst: Fr 01.04.11 18:51 
Zitat:
1. Sollte man XMLReader eigentlich so verwenden, oder eher nicht? Macht es einen Unterschied, XMLReader oder XMLTextReader zu verwenden?


Soweit mir bekannst ist, handelt es sich bei den XmlTextReader einfach um eine erweiterte Version des XmlReaders, welcher aber von der grundlegenden Funktionalität her nichts verbessert.

Auf die Frage "ob man den XmlReader so verwenden sollte" kann ich dir leider keine genaue Antwort geben:
Es kommt im wesentlichen auf ein wichtiges Kriterium an: Wie groß ist/sind die Datei(en)?

... wenn du es mit kleinen Datenquellen zu tun hast solltest du den XmlReader komplett vergessen und dir Linq2Xml anschauen:

XmlReader arbeitet mit einer SAX ähnlichen Technologie (genaueres hier), welche für kleine Dateien keinen Vorteil liefert!

Hier lohnt es sich Linq2Xml anzusehen:
Dies ist die .NET-Version von DOM-XmlReadern wie wir sie aus Java und diversen C++ Frameworks kennen (z.B. Qt). Hier ein kleiner vergleich von MSDN.

Wenn du dich mit Linq2Xml oder allgemein mit Linq gerne auseinader setzen willst empfehle ich dir diesen Webcast: Linq und Konsorten (LINQ und Konsorten ( Teil 4 von 8 ) - LINQ to XML)