XML - 序列化后无法反序列化 [英] XML - Can not deserialize after serialize

查看:49
本文介绍了XML - 序列化后无法反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I create a list, save it as XML (with XmlSerializer) but I not success (although all web searches…) to deserialize.

我的实体是:

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.
};

在我的应用程序中,我创建了一个列表并手动填写.之后我用这个代码保存了它:

In my application I crate a list and I fill it manually. After it I saved it with this code:

//  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文件是自动生成的.

Then I try to load the xml file into list, but it's failed due to: "There is an error in XML document (2, 2)." and _innerException = " was not expected." although the xml file generate automatically.

我的加载代码是:

// 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 文件加载到列表中?

My question: What I did wrong? how can I load the xml file into the list?

谢谢!

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

The XML file (that generate automatically) looks like this:

<?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;设置;} 到实体,像这样:

Update: I also try add {get; set;} to The entities, like this:

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 专家.你想用 loadXmlIntoList() 中的 XmlRootAttribute 做什么?

I'm not an XML expert. What are you trying to do with the XmlRootAttribute in loadXmlIntoList()?

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

I've reworked it slightly so that the deserialization code looks more like its serialization counterpart:

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);
        }
    }

}

这篇关于XML - 序列化后无法反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆