XML错误&x27;根级别的数据无效';

XML错误&x27;根级别的数据无效';,xml,vb.net,winforms,serialization,Xml,Vb.net,Winforms,Serialization,我正在Windows窗体项目中使用以下代码将对象列表保存为XML SaveFileDialog1.ShowDialog() Dim Path = SaveFileDialog1.FileName Dim file As StreamWriter System.IO.File.WriteAllText(Path, "") file = My.Computer.FileSystem.OpenTextFileWriter(Path, False) Dim ser As New XmlSerialize

我正在Windows窗体项目中使用以下代码将对象列表保存为XML

SaveFileDialog1.ShowDialog()
Dim Path = SaveFileDialog1.FileName
Dim file As StreamWriter
System.IO.File.WriteAllText(Path, "")
file = My.Computer.FileSystem.OpenTextFileWriter(Path, False)
Dim ser As New XmlSerializer(GetType(List(Of Player)))
ser.Serialize(file, PlayerList)
file.WriteLine(ser)
file.Close()
并通过以下方式重新阅读:

OpenFileDialog1.ShowDialog()
Dim Path = OpenFileDialog1.FileName
Dim reader As New System.Xml.Serialization.XmlSerializer(GetType(List(Of Player)))
Dim filereader As New System.IO.StreamReader(Path)
PlayerList = reader.Deserialize(filereader)
文件看起来是正确的,下面是当列表中有两个对象时显示的内容:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfPlayer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Player>
    <Name>Kennedy Igboananike</Name>
    <Control>999</Control>
    <Tackling>999</Tackling>
    <Passing>999</Passing>
    <Heading>999</Heading>
    <Shooting>1000</Shooting>
    <Speed>731</Speed>
    <Age>30</Age>
  </Player>
  <Player>
    <Name>Dean Wormall</Name>
    <Control>408</Control>
    <Tackling>390</Tackling>
    <Passing>579</Passing>
    <Heading>428</Heading>
    <Shooting>449</Shooting>
    <Speed>719</Speed>
    <Age>17</Age>
  </Player>
</ArrayOfPlayer>System.Xml.Serialization.XmlSerializer
您不需要:

System.IO.File.WriteAllText(Path, "")
My.Computer.FileSystem.OpenTextFileWriter(Path, False)
  • 如果要覆盖现有数据,将
    false
    指定为append参数就足够了
  • 您不需要
    OpenTextFileWriter
    ,只需将所选文件路径传递给
    StreamReader
    构造函数即可
错误:

file.WriteLine(ser)
这将
ser
System.Xml.Serialization.XmlSerializer
)的类型写入文件末尾。你不会想要的

在这里,我用一条语句声明了一个新的
SaveFileDialog()
(我没有使用
SaveFileDialog
组件,只是类对象-您不需要UI组件来打开对话框),因此它将在
using
块中的代码完成后立即处理。
这同样适用于StreamWriter:当其当前操作完成时,将对其进行处理并刷新流:

Using sfd As New SaveFileDialog()
    sfd.Filter = "XML Files|*.xml"
    sfd.RestoreDirectory = True
    If sfd.ShowDialog() = DialogResult.OK Then
        Using writer As New StreamWriter(sfd.FileName, False)
            Dim ser As New XmlSerializer(GetType(List(Of Player)))
            ser.Serialize(writer, PlayerList)
        End Using
    End If
End Using
要将其读回,请执行相反的操作:
之所以使用DirectCast,是因为
XmlSerializer.Deserialize
返回对象类型

Dim PlayerList As New List(Of Player)
Using ofd As New OpenFileDialog()
    ofd.Filter = "XML Files|*.xml"
    ofd.RestoreDirectory = True
    If ofd.ShowDialog() = DialogResult.OK Then
        Dim serializer As New XmlSerializer(GetType(List(Of Player)))
        Using reader As New StreamReader(ofd.FileName)
            PlayerList = DirectCast(serializer.Deserialize(reader), List(Of Player))
        End Using
    End If
End Using

太好了,谢谢。工作完美。被接受为正确答案:)
Dim PlayerList As New List(Of Player)
Using ofd As New OpenFileDialog()
    ofd.Filter = "XML Files|*.xml"
    ofd.RestoreDirectory = True
    If ofd.ShowDialog() = DialogResult.OK Then
        Dim serializer As New XmlSerializer(GetType(List(Of Player)))
        Using reader As New StreamReader(ofd.FileName)
            PlayerList = DirectCast(serializer.Deserialize(reader), List(Of Player))
        End Using
    End If
End Using