XML - 序列化后无法反序列化

本文关键字:反序列化 序列化 XML | 更新日期: 2023-09-27 18:34:46

我创建了一个列表,将其另存为XML(使用XmlSerializer(,但我没有成功(尽管所有网络搜索...(反序列化。

我的实体是:

public class basicTxtFile
{
    public string filename;
    public string description;
}
public class fileTools
{
};
public class textboxTool : fileTools    // text box
{
    public string defaultText;
    public bool multiLine;
    public bool browseButton;
};
public class comboboxTool : fileTools   // combo box
{
    public List<string> values = new List<string>();
};
// Must file, can choose tools: textbox and'or combobox
public class mustFiles : basicTxtFile
{
    public List<fileTools> mustTools = new List<fileTools>();
};
public class OptionalFiles : mustFiles
{
    public bool exist;  // checkbox for defualt value - if the file is exist, if not.
};

在我的应用程序中,我装箱一个列表并手动填写。之后,我用以下代码保存了它:

//  Save list into XML  -   success
XmlSerializer serializer = new XmlSerializer(typeof(List<mustFiles>), new Type[] {typeof(fileTools), typeof(textboxTool), typeof(comboboxTool)});
using (FileStream stream = File.OpenWrite("MustFiles.xml"))
{
    serializer.Serialize(stream, mustTxtFiles);
}

然后我尝试将 xml 文件加载到列表中,但由于以下原因失败:">XML 文档 (2, 2( 中存在错误">和 _innerException = "不是预期的尽管 XML 文件是自动生成的。

我的加载代码是:

// Load XML file into list
List<mustFiles> mustTry = new List<mustFiles>();
mustTry = bl.loadXmlIntoList<mustFiles>("MustFiles.xml", "mustFiles");

loadXmlIntoList 函数:

public List<T> loadXmlIntoList<T>(string xmlFileName, string xmlElemnetName)
{
    XmlRootAttribute xRoot = new XmlRootAttribute();
    xRoot.ElementName = xmlElemnetName;
    xRoot.IsNullable = true;
    XmlSerializer serializer = new XmlSerializer(typeof(T), xRoot);
    using (FileStream stream = File.OpenRead(xmlFileName))
    {
        List<T> dezerializedList = (List<T>)serializer.Deserialize(stream);
        return dezerializedList;
    }
}

的问题:我做错了什么? 如何将 XML 文件加载到列表中?

谢谢!

XML 文件(自动生成(如下所示:

<?xml version="1.0"?>
<ArrayOfMustFiles xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <mustFiles>
    <filename>file1.txt</filename>
    <description>desc1</description>
    <mustTools>
      <fileTools xsi:type="textboxTool">
        <defaultText>Default text 01</defaultText>
        <multiLine>false</multiLine>
        <browseButton>false</browseButton>
      </fileTools>
    </mustTools>
  </mustFiles>
  <mustFiles>
    <filename>file2.txt</filename>
    <description>desc2</description>
    <mustTools>
      <fileTools xsi:type="textboxTool">
        <defaultText>Defualt text 02</defaultText>
        <multiLine>true</multiLine>
        <browseButton>true</browseButton>
      </fileTools>
      <fileTools xsi:type="comboboxTool">
        <values>
          <string>Val1</string>
          <string>Val2</string>
          <string>Val3</string>
        </values>
      </fileTools>
    </mustTools>
  </mustFiles>
  <mustFiles>
    <filename>file2.txt</filename>
    <description>desc2</description>
    <mustTools>
      <fileTools xsi:type="textboxTool">
        <defaultText>Defualt text 03</defaultText>
        <multiLine>false</multiLine>
        <browseButton>true</browseButton>
      </fileTools>
      <fileTools xsi:type="comboboxTool">
        <values>
          <string>ComboVal 1</string>
          <string>ComboVal  2</string>
          <string>ComboVal  3</string>
        </values>
      </fileTools>
      <fileTools xsi:type="comboboxTool">
        <values>
          <string>Second ComboVal 1</string>
          <string>Second ComboVal  2</string>
          <string>Second ComboVal  3</string>
        </values>
      </fileTools>
      <fileTools xsi:type="textboxTool">
        <defaultText>Second defualt text 03</defaultText>
        <multiLine>true</multiLine>
        <browseButton>false</browseButton>
      </fileTools>
    </mustTools>
  </mustFiles>
</ArrayOfMustFiles>

更新:我还尝试向实体添加{get; set;},如下所示:

public class basicTxtFile
{
    public string filename{ set; get; }
    public string description{ set; get; }
}
public class fileTools
{ };
public class textboxTool : fileTools
{
    public string defaultText{ set; get; }
    public bool multiLine{ set; get; }
    public bool browseButton{ set; get; }
};
public class comboboxTool : fileTools
{
    public List<string> values { set; get; }
    public comboboxTool()
    {
        values = new List<string>();
    }
};
public class mustFiles : basicTxtFile
{
    public List<fileTools> mustTools { set; get; }
    public mustFiles()
    {
        mustTools = new List<fileTools>();
    }
};

XML - 序列化后无法反序列化

我不是 XML 专家。 你想用loadXmlIntoList((中的XmlRootAttribute做什么?

我稍微修改了一下,使反序列化代码看起来更像它的序列化对应项:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        List<mustFiles> mustTxtFiles = new List<mustFiles>();
        mustFiles mf = new mustFiles();
        mf.filename = "filenameA";
        mf.description = "descriptionA";
        textboxTool tbt = new textboxTool();
        tbt.defaultText = "defaultTextA";
        tbt.browseButton = true;
        tbt.multiLine = true;
        mf.mustTools.Add(tbt);
        mustTxtFiles.Add(mf);
        mf = new mustFiles();
        mf.filename = "filenameB";
        mf.description = "descriptionB";
        tbt = new textboxTool();
        tbt.defaultText = "defaultTextB";
        tbt.browseButton = true;
        tbt.multiLine = true;
        mf.mustTools.Add(tbt);
        mustTxtFiles.Add(mf);
        // serialize it
        XmlSerializer serializer = new XmlSerializer(typeof(List<mustFiles>), new Type[] {typeof(fileTools), typeof(textboxTool), typeof(comboboxTool)});
        string xmlFile = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MustFiles.xml");
        using (System.IO.FileStream stream = File.OpenWrite(xmlFile))
        {
            serializer.Serialize(stream, mustTxtFiles);
        }
        // Why not just this?
        // deserialize it 
        //List<mustFiles> mustTry;
        //using (FileStream stream = File.OpenRead(xmlFile))
        //{
        //    mustTry = (List<mustFiles>)serializer.Deserialize(stream);
        //}
        // deserialize it with generic function:
        List<mustFiles> mustTry = loadXml<List<mustFiles>>(xmlFile, new Type[] { typeof(fileTools), typeof(textboxTool), typeof(comboboxTool) });
    }
    public T loadXml<T>(string xmlFileName, Type[] additionalTypes)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T), additionalTypes);
        using (FileStream stream = File.OpenRead(xmlFileName))
        {
            return (T)serializer.Deserialize(stream);
        }
    }
}

我认为您的原因是缺少您正在序列化或反序列化的属性的 get{} set{} 方法!

如果要在序列化中使用它们,则必须将其用作属性。 如果您仅将它们用作字段而不使用 get & set 就会出现问题