Laden...

Gezielte XML Elemente auslesen und in Variable speichern

Erstellt von Sharpykeks vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.389 Views
S
Sharpykeks Themenstarter:in
8 Beiträge seit 2018
vor 5 Jahren
Gezielte XML Elemente auslesen und in Variable speichern

Hallöchen,

hoffe jemand kann einer armen kleinen C#lerin helfen 😃

Ich versuche mich mit C# gerade an XML Dateien, was bisher auch gut klappt.
Ich habe eine XML Datei die auch gelesen werden kann. Generell geht es nur ums Auslesen.
Es klappt schon mit diesem Code:

namespace XML_Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (!File.Exists("C:\\xml\\settings.xml"))
            {
                MessageBox.Show("Datei existiert nicht");
                return;

            }
            XmlReader xr = new XmlTextReader("C:\\xml\\settings.xml");


           

            while (xr.Read())
            {
                if (xr.NodeType == XmlNodeType.Element)
                {
                    if (xr.AttributeCount > 0)
                    {
                        while (xr.MoveToNextAttribute())
                            MessageBox.Show(xr.Name + " -> " + xr.Value );
                    }
                }
            }

            xr.Close();

        }
    }
}

Das Ganze wird mir schön nach und nach in einer Message Box ausgegeben.
Die XML sieht so in etwa aus:

<?xml version="1.0" encoding="ISO-8859-1"?>
<autobahn>
   	<autos>
		<auto name="Auto1"/>
		<auto name="Auto2"/>
	
	</autos>

	<verkehr>
		<status name="Stau!"/>
		<status name="Kein Stau!"/>
  	</verkehr>

	<infozeile>
		<info name="Unfall auf der Strecke!"/>
	</infozeile>

</autobahn>

Mit dieser Funktion lese ich natürlich immer alles aus, und gebe auch gleichzeitig aus.

Ich möchte ihm nun sagen, dass er bspw. nur die Reihe Autos durchgehen soll und jeden Autonamen in eine eigene Variable speichern soll die ich dann weiter verwenden kann. Allerdings weiß ich nicht genau wie ich das Umsetzen soll. Es kann ja sein, dass ich später in der XML noch ein Auto hinzufügen will.

Mit freundlichen Grüßen

16.806 Beiträge seit 2008
vor 5 Jahren

Ob der Aufbau der XML so sinn macht, kann ich aufgrund des Kontext so nicht sagen.
An für sich ist eine Collection "Autos" und dann ein Element "Autos" doppelt gemoppelt.

Was Du jedenfalls willst nennt sich XML Serialisierung.

Aus Deiner XML würde (Neue Klasse in Visual Studio -> Edit -> Paste Special -> Paste XML as Classes)

    // NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public partial class autobahn
    {

        private autobahnAuto[] autosField;

        private autobahnStatus[] verkehrField;

        private autobahnInfozeile infozeileField;

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayItemAttribute("auto", IsNullable = false)]
        public autobahnAuto[] autos
        {
            get
            {
                return this.autosField;
            }
            set
            {
                this.autosField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayItemAttribute("status", IsNullable = false)]
        public autobahnStatus[] verkehr
        {
            get
            {
                return this.verkehrField;
            }
            set
            {
                this.verkehrField = value;
            }
        }

        /// <remarks/>
        public autobahnInfozeile infozeile
        {
            get
            {
                return this.infozeileField;
            }
            set
            {
                this.infozeileField = value;
            }
        }
    }

    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class autobahnAuto
    {

        private string nameField;

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string name
        {
            get
            {
                return this.nameField;
            }
            set
            {
                this.nameField = value;
            }
        }
    }

    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class autobahnStatus
    {

        private string nameField;

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string name
        {
            get
            {
                return this.nameField;
            }
            set
            {
                this.nameField = value;
            }
        }
    }

    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class autobahnInfozeile
    {

        private autobahnInfozeileInfo infoField;

        /// <remarks/>
        public autobahnInfozeileInfo info
        {
            get
            {
                return this.infoField;
            }
            set
            {
                this.infoField = value;
            }
        }
    }

    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class autobahnInfozeileInfo
    {

        private string nameField;

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string name
        {
            get
            {
                return this.nameField;
            }
            set
            {
                this.nameField = value;
            }
        }
    }

Oft ist es einfacher, wenn Du nach OOP designest und das dann in eine XML formst; nicht umgekehrt.

public class Auto
{
    public string Name { get; set; }
}

public enum StauState
{
    Stau,
    KeinStau
}
public class Stau
{
    public StauState State { get; set; }
}

public class Info
{
    public string Name { get; set; }    
}

public class Autobahn
{
    public List<Auto> Autos { get; set; }
    public List<Stau> Staus { get; set; }
    public List<Info> Infos { get; set; }
}
S
Sharpykeks Themenstarter:in
8 Beiträge seit 2018
vor 5 Jahren

Also der Grund ist folgender, ich wollte ganz einfach nur eine Konfigurationsdatei erstellen, sodass man Label o.Ä. umbenennen kann ohne in den Code gehen zu müssen. Ich weiß nicht ob sich da XML eignet oder doch eher ein ini Datei.

P
441 Beiträge seit 2014
vor 5 Jahren

Prinzipiell eignet sich dafür jedes Dateiformat. Die Frage ist ob es sinnvoll ist soetwas zu machen - die würde ich dir selber überlassen.

Im Endeffekt bildet die Konfigurationsdatei, egal ob xml, json oder ini nur eine Objektstruktur (also Instanzen von Klassen) ab, die du zur Laufzeit mit Werten aus der Datei (= Deserialisierung) befüllst und dann auswertest.
Das gleiche würde auch mit einer Datenbank oder einer anderen Abstraktion (z.B. HTTP REST API) funktionieren.

Ini Dateien bieten dir dabei allerdings lange nicht die Flexibilität und Unterstützung durch Bibliotheken, wie xml oder json. Sie haben gefühlt auch eher den Touch der 90er Jahre 😃

16.806 Beiträge seit 2008
vor 5 Jahren

Sharpykeks es ist immer besser gleich zu sagen, worum es geht.
Ansonsten ist es - wie hier eben - nicht zielgerichtet.

Die Frage ist ob es sinnvoll ist soetwas zu machen - die würde ich dir selber überlassen.

Ich würde das bestimmt nicht selbst machen.

Die aktuell beste Art und Weise mit Konfiguratione umzugehen, ist meiner Meinung nach https://www.nuget.org/packages/Microsoft.Extensions.Configuration/
Microsoft hat enorm viel hinein investiert, was man auch an Qualität und Flexibilität merkt.

Siehe auch aktueller Beitrag aus Juni 2018 Best practice für das Verwalten von Einstellungen in einer Software

F
10.010 Beiträge seit 2004
vor 5 Jahren

@Abt:

Sharpykeks es ist immer besser gleich zu sagen, worum es geht.
Ansonsten ist es - wie hier eben - nicht zielgerichtet.

Schon Richtig, aber dann auch genau lesen was er vor hat, nicht wie er es vor hat.

@Sharpykeks:
Was du machen willst nennt sich Lokalisierung und da gibt es viel bessere und std konformere Lösungen.
Für WPF benutzen wir z.b. https://www.codeproject.com/Articles/35159/WPF-Localization-Using-RESX-Files
Für WindowsForms [Tutorial] Lokalisierung von Texten in .NET