XML auslesen

  • C#

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von rgomez.

    XML auslesen

    Hallo Zusammen

    ich Kämpfe gerade etwas mit C# und XML

    Ich möchte einmal alle Serien Namen auslesen das bereits bestens Funktioniert. Das Problem liegt im Moment daran das ich die dazugehöhrigen Staffel und Folgen auslesen möchte (für nur eine Serie)


    C#-Quellcode

    1. XmlReader xmlReader = XmlReader.Create("test.xml");
    2. while (xmlReader.Read())
    3. {
    4. if ((xmlReader.NodeType == XmlNodeType.Element) && (xmlReader.Name == "serie"))
    5. {
    6. if (xmlReader.HasAttributes)
    7. MessageBox.Show(xmlReader.GetAttribute("name"));
    8. }
    9. }


    Das xmlReader.Name == "serie" begrenzt mich hier ja Wohl nur auf die Namen aber ich habe keinen zugriff mehr auf die staffel, lass ich das draußen bekomme ich ja wieder alle Staffeln?

    Kann mir jemand Helfen? Ich glaube ich hab den falschen ansatz


    hier mal meine Beispiel xml

    XML-Quellcode

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <serien>
    3. <serie name="SERIE 1">
    4. <staffel nr="1">
    5. <folge nr="1" view="0"/>
    6. </staffel>
    7. <staffel nr="2">
    8. <folge nr="1" view="0"/>
    9. <folge nr="2" view="0"/>
    10. <folge nr="3" view="0"/>
    11. <folge nr="4" view="0"/>
    12. </staffel>
    13. <staffel nr="3">
    14. <folge nr="1" view="0"/>
    15. <folge nr="2" view="0"/>
    16. <folge nr="3" view="0"/>
    17. <folge nr="4" view="0"/>
    18. <folge nr="5" view="0"/>
    19. </staffel>
    20. </serie>
    21. <serie name="SERIE 2">
    22. <staffel nr="22">
    23. <folge nr="500" view="55"/>
    24. </staffel>
    25. <staffel nr="23">
    26. <folge nr="601" view="0"/>
    27. <folge nr="602" view="0"/>
    28. <folge nr="603" view="0"/>
    29. <folge nr="4" view="0"/>
    30. </staffel>
    31. <staffel nr="24">
    32. <folge nr="801" view="0"/>
    33. <folge nr="802" view="0"/>
    34. <folge nr="803" view="0"/>
    35. <folge nr="804" view="0"/>
    36. <folge nr="805" view="0"/>
    37. </staffel>
    38. </serie>
    39. </serien>
    ich rate sehr von XmlReader ab.
    Wesentlich einfacher wird Xml-Verarbeitung mit einem XmlDocument-Objekt.
    XmlDocument unterstützt auch ("XPath"-)Abfragen ans Xml, vergleichbar Datenbank-Abfragen per Sql.
    gugge Xml-Tutorial
    Es gibt sogar noch was moderneres, nämlich XDocument - aber in c# bringt das keine Vorteile (meine Meinung)
    ich habe gerade versucht es mit XDocument, leider nin ich seit mehreren Stunden nicht erfolgreich. Es scheitert einfach immer am unterblock

    Ich hab jetzt mal diesen kleinen ansatz

    C#-Quellcode

    1. XElement root = XElement.Load(@"test.xml");
    2. XElement element = root.Element("serie");
    3. XElement serienA = element.Element("staffel");
    4. Console.WriteLine(serienA);



    er gibt mir aber leider nur den ersten staffel block aus.

    EDIT:

    C#-Quellcode

    1. XElement root = XElement.Load("test.xml");
    2. XElement element = root.Element("serie");
    3. IEnumerable<XElement> elements = element.Descendants("staffel");
    4. foreach (XElement item in elements)
    5. {
    6. /// Console.WriteLine("--- " + item);
    7. FolgenNr++;


    so bekomme ich jetzt raus das es 3 Folgen sind, das reicht mir hier für das erste (geht auch bestimmt eleganter)


    jetzt brauche ich nurnoch die Folgen Anzahl einer Staffel und ob die Folge view 1 oder 0 ist.
    das ganze bezieht sich auch nur auf die erste Serie, wie kann man hier auch zB die zweite ausgeben lassen?

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „paq“ ()

    Du kannst XmlSerializer nutzen.

    Dafür musst du erstmal Klassen definieren für die Objekte in deiner XML. Ein sehr nutzliches Tool ist Xml2CSharp. (Einfach paste XML datei und Convert!)

    In deinem Fall sieht das dann so aus.

    C#-Quellcode

    1. namespace Entities
    2. {
    3. [XmlRoot(ElementName = "folge")]
    4. public class Folge
    5. {
    6. [XmlAttribute(AttributeName = "nr")]
    7. public string Nr { get; set; }
    8. [XmlAttribute(AttributeName = "view")]
    9. public string View { get; set; }
    10. }
    11. [XmlRoot(ElementName = "staffel")]
    12. public class Staffel
    13. {
    14. [XmlElement(ElementName = "folge")]
    15. public List<Folge> Folge { get; set; }
    16. [XmlAttribute(AttributeName = "nr")]
    17. public string Nr { get; set; }
    18. }
    19. [XmlRoot(ElementName = "serie")]
    20. public class Serie
    21. {
    22. [XmlElement(ElementName = "staffel")]
    23. public List<Staffel> Staffel { get; set; }
    24. [XmlAttribute(AttributeName = "name")]
    25. public string Name { get; set; }
    26. }
    27. [XmlRoot(ElementName = "serien")]
    28. public class SerienCollection
    29. {
    30. [XmlElement(ElementName = "serie")]
    31. public List<Serie> Serien { get; set; }
    32. }
    33. }


    Wie du siehst das Tool definiert String als Typ für die Nummern und übernimmt 1-zu-1 die Namen der XML datei. Du kannst aber troztdem deine Klassen "anpassen" so lange du durch die XML-Attributen die Relation definierst.

    Dann kannst du den XML "deserializen" mittels XmlSerializer

    C#-Quellcode

    1. SerienCollection serienCollection = null;
    2. string path = "D:\\serien.xml";
    3. XmlSerializer serializer = new XmlSerializer(typeof(SerienCollection));
    4. StreamReader reader = new StreamReader(path);
    5. serienCollection = (SerienCollection)serializer.Deserialize(reader);
    6. reader.Close();


    Schau mal dann in serienCollection. Da hast du eine Liste aus Serien, die Staffeln haben, die wiederum Folgen haben. Dann kannst einfach wie du brauchst auf die Daten zugreifen wie z.B

    C#-Quellcode

    1. foreach (var serie in serienCollection.Serien)
    2. {
    3. foreach (var staffel in serie.Staffel)
    4. {
    5. foreach (var folge in staffel.Folge)
    6. {
    7. Console.WriteLine($"Das ist {folge.Nr} mit View:{folge.View}. " + Environment.NewLine +
    8. $"Gehört zu {staffel.Nr} Staffel von {serie.Name}");
    9. }
    10. }
    11. }
    Life doesn't give you a datasheet. Sometimes the docs are wrong and you have to try it.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „rgomez“ ()

    Klar! Du hast jetzt ein Objekt "SerienCollection".

    Du kannst z.B Linq-To-Objects nutzen. Z.B:

    C#-Quellcode

    1. //Gibt aus alle Serien mit Name "Foo".
    2. var targetSerie = serienCollection.Serien.Where(s => s.Name == "Foo");
    3. //Gibt aus alle Serien mit mehr als 3 Staffel.
    4. var targetSerie2 = serienCollection.Serien.Where(s => s.Staffel.Count > 3);
    5. //Nimm einfach x elemente aus der Liste.
    6. var targetSerie3 = serienCollection.Serien.Take(x);
    7. // Gibt aus alle Serien mit mehr als 2 Staffeln und die einer von der Staffeln mind. 5 Folgen hat.
    8. var targetSerie4 = serienCollection.Serien.Where(s => s.Staffel.Count > 2 && s.Staffel.Any(st => st.Folge.Count > 5));


    Mit Linq du hast grenzlose Möglichkeiten. Du kannst aber auch ganz normal:

    C#-Quellcode

    1. var serie = SerienCollection.Serien[0];
    Life doesn't give you a datasheet. Sometimes the docs are wrong and you have to try it.