Wie kann ich in einem XML-File bestimmte Werte auslesen?

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von a.b_om.

    Wie kann ich in einem XML-File bestimmte Werte auslesen?

    Liebe Community

    Ich habe ein Programm geschrieben, der mit COM-Ports arbeitet. :thumbsup:
    Mein letztes Ziel ist noch die gespeicherten Daten in einer XML-File rauszulesen und es anzuzeigen.
    Leider habe ich keine Ahnung, wie ich auf das Element, mit dem tiefsten Namen(Parent)
    finde. :/
    zuerst COM1, falls es existiert, danach COM2 falls es existiert, ...., danach COM10, falls es existiert,....
    Danach, wenn es gefunden hat, sollte man die Innertexte der Childs in eine Liste speichern.

    *Thema verschoben* ~NoFear23m

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „a.b_om“ ()

    @a.b_om Wenn Du die XML-Datei selbst schreibst und liest, mach Dir eine XML-serialisierbare Klasse und feddich.
    Mal was als Anhaltspunkt:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private XmlFile As String = "c:\temp\data.xml" ' Pfad zum Speichern / Lesen
    3. Private Data As MyData
    4. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    5. '' Daten-Instanz erstellen und befüllen
    6. 'Me.Data = New MyData()
    7. 'Me.Data.name = "Test Status"
    8. 'Me.Data.address = "0000"
    9. 'Me.Data.type = 9999
    10. 'Me.Data.timestamp = DateTime.Now
    11. 'Me.Data.flags = 0
    12. 'Me.Data.user = "Tester"
    13. 'Me.Data.SingleValues = New List(Of Integer) From {1, 2, 3, 4, 5}
    14. End Sub
    15. ''' <summary>
    16. ''' Daten auf Festplatte schreiben
    17. ''' </summary>
    18. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    19. Me.Data.WriteData(Me.XmlFile)
    20. End Sub
    21. ''' <summary>
    22. ''' Daten von Festplatte laden
    23. ''' </summary>
    24. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    25. Me.Data = MyData.LoadData(Me.XmlFile)
    26. End Sub
    27. ''' <summary>
    28. ''' aktuelle Daten darstellen
    29. ''' </summary>
    30. Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    31. Me.ListBox1.Items.Clear()
    32. ' hier: nur das Integer-Array
    33. For Each value In Me.Data.SingleValues
    34. Me.ListBox1.Items.Add(value)
    35. Next
    36. End Sub
    37. End Class
    38. '#####################################################
    39. '#####################################################
    40. '#####################################################
    41. Imports System.IO
    42. Imports System.Text
    43. Imports System.Xml.Serialization
    44. ''' <summary>
    45. ''' Datenklasse
    46. ''' </summary>
    47. ''' <remarks>mit XML-Serialisierung</remarks>
    48. Public Class MyData
    49. ' alle vorkommenden Daten
    50. Public Property name() As String
    51. Public Property address() As String
    52. Public Property type() As Integer
    53. Public Property timestamp() As DateTime
    54. Public Property flags() As Integer
    55. Public Property user() As String
    56. Public Property SingleValues() As List(Of Integer)
    57. Public Sub New()
    58. ' Hier die Daten mit Defaultwerten befüllen oder nicht
    59. Me.name = "Hase"
    60. Me.SingleValues = New List(Of Integer)
    61. End Sub
    62. ''' <summary>
    63. ''' Daten aus einer Datei lesen
    64. ''' </summary>
    65. ''' <param name="file">Dateiname</param>
    66. ''' <returns>die geladene Instanz</returns>
    67. Public Shared Function LoadData(file As String) As MyData
    68. Dim data As New MyData()
    69. Try
    70. ' Deserialize XML file to a new object.
    71. Using sr As New StreamReader(file, Encoding.Default)
    72. Dim x As New XmlSerializer(data.GetType())
    73. data = DirectCast(x.Deserialize(sr), MyData)
    74. End Using
    75. Return data
    76. Catch
    77. ' nix tun, die Daten-Instanz ist nicht valid,
    78. ' es wird die Instanz übergeben, die bei New() erzeugt wird
    79. End Try
    80. Return data
    81. End Function
    82. ''' <summary>
    83. ''' Daten in eine Datei schreiben
    84. ''' </summary>
    85. ''' <param name="file">Dateiname</param>
    86. Public Sub WriteData(file As String)
    87. ' Serialize object to a XML file.
    88. Using sw As New StreamWriter(file, False, Encoding.Default)
    89. Dim x As New XmlSerializer(Me.GetType())
    90. x.Serialize(sw, Me)
    91. End Using
    92. End Sub
    93. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Vielen Dank RodFromGermany. Leider, möchte ich es noch nicht mit XMLSerialiser versuchen. Ich mache 2 mal das Programm, um nachher zu sehen, was die Vorteil von der XMLSerialiser zu den Hardcore Methoden sind. Mein jetztiger Code. In dieser Klasse lade ich Comboboxen mit den Werten.
    Spoiler anzeigen

    Quellcode

    1. Private Sub FillCMBs()
    2. Try
    3. Dim xmlFile As XmlDocument = New XmlDocument
    4. Dim strPath As String = "d:\D:\Daten\André\Lernen\UebungCOMPorts\UebungCOMPorts\bin\Debug\UebungCOMPortsEinstellungen.xml"
    5. Dim baudRates = New String() {"110", "300", "600", "1200", "2400", "4800", "9600", "14400", "19200", "28800", "38400", "56000", "115200", "230400", "None"}
    6. Dim paritys = New String() {"None", "Odd", "Even", "Mark", "Space"}
    7. Dim dataBits = New String() {"5", "6", "7", "8"}
    8. Dim stopBits = New String() {"1", "1.5", "2"}
    9. If CheckFileExists(strPath) Then
    10. xmlFile.Load(strPath)
    11. Else
    12. Dim ports As String() = IO.Ports.SerialPort.GetPortNames()
    13. Dim sortedPorts = ports.OrderBy(Function(p) CInt(p.Substring(3))).ToList()
    14. cmbComPort.DataSource = sortedPorts
    15. For Each bautRate As String In baudRates
    16. cmbBaudRate.Items.Add(bautRate)
    17. Next
    18. cmbBaudRate.SelectedIndex = 0
    19. For Each parity As String In paritys
    20. cmbParity.Items.Add(parity)
    21. Next
    22. cmbParity.SelectedIndex = 0
    23. For Each dataBit As String In dataBits
    24. cmbDataBits.Items.Add(dataBit)
    25. Next
    26. cmbDataBits.SelectedIndex = 0
    27. For Each stopBit As String In stopBits
    28. cmbStopBits.Items.Add(stopBit)
    29. Next
    30. cmbStopBits.SelectedIndex = 0
    31. End If
    32. Catch ex As Exception
    33. End Try
    34. End Sub


    Ich dachte eher an das InnerXml, von allen inneren Tags in eine Liste zu speichern. Das nur, wenn der der Parent auf der 2. Ebene ein gewisses InnerXml hat. Ist das überhaupt möglich?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „a.b_om“ ()

    Ok. Das ist mein Xml Modul:
    Ach entschuldigt das mit xmlFile Namensgebung.
    Spoiler anzeigen

    Quellcode

    1. Imports System.IO
    2. Imports System.Xml
    3. Imports System
    4. Module ModXML
    5. Public Sub MakeXMLFile(ByVal strPath As String, ByVal comPort As String, ByVal baudRate As Integer, ByVal parity As Integer, ByVal dataBits As Integer, ByVal stopBits As Integer)
    6. Try
    7. Dim docAs XmlDocument = New XmlDocument
    8. If Not CheckFileExists(strPath) Then
    9. Dim xnIniNode As XmlNode = xmlFile.CreateXmlDeclaration("1.0", "UTF-8", Nothing)
    10. xmlFile.AppendChild(xnIniNode)
    11. Dim xnRootNode As XmlNode = xmlFile.CreateElement("Einstellungen")
    12. xmlFile.AppendChild(xnRootNode)
    13. Else
    14. doc.Load(strPath)
    15. End If
    16. WriteInXMLFile(doc, strPath, comPort, baudRate, parity, dataBits, stopBits)
    17. dox.Save(strPath)
    18. Catch ex As Exception
    19. End Try
    20. End Sub
    21. Public Function CheckFileExists(ByVal strPath As String) As Boolean
    22. Try
    23. If File.Exists(strPath) Then Return True Else Return False
    24. Catch ex As Exception
    25. Return False
    26. End Try
    27. End Function
    28. Public Sub WriteInXMLFile(ByRef docAs XmlDocument, ByVal strPath As String, ByVal comPort As String, ByVal baudRate As Integer, ByVal parity As Integer, ByVal dataBits As Integer, ByVal stopBits As Integer)
    29. Try
    30. 'Prüft ob diese Parent schon gibt
    31. If doc.DocumentElement($"/ComPort") IsNot Nothing Then
    32. 'Parent existiert bereits
    33. 'Daten überschreiben
    34. doc.DocumentElement($"ComPort").Item("Baud_Rate").InnerText = baudRate
    35. doc.DocumentElement($"ComPort").Item("Parity").InnerText = parity
    36. doc.DocumentElement($"ComPort").Item("Databits").InnerText = dataBits
    37. doc.DocumentElement($"ComPort").Item("Stopbits").InnerText = stopBits
    38. Else
    39. 'Parent existiert nicht
    40. 'Parent wird erstellt
    41. Dim xnPerson As XmlNode = doc.CreateElement("ComPort")
    42. xnPerson.InnerText = comPort
    43. doc.DocumentElement.AppendChild(xnPerson)
    44. 'Parent wird mit Childs befüllt
    45. Dim xnBaudRate As XmlNode = doc.CreateElement("Baud_Rate")
    46. xnBaudRate.InnerText = baudRate
    47. xnPerson.AppendChild(xnBaudRate)
    48. Dim xnParity As XmlNode = xmlFile.CreateElement("Parity")
    49. xnParity.InnerText = parity
    50. xnPerson.AppendChild(xnParity)
    51. Dim xnDatabits As XmlNode = doc.CreateElement("Databits")
    52. xnDatabits.InnerText = dataBits
    53. xnPerson.AppendChild(xnDatabits)
    54. Dim xnStopBits As XmlNode = doc.CreateElement("Stopbits")
    55. xnStopBits.InnerText = stopBits
    56. xnPerson.AppendChild(xnStopBits)
    57. End If
    58. Catch ex As Exception
    59. End Try
    60. End Sub
    61. End Module
    google.com/search?q=xmldocument+iterate+through+all+nodes
    stackoverflow.com/questions/29…ugh-all-nodes-in-xml-file

    Nachtrag: Ich verstehe leider gar nicht, warum du überhaupt XML direkt lesen und schreiben willst. Wozu soll das gut sein? Erstelle Dir ein Dataset im Designer und sichere es mit Dataset.WriteXml.
    Mit dem Programmstart lädst Du es wieder ins Dataset mit Dataset.ReadXml. Insgesamt brauchst du deutlicher weniger Code, es ist wartungsärmer und in diesem Forum findest du zu Dataset sowieso die besten Anleitungen die es gibt.

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

    Danke für die Links, die haben geholfen (vor allem der 2.) :thumbsup:

    Nachtrag: Ich wollte zuerst nur die schwere Version machen und danach erst die Vereinfachung(Dataset,...). Das ist meine Art vom Lernen. Ich möchte die Vorteile sehen. Wenn ich das vorgeplappert bekomme, checke ich es erst beim 3. oder 4. Mal durchlesen. So habe ich aber die schöne und die unschöne Version.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „a.b_om“ ()