XML Datei lesen



  • Hallo ich lernen gerade C# und versuche ein Adressbuch zu schreiben.

    XML Datei

    <Persons>
      <Person
        firstname=""
        lastname=""
        age=""
        land=""
        street=""
        place=""
        plz=""
        phone=""
        mobile="" />
      <Person
        firstname=""
        lastname=""
        age=""
        land=""
        street=""
        place=""
        plz=""
        phone=""
        mobile="" />
    </Persons>
    

    Ich wollte die Daten so auslesen und habe dann am Ende erst festgestellt das es nicht funktioniert 😡

    XmlNodeList personFirstName = xmlDoc.GetElementsByTagName("firstname");
    XmlNodeList personLastName = xmlDoc.GetElementsByTagName("lastname");
    XmlNodeList personAge = xmlDoc.GetElementsByTagName("age");
    XmlNodeList personLand = xmlDoc.GetElementsByTagName("land");
    XmlNodeList personStreet = xmlDoc.GetElementsByTagName("street");
    XmlNodeList personPlace = xmlDoc.GetElementsByTagName("place");
    XmlNodeList personPlz = xmlDoc.GetElementsByTagName("plz");
    XmlNodeList personPhone = xmlDoc.GetElementsByTagName("phone");
    XmlNodeList personMobile = xmlDoc.GetElementsByTagName("mobile");
    

    Ich finde sonst nur Beispiele in denen man einzeln ausliest aber nicht mit XmlNodeList.



  • Wie genau erhältst Du diese XML? Wird die in Editor geschrieben, vom Webserver erstellt, oder ebenfalls in deine Programm (z.B. aus einem Objekt erstellt) ?



  • public bool Save( string filename )
        {
            try
            {
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;
                settings.OmitXmlDeclaration = true;
                settings.NewLineOnAttributes = true;
    
                XmlWriter writer = XmlWriter.Create(filename, settings);
                writer.WriteStartDocument();
                writer.WriteStartElement("Persons");
    
                for (int i = 0; i < persons.Count; i++)
                {
                    writer.WriteStartElement("Person");
                    writer.WriteAttributeString("firstname", persons[i].m_firstname);
                    writer.WriteAttributeString("lastname", persons[i].m_lastname);
                    writer.WriteAttributeString("age", persons[i].m_age);
                    writer.WriteAttributeString("land", persons[i].m_land);
                    writer.WriteAttributeString("street", persons[i].m_street);
                    writer.WriteAttributeString("place", persons[i].m_place);
                    writer.WriteAttributeString("plz", persons[i].m_plz);
                    writer.WriteAttributeString("phone", persons[i].m_phone);
                    writer.WriteAttributeString("mobile", persons[i].m_mobile);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Flush();
                writer.Close();
            }
            catch (Exception ex)
            {
                Debug.Console.Print(ex.Message);
                return false;
            }
            return true;
        }
    


  • Es gibt verschiedene Wege um dein Xml zu lesen: XDocument, XmlDocument, XPathDocument + XPathNavigator.

    Um konkret auf die XmlNodeList einzugehen: GetElementsByTagName() sucht Elemente nicht Attribute. Wenn du die Attribute auswerten willst, musst du das Xml-Dokument mit XmlDocument laden, dann über die XmlNodeList das Element holen und abschließend XmlElement.GetAttribute(<Attributename>) aufrufen, um die Werte innerhalb der Attribute zu erhalten.



  • Versuche doch mal folgendes, wenn du sowieso schon ein Person Object besitzt

    using System.Xml.Serialization;
    using System.IO;
    
    public void Save()  //serialisiert ein Object und speichert diese in einem .xml-File
            {
                string pfad = @"..\..\meineXML.xml"; //Pfad des .xml-Files
    
                XmlSerializer xs = new XmlSerializer(typeof(Person));   //XMLSerializer wird instanziert als typeof(Person)
                using (TextWriter sw = new StreamWriter(pfad))  //using immer verwenden wenn Klassen IDisposeable implementieren (Stream)
                {
                    xs.Serialize(sw, this); //Serialisiert Person, wenn diese Klasse vom Typ Person ist (this)
    }
            }
    
    public void Load()  //und wieder laden        {
                string pfad = @"..\..\meineXML.xml"; //Pfad des .xml-Files
                Person person;
    
                using (FileStream fs = new FileStream(pfad, FileMode.Open)) //using immer verwenden wenn Klassen IDisposeable implementieren
                {
                    XmlSerializer xs = new XmlSerializer(typeof(Person));   //XMLSerializer wird instanziert als typeof(Person)
                    person = (Person)xs.Deserialize(fs);    //Deserialisiert 
                    this.RemoveRange(0, this.Count);    //this.clear()
                    this.AddRange(person.ToArray());    //fügt das Array[xml-file] der lsite hinzu , wenn diese Klasse vom Typ Person ist (this)
                }
            }
    


  • Es geht auch VIIIIEEEEL einfacher und eleganter wie der ganze mist da oben!

    Stichwort: Linq to XML

    EDIT:: nicht böse gemeint 😉



  • Danke für die Antwortet ich habe es mal selbst versucht aber naja...

    Das Beispiel von Peter ist sicher gut aber ich verstehe diesen Code nicht.

    public bool LoadFromXmlFile(string filename)
        {
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
    
                if (File.Exists(filename))
                {
                    xmlDoc.Load(filename);
                }
                else
                {
                    StringBuilder errorMsg = new StringBuilder("The file" + filename + "could not be located");
                    Exception ex = new Exception(errorMsg.ToString());
                }
    
                foreach (XmlNode i in xmlDoc.SelectNodes("/Persons/Person/*"))
                {
                    Debug.Console.Print(i["firstname"].Name);
                }
    
            }
            catch (Exception ex)
            {
                Debug.Console.Print(ex.Message);
                return false;
            }
            return true;
        }
    

    Egal was ich eingebe foreach durchläuft die Schleife nicht 😕 es kommt auch keine Fehlermeldung.



  • hasts schonmal getrackt? also debugging und einzelschritt durchlaufen? dann schauen was in den Variablen hängt.... mit Visual Studio geht das ja wunderbar ...



  • i ist einfach leer



  • Bist du sicher, dass deine Elemente keinen Namespace haben? Ist das oben wirklich die komplette XML-Datei oder fehlt da noch was?



  • Das ist die vollständige Datei und ich versuche jetzt schon seit Stunden sie einzulesen. Könnte mir jemand ein verständliches Beispiel schreiben, wie ich die Daten einlesen kann. Es ist zur einübung in die Sprache und ich schreibe jetzt eine neue Klasse nur zum einlesen, damit ich herausfinden kann wo der Fehler liegt.



  • kurze und verständliche basics in 3 teilen

    Klick Hier



  • Hat sich erledigt danke. Das Problem war writer.WriteAttributeString durch writer.WriteElementString ersetzt und schon kann ich die Daten lesen.



  • Kennst du auch den unterschied zwischen element und attribute?


Anmelden zum Antworten