我不能为我的生活找出为什么我无法将我的XML反序列化为类实例。请参阅下面我尝试的两种方法(及其各自的错误消息)。
方法一:
public static SkillCollection Deserialize(string path)
{
using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(Path.Combine(path, "Skills.xml"))))
{
SkillCollection skills = null;
try
{
var serializer = new DataContractSerializer(typeof(SkillCollection));
var reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8, new XmlDictionaryReaderQuotas(), null);
skills = (SkillCollection)serializer.ReadObject(memoryStream);
}
catch (SerializationException ex)
{
Globals.Instance.ApplicationLogger.Log("The object graph could not be deserialized from the binary stream because of the following error: " + ex);
}
return skills;
}
}
这样称呼: Skills = SkillCollection.Deserialize(path);
错误: XmlException was thrown: UnexpectedEndOfFile
方法二:
public static object Deserialize(string xml, Type toType)
{
Console.WriteLine("File exists? " + File.Exists(xml));
using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8, new XmlDictionaryReaderQuotas(), null);
DataContractSerializer serializer = new DataContractSerializer(toType);
return serializer.ReadObject(reader);
}
}
这样称呼: Skills = (SkillCollection) SkillCollection.Deserialize(Path.Combine(path, "Skills.xml"), typeof(SkillCollection));
错误1: XmlException was thrown: "The data at the root level is invalid. Line 1, position 1."
错误2: SerializationException was thrown: "There was an error deserializing the object of type MagBot_FFXIV.SkillCollection. The data at the root level is invalid. Line 1, position 1."
我的XML:
<Skills>
<Fire>
<Cast>0.00</Cast>
<ReCast>60.00</ReCast>
<MPCost>0</MPCost>
<Button>0</Button>
</Fire>
<Ice>
<Cast>2.49</Cast>
<ReCast>2.49</ReCast>
<MPCost>9</MPCost>
<Button>1</Button>
</Ice>
</Skills>
万分感谢您的帮助。
更新
之前我曾经使用LINQ2XML,但在我的情况下它并没有帮助。请参阅我今天早些时候发布的这篇文章:XML to Dictionary to Instances of Custom Class
我的最终代码如下。完美运作,希望它能帮助其他人。
public static object DataContractSerializer_Deserialize(string path, Type toType)
{
using (var sr = new FileStream(path, FileMode.Open))
{
SkillCollection p = null;
var serializer = new DataContractSerializer(toType);
var reader = XmlDictionaryReader.CreateTextReader(sr, new XmlDictionaryReaderQuotas());
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (serializer.IsStartObject(reader))
{
Console.WriteLine(@"Found the element");
p = (SkillCollection)serializer.ReadObject(reader);
}
Console.WriteLine(reader.Name);
break;
}
}
return p;
}
}
备注:
答案 0 :(得分:1)
你的两种方法都有一个基本但很容易修复的bug。
在方法1中,行:
new MemoryStream(Encoding.UTF8.GetBytes(Path.Combine(path, "Skills.xml")))
错误,因为内存流接收文件的 PATH 的字节表示, 而是它的实际内容。
在method2中,我猜它的错误相同,但是参数名称&#34; xml&#34;是误导。但是,由于您首先使用xml检查文件是否存在,我认为它还意味着文件的 PATH ,而不是其内容。
请改为尝试:
new MemoryStream(Encoding.UTF8.GetBytes(File.ReadAllText(Path.Combine(path, "Skills.xml"))))
假设DataContractSerializer的实际文件内容格式正确, 应该 工作。如果它没有,我会建议您首先序列化一个实时的SkillsCollection对象并查看它的外观,并以此为出发点。