List (of Typ) in xml-Datei speichern

  • VB.NET

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von lurker.

    List (of Typ) in xml-Datei speichern

    Guten Abend.

    Ich möchte eine List (Of Termin) abspeichern. Dabei ist mir xml am sinnvollstem vorgekommen. (In Java weiß ich ganz genau wie ich tun müsste ;) )

    Mithilfe von Google bin ich auf den XmlSerializer gestoßen. Ich habe versucht diesen Ordnungsgemäß einzubauen, doch leider funktioniert das ganze leider nicht so wie es eigentlich sollte.

    Code:

    VB.NET-Quellcode

    1. Public Sub speichern()
    2. Dim objStreamWriter As New StreamWriter(Application.StartupPath & "\Terminlog.xml")
    3. Dim x As New XmlSerializer(New Termin().GetType)
    4. x.Serialize(objStreamWriter, listAktuel)
    5. objStreamWriter.Close()
    6. End Sub


    Zum Problem:
    Der Terminlog.xml bleibt mit diesem Code leider leer.

    An was liegt das? Liegt es daran, dass list nicht von dem unterstütz XmlSerializer wird (wahrscheidlich müssen solch Objecte Serilizable oder so ähnlich implementieren)
    Wie kann ich das umgehen? Geht das überhaupt? Falls nicht, was empfehlt ihr mir?
    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%
    So weit ich weis, müssen bei der XML-Serialisierung 3 Sachen eingehalten werden:
    1. Das Attribut <Serializable()> muss auf die Klasse angewendet werden.
    2. Die Klasse muss über einen parameterlosen Konstruktor Sub New() verfügen.
    3. Alle Eigenschaften, die serialisiert werden sollen, müssen mit dem Public-Modifizierer ausgestattet sein.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VB1963“ ()

    eine List(Of T) lässt sich problemlos serialisieren, jdfs. solange T serialisierbar ist.
    Das geht türlich nicht mit lurkers GurkenCode, aber auf Msdn solls wohl bessere Codebeispiele geben.
    Wie findet man die? Mit F1 - Visual-Studio richtig nutzen

    Allerdings stimme ich @programmer71: zu, dass, wenn man Termine abspeichern möchte, dass man da offensichtlich mit einer Datenverarbeitung befasst ist, und da nimmt man dann besser eine für Datenverarbeitung vorgesehene Technologie, etwas typisierte Datasets.
    Daten laden, speichern, verarbeiten

    programmer71 schrieb:

    nimm doch gleich lieber ein DataSet.
    Würd ich ja gerne, doch die Vorgabe ist eine List(of T) zu benutzen.

    ErfinderDesRades schrieb:

    aber auf Msdn solls wohl bessere Codebeispiele geben.

    Ich habe diesen Code auch gefunden, doch keine Möglichkeit direkt ein ganzes Objekt zu schreiben. Oder ist soetwas in .net überhaubt nicht möglich?
    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%
    Dim x As New XmlSerializer(New Termin().GetType)
    x.Serialize(objStreamWriter, listAktuel)

    Das klappt nicht.

    Du hast doch da ne Liste von Terminen, oder?
    Dann musst du auch List(of Termin).GetType machen ;)
    --
    Noch eins: Du machst entweder deinen Code im Form_Load, oder du machst Try Catch.
    Beides solltest du lieber lassen, weil du (wie du gerade selbst gemerkt hast) Fehler unterdrückt werden.
    Hier hätte es eig. längst eine Exception geben müssen.

    PS: Aktuell schreibt man mit ll.

    Manawyrm schrieb:

    ähm. Müsste klappen..
    Leider nicht, nun kommt folgende Fehlermeldung
    Fehler beim Reflektieren des Typs 'System.Collections.Generic.List`1[Desktopanwendung.Termin]'.

    Manawyrm schrieb:



    PS: Aktuell schreibt man mit ll.
    Ist ein Angabefehler, und ich über nahm ihn einfach als "Protest" ;)
    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%
    Probierma:
    GetType(List(Of Termin))

    GetType und Object.GetType() sind im Prinzip das Selbe, nur dass sich Foo.GetType() explizit auf die Instanz bzw. "Foo" bezieht.
    /nicht getestet

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „rotherford“ ()

    Das ganze könnte man auch so machen:

    VB.NET-Quellcode

    1. Public Sub Save(Of T)(ByVal obj As Object, ByVal path As String)
    2. Dim xmlSerializer As New XmlSerializer(GetType(T))
    3. Using writer As New StreamWriter(path)
    4. xmlSerializer.Serialize(writer, obj)
    5. End Using
    6. End Sub


    Bsp Aufruf:

    VB.NET-Quellcode

    1. Dim l As New List(Of String)
    2. l.Add("Item")
    3. l.Add("Item2")
    4. l.Add("Item3")
    5. Save(Of List(Of String))(l, Path.Combine(Environment.CurrentDirectory, "test.xml"))


    Output:

    Spoiler anzeigen

    XML-Quellcode

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    3. <string>Item</string>
    4. <string>Item2</string>
    5. <string>Item3</string>
    6. </ArrayOfString>

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ident“ ()

    Ich komm einfach nicht auf den Fehler...

    Es wird immer bei dieser Zeile:

    VB.NET-Quellcode

    1. Dim xmlSerializer As New XmlSerializer(GetType(T))

    Dieser Fehler geworfen:
    Fehler beim Reflektieren des Typs 'System.Collections.Generic.List`1[Desktopanwendung.Termin]'.

    Es gibt auch keinen Innerenfehler

    Es ändert auch nichts wenn ich mal probemässig das so übernehme: :cursing:

    VB.NET-Quellcode

    1. Public Sub speichern()
    2. Dim xmlSerializer As New XmlSerializer(GetType(List(Of Termin)))
    3. Using writer As New StreamWriter(Application.StartupPath & "\Terminlog.xml")
    4. xmlSerializer.Serialize(writer, listAktuel)
    5. End Using
    6. End Sub
    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%

    xtts02 schrieb:

    Ich wiederhole meine Frage aus Posting #10.
    Zu 1): Head der

    VB.NET-Quellcode

    1. <Serializable()>
    2. Public Class Termin
    3. Implements IComparable(Of Termin)
    4. End Class


    Zu 2): Ist vorhanden

    zu 3): Es ist ALLES in Termin public

    Spoiler anzeigen
    [*]Das Attribut <Serializable()> muss auf die Klasse angewendet werden.
    [*]Die Klasse muss über einen parameterlosen Konstruktor Sub New() verfügen.
    [*]Alle Eigenschaften, die serialisiert werden sollen, müssen mit dem Public-Modifizierer ausgestattet sein.
    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%
    Versuche mit einer ausgelagerten List (Of Termin).
    Beispiel:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private _persons As New PersonCollection
    3. Private _filename As String = IO.Path.Combine(IO.Path.GetTempPath, "persons.xml")
    4. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    5. End Sub
    6. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    7. Using sw As New IO.StreamWriter(_filename)
    8. Dim x As New Xml.Serialization.XmlSerializer(GetType(PersonCollection))
    9. x.Serialize(sw, _persons)
    10. End Using
    11. End Sub
    12. Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    13. If Not IO.File.Exists(_filename) Then Return
    14. Using sr As New IO.StreamReader(_filename)
    15. Dim x As New Xml.Serialization.XmlSerializer(GetType(PersonCollection))
    16. _persons = CType(x.Deserialize(sr), PersonCollection)
    17. End Using
    18. End Sub
    19. Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
    20. _persons.Add(New PersonCollection.Person With {.FirstName = "Peter", .LastName = "Mustermann", .BirthDay = New Date(1982, 11, 21)})
    21. _persons.Add(New PersonCollection.Person With {.FirstName = "Lisa", .LastName = "Musterfrau", .BirthDay = New Date(1992, 11, 21)})
    22. _persons.Add(New PersonCollection.Person With {.FirstName = "Andre", .LastName = "Mustermädchen", .BirthDay = New Date(2002, 11, 21)})
    23. End Sub
    24. Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
    25. For Each p In _persons
    26. Debug.Print("Vorname: {0}, Nachname: {1}, Geburtsdatum: {2}", p.FirstName, p.LastName, p.BirthDay.ToString)
    27. Next
    28. End Sub
    29. End Class
    30. <Serializable()> _
    31. Public Class PersonCollection
    32. Inherits List(Of Person)
    33. Public Sub New()
    34. End Sub
    35. <Serializable()> _
    36. Public Class Person
    37. Public Sub New()
    38. End Sub
    39. Public Property FirstName As String
    40. Public Property LastName As String
    41. Public Property BirthDay As Date
    42. End Class
    43. End Class

    ErfinderDesRades schrieb:

    lingt unverschämt, aber ists möglich, dass wir den ganzen Code der Klasse Termin
    ist kein problem:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. <Serializable()>
    3. Public Class Termin
    4. Implements IComparable(Of Termin)
    5. Public erinnerung As Integer
    6. Public uhrzeit As Zeit
    7. Public datum As Date
    8. Public beschreibung As String
    9. Public Sub New(ByVal erinnerung As Integer, ByVal uhrzeit As Zeit, ByVal datum As Date, ByVal beschreibung As String)
    10. Me.erinnerung = erinnerung
    11. Me.uhrzeit = uhrzeit
    12. Me.beschreibung = beschreibung
    13. End Sub
    14. Public Sub New()
    15. End Sub
    16. Public Sub setErinnerung(ByVal erinnerung As Integer)
    17. Me.erinnerung = erinnerung
    18. End Sub
    19. Public Sub setUhrzeit(ByVal uhrzeit As Zeit)
    20. Me.uhrzeit = uhrzeit
    21. End Sub
    22. Public Sub setBeschreibung(ByVal beschreibung As String)
    23. Me.beschreibung = beschreibung
    24. End Sub
    25. Public Sub setDatum(ByVal datum As Date)
    26. Me.datum = datum
    27. End Sub
    28. Public Function getErinnerung() As Integer
    29. Return Me.erinnerung
    30. End Function
    31. Public Function getUhrzeit() As Zeit
    32. Return Me.uhrzeit
    33. End Function
    34. Public Function getBeschreibung() As String
    35. Return Me.beschreibung
    36. End Function
    37. Public Function getDatum() As Date
    38. Return Me.datum
    39. End Function
    40. Function CompareTo(ByVal other As Desktopanwendung.Termin) As Integer Implements IComparable(Of Desktopanwendung.Termin).CompareTo
    41. If Me.datum.CompareTo(other.datum) < 1 Then
    42. Return -1
    43. ElseIf Me.datum.CompareTo(other.datum) > 1 Then
    44. Return 1
    45. Else
    46. If Me.uhrzeit.Compare(other.uhrzeit) < 1 Then
    47. Return -1
    48. ElseIf Me.uhrzeit.Compare(other.uhrzeit) > 1 Then
    49. Return 1
    50. Else
    51. Return 0
    52. End If
    53. End If
    54. End Function
    55. Public Overrides Function ToString() As String
    56. Return erinnerung & ";" & uhrzeit.ToString & ";" & datum & ";" & beschreibung
    57. End Function
    58. End Class
    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%