[Neuling] C# XML-Datei ändern

03/29/2013 13:19 Hydroxyandrost#1
Guten Tag,
da ich mich seit wenigen Tagen mit C# beschäftige, wollte ich ein wenig rumprobieren mit den Lesen und Schreiben von XML-Dateien. Dafür habe
ich ein kleiner Projekt angelegt, hier der Quellcode:

PHP Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;


namespace 
nostale
{
    class 
Program
    
{
        static 
void Main(string[] args)
        {
            
Console.Title "NosTale Gold";
            
string befehl "";
            

            while (
befehl != "/exit")
            {
#region einstellungen
                
                
                
string input;
                
                
int zahlergebnis;
                
                
XmlReader reader XmlReader.Create(@"C:\Users\Jonas\Desktop\gold.xml");
                
reader.ReadStartElement("Gold");
                
                
reader.ReadStartElement("ic");
                
string ic reader.ReadString();
                
reader.ReadEndElement();

                
reader.ReadStartElement("drop");
                
string drop reader.ReadString();
                
reader.ReadEndElement();

                
reader.ReadStartElement("npc");
                
string npc reader.ReadString();
                
reader.ReadEndElement();

                
reader.ReadStartElement("player");
                
string player reader.ReadString();
                
reader.ReadEndElement();

                
reader.ReadStartElement("reward");
                
string reward reader.ReadString();
                
reader.ReadEndElement();

                
reader.ReadStartElement("all");
                
string all reader.ReadString();
                
reader.ReadEndElement();

                
reader.Close();



#endregion

#region goldanzahl
                
                        

                
DateTime Zeit DateTime.Now;
                
Zeit.ToString("yyyy-MM-dd_HH:mm:ss");

                
Console.WriteLine("Letzte Aenderung:");
                
Console.WriteLine(Zeit);
                
Console.WriteLine("");
                
Console.WriteLine("************************************************************");
                
Console.WriteLine("");
                
Console.WriteLine("Instant Combat      :  {0} Gold"ic);
                
Console.WriteLine("Gesammelt           :  {0} Gold"drop);
                
Console.WriteLine("Verkauft an NPC     :  {0} Gold"npc);
                
Console.WriteLine("Verkauft an Spieler :  {0} Gold"player);
                
Console.WriteLine("Quest/Ts Belohnung  :  {0} Gold"reward);
                
Console.WriteLine("___________________________________________________________");
                
Console.WriteLine("Gesamt              :  {0} Gold"all);
                
Console.WriteLine("___________________________________________________________");
                
Console.WriteLine("");
                
befehl Console.ReadLine();
#endregion


#region befehle

                
switch (befehl)
                {
                    case 
"/ic":



                        
Console.WriteLine("Wie viel?");
                        
input Console.ReadLine();
                        
zahl Convert.ToInt32(input);

                        
ergebnis Convert.ToInt32(ic) + zahl;
                        
                        
/* Und das Ergebnis soll in der XML-Datei aktualisiert werden 
                           Also soll es dann so aussehen: <ic>ergebnis</ic> 
                           das gleiche bei den anderen auch*/
                    
break; 

                    case 
"/drop":

                        
Console.WriteLine("Wie viel?");
                        
input Console.ReadLine();
                        
zahl Convert.ToInt32(input);

                        
ergebnis Convert.ToInt32(drop) + zahl;

                        break;

                    case 
"/npc":



                        
Console.WriteLine("Wie viel?");
                        
input Console.ReadLine();
                        
zahl Convert.ToInt32(input);

                        
ergebnis Convert.ToInt32(npc) + zahl;

                        break;

                    case 
"/player":

                        
Console.WriteLine("Wie viel?");
                        
input Console.ReadLine();
                        
zahl Convert.ToInt32(input);

                        
ergebnis Convert.ToInt32(player) + zahl;

                        break;

                    case 
"/reward":



                        
Console.WriteLine("Wie viel?");
                        
input Console.ReadLine();
                        
zahl Convert.ToInt32(input);

                        
ergebnis Convert.ToInt32(reward) + zahl;

                        break;

                    case 
"/all":

                        
Console.WriteLine("Wie viel?");
                        
input Console.ReadLine();
                        
zahl Convert.ToInt32(input);

                        
ergebnis Convert.ToInt32(all) + zahl;

                        break;



                }
                
#endregion


             
Console.Clear();
            }
        }


    }

Wie man unten sieht, habe ich ein Kommentar geschrieben

Quote:
/* Und das Ergebnis soll in der XML-Datei aktualisiert werden
Also soll es dann so aussehen: <ic>ergebnis</ic> das gleiche bei den anderen auch*/
Jou, ich will die Datei nicht immer neu schreiben lassen, sondern nur den Wert ersetzen. Hat da jmd. eine Idee, wie ich das hinbekommen könnte?
03/29/2013 14:18 disortion#2
Du kannst eine XML-Klasse einbinden die dir dann z.B. Nodes zu Verfügung stellt.
Mit diesen Nodes kannst du dann die entsprechenden Werte auslesen/ersetzen/lesen/schreiben/etc.

Das würde grob so aussehen: ParentNode.ChildNode.Value(DEIN WERT);

Dafür musst du aber die XML-Datei auch mit diesen entsprechenden Knoten aufbauen was bei dir nicht der Fall ist(oder extern gelöst wurde).

Ansonsten fällt mir hier nur ein einfach mit entsprechendem "replace()" zu arbeiten.
03/29/2013 18:53 nkkk#3
warum genau willst du datei nicht neu schreiben lassen? Die datei scheint mir nicht so gross , dass das ins gewicht fallen würde.

Ich persönich benutzte XmlReader eher selten, C# gibt die da viele alternativen(XmlReader, XmlSeralizer ,Xdocument (aka Linq to xml), XmlDucument(eher veraltet)), ich benutzte am liebsten XmlSeralizer und XDocument.
XmlReader kann nur xml dateien lesen (Reader = leser)

hier wie ich es machen würde(muss nicht zu 100% richtig sein da ich nicht weis wie deine xml datei aussieht)
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Programm
    {
        static void Main(string[] args) 
        {
            var s = File.Open("gold.xml",FileMode.Open);
            var ser = new XmlSerializer(typeof(XmlGold));
            var gold = (XmlGold) ser.Deserialize(s);
            s.Close();

            foreach (var p in typeof(XmlGold).GetProperties())
                Console.WriteLine(p.Name + " hat den wert: " + p.GetValue(gold, null));
            Console.WriteLine("Welchen wert wollen sie ändern?");
            var wert_name = Console.ReadLine().TrimStart('/');
            Console.WriteLine("um wieviel wollen sie ändern?");
            var wert_delta = Int32.Parse(Console.ReadLine().TrimStart('/'));
            foreach (var p in typeof(XmlGold).GetProperties())
                if (p.Name == wert_name)
                {
                    p.SetValue(gold, (Int32)p.GetValue(gold, null) + wert_delta, null);
                    break;
                }
            s = File.Open("gold.xml", FileMode.Truncate);
            ser.Serialize(s, gold);
            s.Close();
        }
    }
    [XmlType(TypeName="Gold")]
    public class XmlGold 
    {
        [XmlElement(ElementName = "ic")]
        public Int32 ic { get; set; }
        [XmlElement(ElementName = "drop")]
        public Int32 drop { get; set; }
        [XmlElement(ElementName = "player")]
        public Int32 player { get; set; }
        [XmlElement(ElementName = "reward")]
        public Int32 reward { get; set; }
        [XmlElement(ElementName = "all")]
        public Int32 all { get; set; }
    }
}
das hat jetzt noch nciht alles z.B. gibt es nicht das datum aus...
Ps: ich würde "all" nicht als eigenständigen wert speichern sondern bei der ausgabe einfach all die davor summieren.