如何将C#反序列化与分层类结构结合使用
我正在尝试将一些xml文件反序列化为一些类,这些类已简化为以下内容:如何将C#反序列化与分层类结构结合使用,c#,class,serialization,hierarchy,C#,Class,Serialization,Hierarchy,我正在尝试将一些xml文件反序列化为一些类,这些类已简化为以下内容: [XmlRoot("person")] [Serializable] public class Person { [XmlElement] public Toy Toy { get; set; } } [Serializable] public class ActionMan : Toy { [XmlElement("guns")] public string Guns; } [Serial
[XmlRoot("person")]
[Serializable]
public class Person
{
[XmlElement]
public Toy Toy { get; set; }
}
[Serializable]
public class ActionMan : Toy
{
[XmlElement("guns")]
public string Guns;
}
[Serializable]
public class Doll : Toy
{
[XmlElement("name")]
public String Name;
}
[XmlInclude(typeof(Doll))]
[XmlInclude(typeof(ActionMan))]
public class Toy
{
}
[TestFixture]
public class ToyTest
{
[Test]
public void testHierarchy()
{
String filePath = @"test\brother.xml";
String sisfilePath = @"test\sister.xml";
var serializer = new XmlSerializer(typeof(Person));
Person brother = (Person)serializer.Deserialize(new FileStream(filePath, FileMode.Open));
Person sister = (Person)serializer.Deserialize(new FileStream(sisfilePath, FileMode.Open));
Assert.IsNotNull(brother);
Assert.IsNotNull(sister);
Assert.IsAssignableFrom(typeof(ActionMan),brother.Toy);
Assert.IsAssignableFrom(typeof(Doll),sister.Toy);
}
}
我想使用c#序列化(我知道我可以使用我自己的反序列化程序),我想我可能只是缺少了一个我不知道的特定标记(我肯定我有多余的标记)
以下是一个xml文件:
<person>
<doll>
<name>Jill</name>
</doll>
</person>
吉尔
我在第三个断言中得到的错误是“Expected:assignable from”,person应该包含一个“doll”属性而不是“Toy”属性,我指的是名称。XML节点必须与属性名称具有相同的名称-大小写很重要 当我尝试序列化您的结构(将ActionMan作为玩具的人)时,我得到了
我想这就是处理类型继承的方法。
但是我想您无法更改已经序列化的XML。请尝试以下方法
public class Person
{
public Toy toy
{
get
{
return (doll == null) ? (Toy)actionMan : (Toy)doll;
}
}
public Doll doll;
public ActionMan actionMan;
}
public class Toy
{
}
public class Doll : Toy
{
public String name;
}
public class ActionMan : Toy
{
public String guns;
}
class Program
{
static void Main(string[] args)
{
Person brother = new Person();
ActionMan am = new ActionMan();
am.guns = "Laser Beam";
brother.actionMan = am;
Person sister = new Person();
Doll d = new Doll();
d.name = "Jill";
sister.doll = d;
Serialize(brother, "brother.xml");
Serialize(sister, "sister.xml");
Person b = Deserialize("brother.xml");
Person s = Deserialize("sister.xml");
Console.WriteLine(((ActionMan)b.toy).guns);
Console.WriteLine(((Doll)s.toy).name);
Console.Read();
}
public static Person Deserialize(String filename)
{
var serializer = new XmlSerializer(typeof(Person));
return (Person)serializer.Deserialize(new FileStream(filename, FileMode.Open));
}
public static void Serialize(Person p, String filename){
Stream stream = File.Open(filename, FileMode.Create);
XmlSerializer s = new XmlSerializer(typeof(Person));
s.Serialize(stream, p);
stream.Close();
}
你可以从这里扩展。请记住,在属性名称中,大小写很重要。我得到的序列化输出是
brother.xml
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<actionMan>
<guns>Laser Beam</guns>
</actionMan>
</Person>
我所做的是按照我想要的方式设计类结构,填充一些基本数据,然后序列化它。然后检查它是如何序列化和调整Xml属性的。如果你的
Toy
类只有几个派生,那么你可以用一个action-man字段和一个doll字段分别反序列化它们,这两个字段可能是空的,也可能不是空的
或者从Xml文件转到c类,我使用xsd.exe
工具生成一个.xsd
文件,其中包含xsd mydata.Xml
,然后从该文件生成一个c类文件,其中包含xsd/c/l:cs mydata.xsd
。然后我检查类数据,以获得关于如何定义类以及使用哪些属性的线索
链接到Microsoft提供的工具。为您的架构创建xsd,然后使用xsd生成序列化程序代码。如果您修改类的源代码,则可以修改XML以外的任何内容。如果可能的话,我想使用轻量级的、标准的、最重要的是非生成代码。如果我一定要使用生成的序列化程序,那么很好,但我认为可能有一种更简单的方法我没有。你能检查一下使用Debugger加载的数据吗?很好地解释了其他人的答案。@tou-a)首先我+1另一个答案,b)我根据我的经验报告,即使它与其他人的经验相同,c)我还使用
xsd
添加了一个新想法。这里的问题到底是什么?Doll和ActionMan类都继承自Toy类。这就是为什么将其中一个实例亲自指定给toy属性是可行的。诀窍在于toy属性的get方法,以及类Person包含每种类型的变量Doll和ActionMan。
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<actionMan>
<guns>Laser Beam</guns>
</actionMan>
</Person>
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<doll>
<name>Jill</name>
</doll>
</Person>
Laser Beam
Jill