简体   繁体   中英

Deserialize Existing XML file in VB.NET

I am changing a VB.NET application to use XmlSerializer instead of XMLDocument to read/write to an XML settings file and want to preserve backwards compatibility.

Here is a sample of the XML file contents:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <postHistory>
      <postFile>a.txt</postFile>
      <postFile>b.txt</postFile>
      <postFile>c.txt</postFile>
    </postHistory>
  </appSettings>
  <SettingsPath>d.txt</SettingsPath>
</configuration>

Here are the classes I came up with that correctly de-serialize the original file.

Imports System.Xml.Serialization
Imports System.Collections.Generic

<XmlRoot("configuration")>
Public Class LocalSettings
  <XmlElement("appSettings")>
  Public appSettings As New postHistory()
  Public SettingsPath As String = ""
End Class

Public Class postHistory
  Public postHistory As New SubSettings()
End Class

Public Class SubSettings
  <XmlElement("postFile")>
  Public postHistory As New List(Of String)
End Class

This is the code used to de-serialize the file:

  Public Shared Function GetLocalSettings(ByVal filePath As String) As LocalSettings
    Dim lSettings As New LocalSettings()

    Try
      Dim xs As New XmlSerializer(GetType(LocalSettings))
      Using fs As New FileStream(filePath, FileMode.Open)
        lSettings = xs.Deserialize(fs)
      End Using
    Catch ex As Exception
      ' Handle exception
    End Try

    Return lSettings
  End Function

This solution works but feels awkward. Is there a more optimal way to de-serialize that doesn't require nesting the 'postHistory' list within two sub-classes?

You can use XmlArrayAttribute(string name) to specify that a list should be serialized in two levels, with the outer container element having the specified name. Then you can use XmlArrayItemAttribute(string name) to specify the inner element name.

Thus:

<XmlRoot("configuration")>
Public Class LocalSettings
  <XmlElement("appSettings")>
  Public appSettings As New postHistory()
  Public SettingsPath As String = ""
End Class

Public Class postHistory
  <XmlArray("postHistory")>
  <XmlArrayItem("postFile")>
  Public postHistory As New List(Of String)
End Class

This allows the SubSettings class to be eliminated.

Sample fiddle .

For more information see Controlling XML Serialization Using Attributes .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM