2013-10-09 49 views
0

我創建一個列表,保存爲XML(與XmlSerializer),但我沒有成功(雖然所有網絡搜索...)反序列化。XML - 無法反序列化後序列化

我的實體是:

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>(); 
    } 
}; 
+0

我沒有看到一個調用反序列化()。什麼是loadXmlIntoList()? –

+0

對不起,我忘了改變它。我現在會更新我的問題。謝謝 – AsfK

+0

添加功能。再次感謝 – AsfK

回答

1

我不是一個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); 
     } 
    } 

} 
+0

真的很感謝你!我花了幾個小時,真的非常感謝你! – AsfK

0

我覺得你就是導致您正在序列化或反序列化的屬性的get {} set {}方法丟失!

如果要在序列化中使用它們,必須將其用作屬性。有問題,如果你只用它們作爲領域沒有得到&集

+0

我加了'{get;設置;}'但它仍然不起作用。你能解釋一下你在'用它作爲屬性'時的意思嗎?謝謝。 – AsfK

+0

在你的代碼中你寫了 public class basicTxtFile { public string filename; 公共字符串描述; } 的在這方面變量是 如果您正在使用,而不是不可用作封裝屬性的字段: 公共類basicTxtFile { 公共字符串的文件名{獲得;組; }; public string description {get;組; }; } 這使得字段成爲封裝的屬性! 通常它應該與現在的序列化程序 – 2013-10-09 13:27:24

+0

一起使用,您必須添加get;組;以ALLE爲元素使用XML元素 – 2013-10-09 13:30:42