Laden...

XML Speichervorgang Dateien mit anhängen/abändern

Erstellt von AceTecNic vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.441 Views
A
AceTecNic Themenstarter:in
51 Beiträge seit 2018
vor 4 Jahren
XML Speichervorgang Dateien mit anhängen/abändern

verwendetes Datenbanksystem: XML

Ich arbeite an einem Programm mit dem ich Farbpulverbestände und deren Lagerort erfassen kann.
Beim eingeben gibt es drei Textboxen die das in eine XML schreiben.
Nach langem probieren und lesen kann ich die Struktur nun endlich wie gewünscht abspeichern.
Bei jedem Speichervorgang überschreibt er mir die ganze Datei, ähnlich wie bei txt-Dateien, allerdings finde ich keine AppendAll ähnlichen Befehle.

Was ich vor habe:
Beim eingeben der Werte (RAL, Lagerort, Gewicht) soll geprüft werden, ob RAL schon vorhanden ist, wenn ja: das Gewicht zum bestehenden dazu addieren. Sollte der Lagerort gleich sein, aber die RAL unterschiedlich müsste eine einfache Msgbox auftauchen.
Wenn kein RAL und kein Lagerort vorhanden, müsste ein neuer Eintrag hinzugefügt werden.
Das ganze soll in einer Listbox (gern auch was anderes wenn inkompatibel) angezeigt werden.

Meine Frage: Ist das ganze einfacher mit einer Datenbank? Ich habe mich noch nie groß damit beschäftigt daher kenne ich mich damit nicht gut aus.

Ich möchte keinen Code ergaunern, wenn mir jemand ein paar Tipps geben kann wie ich das angehen soll probiere ich gern ein wenig aus. Ja - Ich bin ein Neuling in Sachen C# und programmieren im Allgemeinen... Daher sieht mein Code komisch aus und ist nicht perfekt 😄

Anbei mein Code bis jetzt:

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.Xml.Linq;


namespace PulverExplorer
{
    public partial class Bearbeiten : Form
    {
        public Bearbeiten()
        {
        
        InitializeComponent();
        }

        private void speichernUndSchließenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                //------------------------
                // Speichert 
                /*Datenklasse datenklasse = new Datenklasse();

                datenklasse.RAL = txt_in_RAL.Text;
                datenklasse.LAGERORT = txt_in_Lagerort.Text;
                datenklasse.GEWICHT = txt_in_Gewicht.Text;

                Datenspeichern.SaveDaten(datenklasse, "C:\\Desktop\\Datenblock.xml");
                this.Close();
                */
                //-----------------------
                //Versuch zum speichern im Baum
                XElement Farben =
                    new XElement("Farbübersicht",
                        new XElement("RAL", txt_in_RAL.Text),
                        new XElement("Lagerort", txt_in_Lagerort.Text),
                        new XElement("Gewicht", txt_in_Gewicht.Text));

                        
                Datenspeichern.SaveDaten(Farben, "C:\\Desktop\\Datenblock.xml");

            }
            catch
            {
                MessageBox.Show("Hoops");
            }
          
        }  
        

        private void abbrechenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btn_Eintragen_Click(object sender, EventArgs e)
        {
            
            /*
            string Pfad = @"C:\test.txt";
            string RAL = txt_in_RAL.Text;
            string Lagerort = txt_in_Lagerort.Text;
            string Gewicht = txt_in_Gewicht.Text;

            File.AppendAllText(Pfad,"\n" + RAL + "\t" + "\t" + Lagerort + "\t" + "\t" + Gewicht);
            */
        }
    }
}

Datenspeichern.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml.Serialization;

namespace PulverExplorer
{
    public class Datenspeichern
    {
        public static void SaveDaten(object obj, string filename)
        {
            XmlSerializer sr = new XmlSerializer(obj.GetType());
            TextWriter writer = new StreamWriter(filename);
            sr.Serialize(writer, obj);
            writer.Close();
        }
    
    }
}

Das kommt dabei raus:

<?xml version="1.0" encoding="utf-8"?>
<Farbübersicht>
  <RAL>5018</RAL>
  <Lagerort>1.658</Lagerort>
  <Gewicht>14.5</Gewicht>
</Farbübersicht>
6.911 Beiträge seit 2009
vor 4 Jahren

Hallo AceTecNic,

Ist das ganze einfacher mit einer Datenbank?

Das hatten wir schon in Speichern in eine bestehende txt-Datei und braucht hier nicht wiederholt werden.

Wenn du es per XmlSerialisierung angehst, so verwende im Speicher als Datenklasse ein Dictionary<K, V> mit entsprechendem Key (Lagerort, RAL). Dann wird es einfacher.

Es ist auch nicht nötig XElement als Modell zu verwenden, das ist schon zu nah am XML dran. Entweder per XElement selbst das aufbauen od. Xml-Serialisierung. Einfacher ist es aber mit dem Dictionary.

Überleg dir generell was du abbilden willst. Wie das geschehen soll lass vorerst außer Acht.
Du willst eine Übersicht haben, die angibt wieviel von der jeweiligen Farbe an welchem Lagerort vorhanden ist. Korrekt?

D.h. die erste Unterteilung ist nach Lagerort. Jeder Lagerort kann mehrere Farben haben und zu jeder Farbe soll die vorhanden Menge gespeichert werden.
Als (UML-) Modell schaut das dann wie im angehängten Bild aus.

Das gilt es nun in Code zu gießen...(update kommt gleich)

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

6.911 Beiträge seit 2009
vor 4 Jahren

Hallo AceTecNic,

Ich möchte keinen Code ergaunern

Ich hab das Gefühl dass das auch stimmt, daher hab ich ein kleines Projekt gebastelt, andem du dich orientieren kannst. Siehe Anhang.
VS 2017 od. neuer mit installierten .NET 4.8 ist nötig (kann sicher auch auf .NET 4.5 laufen).

Was ist dabei?* Trennung von Logik und UI (nähere Infos -> [Artikel] MVVM und DataBinding (ist für WPF, aber die Grundlagen gelten auch für WinForms, etc.)

  • Unit-Tests (für ein paar Typen, siehe ReadMe.txt im Test-Projekt)
  • ein paar C#-Features, damit du siehst wie es elegant möglich ist

Was ist nicht dabei?* deine gewünschte Anwendung 😉 Das hier soll eine Hilfestellung sein, wie von dir gewünscht

  • Unit-Tests für alle Typen
  • komplette UI mit Hinzufügen, Editieren (dazu reichen meine Winforms-Kenntnisse auch nicht mehr aus -- müsste mich selbst wieder einarbeiten)

Den Rest solltest du selbst schaffen können.

Noch etwas: in Speichern in eine bestehende txt-Datei hat Abt ein mögliches korrektes XML gezeigt, dessen Aufbau genau umgekehrt zu meinem hier ist. Keines der beiden erachte ich als "richtiger", es hängt vielmehr vom Anwendungsfall ab. Also ob der Lagerort (bei mir) od. die Farbe (bei Abt) im Vordergrund steht. Filtern lässt sich -- z.B. mit Linq -- in beide Richtungen.
Hier ist auch ein Vorteil einer richtigen DB zu sehen, nämlich dass diese Unterscheidung egal ist, da DBs für so etwas ausgelegt und gemacht wurden.

Letzter Hinweis zum Projekt: ich hab das jetzt eben schnell runtergetippt, daher erhebe ich auch keinen Anspruch dass es ausgereift und ideal ist. Es gibt durchaus Verbesserungen, aber für eine grobe Richtschnur sollte es reichen.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

A
AceTecNic Themenstarter:in
51 Beiträge seit 2018
vor 4 Jahren

Vielen Dank für deine Bemühungen!!!

Du willst eine Übersicht haben, die angibt wieviel von der jeweiligen Farbe an welchem Lagerort vorhanden ist. Korrekt?

Genau, ich möchte wissen welche Farbe, an welchem Lagerort, in welcher Masse vorhanden ist.

Überleg dir generell was du abbilden willst. Wie das geschehen soll lass vorerst außer Acht.

Habe ein Bild mit angefügt wie ich das machen möchte.

Ich hab das Gefühl dass das auch stimmt, daher hab ich ein kleines Projekt gebastelt, andem du dich orientieren kannst. Siehe Anhang.
VS 2017 od. neuer mit installierten .NET 4.8 ist nötig (kann sicher auch auf .NET 4.5 laufen).

Vielen Dank! Ich hoffe du bist nicht so lange dran gesessen extra wegen mir 8o

Ich habe mir das Projekt mal angesehen, allerdings brauche ich immer ein wenig bis ich andere Codes gelesen habe und mir durchblick verschafft hab. 😁

Mit dem Dictionary muss ich mich noch einlesen, da finde ich sicherlich ein paar How2 im Netz..

Danke für deine Hilfe! 🙂

EDIT: Bild vergessen anzufügen

6.911 Beiträge seit 2009
vor 4 Jahren

Hallo AceTecNic,

Habe ein Bild mit angefügt wie ich das machen möchte.

Genau mit so einem Bild solltest du die Überlegungen starten, noch bevor eine Zeile programmiert wird.
Das gibt genau das wieder was du haben willst. Die Umsetzung davon ist dann Programmierer-Handwerk.

Ich hoffe du bist nicht so lange dran gesessen extra wegen mir

Ich schick dir dann die Rechnung 😉
Hat nicht so lange gedauert, aber ich wollte ein paar Punkte wie Unit-Tests, etc. einbauen. V.a. damit ein "Anfänger" einen möglichen Weg sieht wie es gehen kann. Unit-Tests haben oft eine hohe moralische Hemmschwelle, die jedoch unbegründet ist. Ganz im Gegenteil: ohne Tests weiß ja nicht ob der Code überhaupt passt.

andere Codes gelesen habe und mir durchblick verschafft hab.

Versuch einmal das Projekt -- v.a. die Model-Typen -- zu verstehen.
Gem. deinem Bild sollte das XML wie von Abt im anderen Thread skizziert ausschauen. Wenn du das Projekt hier verstanden hast, so ist es ziemlich einfach* das so zu ändern, damit es wie in deinem Bild gezeigt funktioniert.

* das mit "einfach" bitte nicht falsch verstehen. Ich bin schon lange dabei, daher ist es einfach 😉 Mit der obigen Ansage will ich nur ausdrücken, dass du das sicher schaffen wirst, sobald du verstanden hast worum es geht, denn es ist keine Hexerei, etc. nötig. Einfach die Typen etwas umbauen und fertig. Der erste Schritt ist aber das Verständnis was passiert. Dazu zählt auch -- wie du richtig erkannt hast -- das Dictionary als praktische Datenstruktur.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

A
AceTecNic Themenstarter:in
51 Beiträge seit 2018
vor 4 Jahren

Danke für den Hinweis mit dem Dictionary!
Vom Prinzip her gefällt mir das schon ganz gut 😄

Hab mal eine einfache Übung gemacht mit der ich RAL, Lagerort und Gewicht hinzufügen kann und mir diese im msgbox ausgibt.

Werde mich die Tage mal mit deinem Programm auseinander setzen. Da das schon ziemlich komplex ist, werd ich wohl etwas länger benötigen. Vorallem so viele Klassen und keine Ahnung wieviel da noch drin ist 😮

Bei mir sind "Programme" immer nur auf einer Seite... Zumindest noch.

Du hast viele Funktionen drin von denen ich noch nie gehört habe. Denke ich brauch bis dahin noch etwas.
Habe gestern noch mit einem C# "Kurs" angefangen, da mir doch einiges von Grund auf noch fehlt.
Denke es ist besser wenn ich diesen vorab mache um zumindest gewisse Grundkenntnisse und die Strukturen zu erlernen.

public void btn_eingeben_Click(object sender, EventArgs e)
        {
            string RALbox = txt_in_1.Text;
            string Lagerbox = txt_in_2.Text;
            string Kilobox = txt_in_3.Text;
            Dictionary<string, string> farben = new Dictionary<string, string>();

            farben.Add("RAL", RALbox);
            farben.Add("Lagerort", Lagerbox);
            farben.Add("kg", Kilobox);

            MessageBox.Show("RAL " + RALbox + "\n" + "Lagerort " + Lagerbox + "\n" + "kg" + Kilobox);


        }
6.911 Beiträge seit 2009
vor 4 Jahren

Hallo AceTecNic,

Bei mir sind "Programme" immer nur auf einer Seite... Zumindest noch.

Das ist / war vermutlich bei jedem zu Beginn so. Auch daher das Beispiel mit einem Aufbau wie es "besser", zumindest aufgeteiltert, geht.
Alle Typen haben recht wenig Code, da eben alles aufgeteilt ist. Nicht nur die Übersichtlich-/Lesbarkeit vom Code steigt dadurch, auch lässt sich der Code besser warten. D.h. das Projekt ist für spätere Änderungen / Erweiterungen / Anpassungen besser gerüstet als wenn alles in einer Mega-Datei (Form1.cs) steht.
Zusätzlich wird somit der Code testbar, einfacher versionierbar usw. Die Vorteile davon sind mannigfaltig, ich werde nicht alles wiederholen, da diese mehr od. weniger gesichertes Wissen ist 😉

Da das schon ziemlich komplex ist

Ich wünsche dir dass du nach dem "Aha-Erlebnis" das nicht mehr als komplex, sondern trivial siehst. (Das war zumindest meine Motivation das Projekt so zu erstellen)

im msgbox ausgibt.

Als Hinweis für später: Warten auf Schließen einer anderen Form [und warum man Dialoge nicht modal machen sollte] und Nenne deinen Fall, wo du denkst, ohne modalen Dialog geht es nicht, und ich nenne eine Alternative

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

A
AceTecNic Themenstarter:in
51 Beiträge seit 2018
vor 4 Jahren

Ich danke dir für deine Bemühungen und deinen Beistand zu meinen (vielen) Fragen! 🙂

Ich werde mir wie gesagt diese Woche noch den Kurs reinhämmern um die Grundlagen einfach mal zu verstehen. Da hab ich doch noch viele Defizite gefunden. Ich denke die sollten schon sitzen bevor man sich in ein zu großes "Anfängerprojekt" reinstürzt.

Sobald ich damit durch bin, werde ich mir mal deinen Code vorknüpfen. Eventuell fällt mir das dann etwas leichter. 😁

Als Hinweis für später: Warten auf Schließen einer anderen Form [und warum man Dialoge nicht modal machen sollte] und Nenne deinen Fall, wo du denkst, ohne modalen Dialog geht es nicht, und ich nenne eine Alternative

Über die MSGBox habe ich schon mehr gelesen, dass diese nicht unbedingt eine gute Wahl ist. Allerdings nehm ich diese gern für "kleine" Ausgaben. Zumindest für Übungszwecke...

Ich würde das hier dann mal vorerst als -gelöst- betrachten.

Abschließende Frage noch an dich: Du gibst nicht zufällig "Onlinekurse" oder ähnliches? 😁 👍

6.911 Beiträge seit 2009
vor 4 Jahren

Hallo AceTecNic,

Du gibst nicht zufällig "Onlinekurse" oder ähnliches?

Nein.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"