[VC#] XML Daten Vergleichen

janosch

Erfahrenes Mitglied
HI!

Ich bin grad dabei eine Higscoreliste zu Programmieren. Die Daten lese ich aus einer XML Datei ein und möchte sie sortiert wider ausgeben. Das einlesen der XML Datei und das Anzeigen der Datensätze funktioniert soweit. Jedoch habe ich jetzt das Problem, dass ich mithilfe von "EQUALS" keinen vergleich machen kann.
So jetzt erst mal mein Code:

highscore.xml
PHP:
<?xml version="1.0" encoding="utf-8" ?>
<highscore>
  <spieler>
    <name>
      Jan
    </name>
    <zuege>
      4
    </zuege>
  </spieler>
  <spieler>
    <name>
      Janosch
    </name>
    <zuege>
      8
    </zuege>
  </spieler>
  <spieler>
    <name>
      Michael
    </name>
    <zuege>
      14
    </zuege>
  </spieler>
  <spieler>
    <name>
      Tom
    </name>
    <zuege>
      21
    </zuege>
  </spieler>
</highscore>

PHP:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Xml;

namespace _Gewinnt
{
    public partial class highscore : Form
    {
        StreamReader streamReader = null;
        StringBuilder text = null;
        string xmlPath = null;
        string text1 = null;

        public highscore()
        {
            InitializeComponent();
            text = new StringBuilder();
            string applicationName = Assembly.GetExecutingAssembly().GetName().CodeBase;
            string applicationPath = Path.GetDirectoryName(applicationName);
            xmlPath = Path.Combine(applicationPath,"highscore.xml");

            streamReader = new StreamReader(xmlPath);
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(streamReader);

            XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//spieler");

            for (int i = 0; i < xmlNodeList.Count; i++)
            {
                if (xmlNodeList[i]["zuege"].InnerText=="21") MessageBox.Show("geht");//Test ob der vergleich funktioniet
               if(xmlNodeList[i]["zuege"].InnerText.Equals("4"))MessageBox.Show("geht equals");//Test ob der vergleich funktioniet


            }


            
        }

    }
}

Für Hilfe wäre ich dankbar.
Achja eine Frage habe ich noch. Und zwar wie kann ich das ganze sortiert nach "zuegen" ausgeben? Gibt es dafür eine fertige funktion

mfg Janosch
 
Zuletzt bearbeitet:

Norbert Eder

Erfahrenes Mitglied
Aus jedem Highscore-Eintrag ein eigenes Objekt vom (beispielsweise) Typ Highscore generieren. Die Klasse Highscore implementiert IComparable und damit kannst du die Objekte dann auch vergleichen und sortieren.
 

janosch

Erfahrenes Mitglied
HI!

THX erstmal für die Hilfe aber ich bin in C# nicht so gut will heisen habe grad erst angefangen
und kenn mich noch nicht so gut in OOP aus. Kannst du mir zeigen wie das geht?
 

janosch

Erfahrenes Mitglied
HI!

Hab ich das jetzt richtig verstanden, dass ich jetzt noch eine klasse "Highscore_data" mit den jeweiligen get/set methoden erstellen muss?

Die Daten schreib ich dann mit hilfe einer Schleife widerrum in die einzelnen Objekte.

So z.B.:
Code:
        SortedList<Highscore_data, string> xmlData = 
            new SortedList<Highscore_data, string>();



            for (int i = 0; i < xmlNodeList.Count; i++)
            {

xmlData.Add(new Highscore_data(xmlNodeList[i]["zuege"].InnerText,xmlNodeList[i]["name"].InnerText));


            }
 

janosch

Erfahrenes Mitglied
HI!

So ich habe jetzt mal folgendes gemacht. Ich habe mir eine Klasser erstelt in der ich die Daten Speichern kann und ruf diese Klasse jetzt in einer for schleife auf. Jedoch bekomme ich jetzt immer eine Fehler beim durchlauf der FOR-Schleife. Ich weiß echt nicht mehr weiter :confused:

Hier noch mal der Code:

highscore.cs
PHP:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Xml;

namespace _Gewinnt
{
    public partial class highscore : Form
    {
        StreamReader streamReader = null;
        StringBuilder text = null;
        string xmlPath = null;

        public highscore()
        {
            SortedList<highscore_data,string> xmlData = new SortedList<highscore_data,string>();

            InitializeComponent();

            string applicationName = Assembly.GetExecutingAssembly().GetName().CodeBase;
            string applicationPath = Path.GetDirectoryName(applicationName);
            xmlPath = Path.Combine(applicationPath,"highscore.xml");
            //MessageBox.Show(xmlPath);

            //streamReader = new StreamReader(xmlPath);
            //platz1.Text = streamReader.ReadToEnd();
            //this.Controls.Add(this.platz1);
            //streamReader.Close();

            streamReader = new StreamReader(xmlPath);
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(streamReader);

            XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//spieler");

            MessageBox.Show(xmlNodeList.Count.ToString());

            try
            {
                for (int i = 0; i < xmlNodeList.Count; i++)// hier liegt der fehler
                {
                    xmlData.Add(new highscore_data(xmlNodeList[i]["name"].InnerText, xmlNodeList[i]["zuege"].InnerText), null);

                }

                MessageBox.Show(xmlData.Count.ToString());
            }
            catch (Exception)
            {

                throw new ArgumentOutOfRangeException();
                
            }

        }

        private void OK_Click(object sender, EventArgs e)
        {

        }

    }
}

highscore_data.cs

PHP:
using System;
using System.Collections.Generic;
using System.Text;

namespace _Gewinnt
{
    class highscore_data : IComparable <highscore_data>
    {

        string name = null;
        string zuege = null;

        public int CompareTo(highscore_data other)
        {
            return 0;
        }

        public string getName()
        {
            return this.name;

        }

        public string getZuege()
        {
            return this.zuege;

        }

        public highscore_data(string nameIn, string zuegeIn)
        {
            this.name = nameIn;
            this.zuege = zuegeIn;
        }
        public highscore_data()
        {

        }
    }
}

Vielleicht kann mir ja jemand weiter helfen.


mfg Janosch


P.S. Ich bin echt noch ein Anfänger was VS05 und C# angeht ;)
 

Norbert Eder

Erfahrenes Mitglied
Ich hab hier etwas für dich, schau es dir in Ruhe an und stelle dann deine Fragen :)

Zuerst die Daten-Klasse (diese enthält dann immer einen Highscore-Eintrag)
C#:
public class Highscore : IComparable<Highscore>
{
    private string _name = String.Empty;
    private int _score = 0;

    public string Name
    {
        get { return this._name; }
        set { this._name = value; }
    }

    public int Score
    {
        get { return this._score; }
        set { this._score = value; }
    }

    public Highscore(string name, int score)
    {
        this._name = name;
        this._score = score;
    }

    public override string ToString()
    {
        return this._name.PadRight(20, ' ') + this._score;
    }

    #region IComparable<Highscore> Members

    public int CompareTo(Highscore other)
    {
        if (this._score.CompareTo(other._score) == 0)
            return this._name.CompareTo(other._name);
        else
            return this._score.CompareTo(other._score) * (-1);
   }

    #endregion
}
Durch das implementierte Interface IComparable musst die Methode CompareTo implementiert werden, die in unserem Fall als signifikante Eigenschaft den erreichten Score hat (absteigende Sortierung) und in weiterer Folge noch den Namen sortiert (aufsteigend).

Und hier nun der Test der Klasse inklusive Ausgabe (hier allerdings Konsole. Du musst das dann halt in einer Liste oder was auch immer in deiner Form dann anzeigen):
C#:
List<Highscore> highscoreList = new List<Highscore>();
highscoreList.Add(new Highscore("Norbert2", 17));
highscoreList.Add(new Highscore("Norbert1", 17));
highscoreList.Add(new Highscore("Norbert3", 3));
highscoreList.Add(new Highscore("Karl", 3));

highscoreList.Sort();

Console.WriteLine("Highscore");
Console.WriteLine("------------------------------------------");

foreach(Highscore hscore in highscoreList)
    Console.WriteLine(hscore);
Die Ausgabe sieht so aus:
Code:
Highscore
------------------------------------------
Norbert1            17
Norbert2            17
Karl                3
Norbert3            3
Wie gesagt, schau dir das in Ruhe an, sollte aber sonst nicht allzu schwierig sein.
 

janosch

Erfahrenes Mitglied
HI!

Ich habe mir das jetzt angeschaut und soweit ist mir das jetzt klar. Eine Frage habe ich jedoch noch.

Das hier:

PHP:
highscoreList.Add(new Highscore("Norbert2", 17));
highscoreList.Add(new Highscore("Norbert1", 17));
highscoreList.Add(new Highscore("Norbert3", 3));
highscoreList.Add(new Highscore("Karl", 3));

müste dan ja auch ungefähr so gehen,wenn man die Daten aus ein XML Datei liest:

PHP:
                for (int i = 0; i < xmlNodeList.Count; i++)
                {
                    highscoreList.Add(new highscore_data(xmlNodeList[i]["name"].InnerText, xmlNodeList[i]["zuege"].InnerText));

                }

So weit meine Theorie. Ich kann es leider nicht testen, da ich grad auf der Arbeit bin.

mfg

Janosch
 
Zuletzt bearbeitet:

Norbert Eder

Erfahrenes Mitglied
Du solltest schon auch überprüfen was da in InnerText so drinnen steht. Sonst kannst dir deine Anwendung schnell mal um die Ohren hauen.
 

Neue Beiträge