# [C#] XML-Datei parsen



## haui95 (25. Jan 2014)

Guten Tag,

ich möchte eine XML-Datei effizient und mit wenig Codezeilen parsen. Dabei sollen die Attribute der Elemente in verschiedene Listen gespeichert werden. Diese Listen dienen als Parameter des Konstruktors der Klasse Spur. Am Ende jedes Elementes "spur" der XML-Datei soll die neu erstellte Spur zu einer Liste "spuren" hinzugefügt werden.

[XML]
<?xml version="1.0" encoding="UTF-8"?>
<punkte>
    <spur>
        <punkt x="976.0" y="384.0"/>
        <punkt x="375.0" y="389.0"/>
        <punkt x="185.0" y="394.0"/>
        <punkt x="-20.0" y="399.0"/>
        <ampel id="1" pos="292" phase="6"/>
    </spur>
    <spur>
        <punkt x="976.0" y="325.0"/>
        <punkt x="575.0" y="300.0"/>
        <punkt x="535.0" y="-20.0"/>
        <ampel id="2" pos="292" phase="6"/>
    </spur>
    <spur>
        <punkt x="-20.0" y="536.0"/>
        <punkt x="250.0" y="531.0"/>
        <punkt x="500.0" y="531.0"/>
        <punkt x="976.0" y="520.0"/>
        <ampel id="3" pos="225" phase="6"/>
    </spur>
    <spur>
        <punkt x="-20.0" y="480.0"/>
        <punkt x="425.0" y="415.0"/>
        <punkt x="477.0" y="-20.0"/>
        <ampel id="4" pos="225" phase="6"/>
    </spur>
    <spur>
        <punkt x="400.0" y="-20.0"/>
        <punkt x="470.0" y="430.0"/>
        <punkt x="976.0" y="460.0"/>
        <ampel id="5" pos="218" phase="6"/>
    </spur>
    <spur>
        <punkt x="340.0" y="-20.0"/>
        <punkt x="310.0" y="300.0"/>
        <punkt x="-20.0" y="343.0"/>
        <ampel id="6" pos="218" phase="6"/>
    </spur>
</punkte>
[/XML]

Bisher habe ich folgenden Code:


```
XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            doc.Normalize();

            var elements = doc.GetElementsByTagName("spur");
            foreach (XmlElement spur in elements)
            {
                List<float> xList = new List<float>();
                List<float> yList = new List<float>();
                List<int> id = new List<int>();
                List<int> pos = new List<int>();

                var points = spur.GetElementsByTagName("punkt");
                var lights = spur.GetElementsByTagName("ampel");

                foreach (XmlElement p in points)
                {
                    xList.Add(float.Parse(p.GetAttribute("x")));
                    yList.Add(float.Parse(p.GetAttribute("y")));
                }

                foreach (XmlElement l in lights)
                {
                    pos.Add(int.Parse(l.GetAttribute("pos")));
                    id.Add(int.Parse(l.GetAttribute("id")));
                }

                spuren.Add(new Spur(xList, yList, id, pos));
            }
```

Gibt es eine Möglichkeit, das Auslesen der XML-Datei zu optimieren. Mit Linq bin ich auch nicht weiter gekommen. Obwohl der Code funktioniert, gefällt er mir jedoch nicht.

Vielen Dank

Hauke


----------



## SasaE (3. Apr 2019)

Alte Frage, soll aber trotzdem nicht unbeantwortet bleiben.
Hier meine Lösung zur Deserialisierung:
- Definition der Klassen und Attributierung entsprechend der XML
- Deserialisierungsmethode (im Beispiel statisch) im der Punkte-Klasse (wahlweise auch als separate Klasse)


```
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace _
{
    class Program
    {
        static void Main(string[] args)
        {
            var path = "C:\\Temp\\input.xml";
            var file = new FileInfo(path);
            var punkte = Punkte.Deserialize(file);
        }
    }

    [Serializable]
    [XmlRoot(ElementName = "punkte")]
    public class Punkte
    {
        [XmlElement(ElementName = "spur")]
        public List<Spur> Spuren { get; set; } = new List<Spur>();

        public static Punkte Deserialize(FileInfo file)
        {
            using (var stream = file.OpenRead())
            {
                using (var reader = new StreamReader(stream))
                {
                    var xmlSerializer = new XmlSerializer(typeof(Punkte));
                    return (Punkte)xmlSerializer.Deserialize(reader);
                }
            }
        }
    }

    [Serializable]
    public class Spur
    {
        [XmlElement(ElementName = "punkt")]
        public List<Punkt> Punkte { get; set; } = new List<Punkt>();
       
        [XmlElement(ElementName = "ampel")]
        public Ampel Ampel { get; set; }
    }
    [Serializable]
    public class Punkt
    {
        [XmlAttribute(AttributeName = "x")]
        public double X { get; set; }

        [XmlAttribute(AttributeName = "y")]
        public double Y { get; set; }
    }
   
    [Serializable]
    public class Ampel
    {
        [XmlAttribute(AttributeName = "id")]
        public int Id { get; set; }

        [XmlAttribute(AttributeName = "pos")]
        public int Pos { get; set; }

        [XmlAttribute(AttributeName = "phase")]
        public int Phase { get; set; }
    }
}
```


----------



## krgewb (3. Apr 2019)

@haui95
Für XML musst du die Code-Tags verwenden.

```
<?xml version="1.0" encoding="UTF-8"?>
<punkte>
    <spur>
        <punkt x="976.0" y="384.0"/>
        <punkt x="375.0" y="389.0"/>
        <punkt x="185.0" y="394.0"/>
        <punkt x="-20.0" y="399.0"/>
        <ampel id="1" pos="292" phase="6"/>
    </spur>
    <spur>
        <punkt x="976.0" y="325.0"/>
        <punkt x="575.0" y="300.0"/>
        <punkt x="535.0" y="-20.0"/>
        <ampel id="2" pos="292" phase="6"/>
    </spur>
    <spur>
        <punkt x="-20.0" y="536.0"/>
        <punkt x="250.0" y="531.0"/>
        <punkt x="500.0" y="531.0"/>
        <punkt x="976.0" y="520.0"/>
        <ampel id="3" pos="225" phase="6"/>
    </spur>
    <spur>
        <punkt x="-20.0" y="480.0"/>
        <punkt x="425.0" y="415.0"/>
        <punkt x="477.0" y="-20.0"/>
        <ampel id="4" pos="225" phase="6"/>
    </spur>
    <spur>
        <punkt x="400.0" y="-20.0"/>
        <punkt x="470.0" y="430.0"/>
        <punkt x="976.0" y="460.0"/>
        <ampel id="5" pos="218" phase="6"/>
    </spur>
    <spur>
        <punkt x="340.0" y="-20.0"/>
        <punkt x="310.0" y="300.0"/>
        <punkt x="-20.0" y="343.0"/>
        <ampel id="6" pos="218" phase="6"/>
    </spur>
</punkte>
```
[/B]


----------



## mihe7 (3. Apr 2019)

krgewb hat gesagt.:


> Für XML musst du die Code-Tags verwenden.


Ob ihn das nach 5 Jahren noch interessiert?


----------

