【问题标题】:XML Error, 'Data at the root level is invalid'XML 错误,“根级别的数据无效”
【发布时间】:2020-04-23 22:32:12
【问题描述】:

我在 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

但是当我试图读回它时,我得到了错误:

根级别的数据无效。第 X 行,位置 17

对应于/ArrayOfPlayer之后和System.Xml的开头...等。

据我所知,查看 xml 的其他示例,最终的 System.Xml.Serialization.XmlSerializer 不应该存在并且似乎导致了问题,但我无法从我的代码中找出为什么它被附加在结尾。我正在尝试使用完全空白的文件,所以它与以前的写入无关。

代码取自不同的地方,所以有点混搭,因为我一直在努力研究如何序列化/反序列化对象列表。

我的班级在一个单独的文件中,如下所示:

<Serializable>
Public Class Player
    Public Property Name As String
    Public Property Control As Integer
    Public Property Tackling As Integer
    Public Property Passing As Integer
    Public Property Heading As Integer
    Public Property Shooting As Integer
    Public Property Speed As Integer
    Public Property Age As Integer

End Class

【问题讨论】:

    标签: xml vb.net winforms serialization


    【解决方案1】:

    你不需要:

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

    错误:

    file.WriteLine(ser)
    

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

    在这里,我用Using 声明声明了一个新的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
    

    【讨论】:

    • 太好了,谢谢。完美运行。接受为正确答案:)
    猜你喜欢
    • 2014-01-17
    • 2015-11-05
    • 1970-01-01
    • 2019-12-15
    • 2011-01-21
    • 2023-03-23
    • 1970-01-01
    相关资源
    最近更新 更多