【发布时间】:2015-08-21 11:43:55
【问题描述】:
我知道这是一个热门话题,我进行了广泛的研究,但没有找到问题的答案。
我有一个基类IntroductionAction 和两个派生类IntroductionActionComplex 和IntroductionActionSimple。我有一个IntroductionAction 对象列表,我已向其中添加了两种派生类型的对象。我的课程如下:
[XmlInclude(typeof(IntroductionActionComplex))]
[XmlInclude(typeof(IntroductionActionSimple))]
public class IntroductionAction
{
public IntroductionAction() { }
}
public class IntroductionActionComplex : IntroductionAction
{
[XmlIgnore]
public string name { get; set; }
[XmlElement(ElementName = "QuestionString")]
public string question { get; set; }
[XmlElement(ElementName = "AnswerString")]
public List<string> answerStrings { get; set; }
public IntroductionActionComplex()
{
name = string.Empty;
question = null;
answerStrings = new List<string>();
}
}
public class IntroductionActionSimple : IntroductionAction
{
[XmlIgnore]
public string name { get; set; }
[XmlText]
public string Value { get; set; }
public IntroductionActionSimple()
{
Value = string.Empty;
}
}
然后我按如下方式创建列表
[XmlElement("IntroductionAction")]
public List<IntroductionAction> introductionActions { get; set; }
我正在使用XmlSerializer 并且所有内容都正确序列化。这是包含正确派生类之一的列表的结果 XML。
<IntroductionAction>
<QuestionString>
test
</QuestionString>
<AnswerString>
test
</AnswerString>
<AnswerString>
test
</AnswerString>
</IntroductionAction>
<IntroductionAction>
test
</IntroductionAction>
此 XML 文件将进入设备,该设备不会将其读取为 XML,而只是搜索标签并执行它需要做的任何工作,因此该文件不能包含任何 XSI 或 XSD 标签,缩进等通常与适当的 XML 相关联。
我的反序列化代码很简单:
public static T Deserialize_xml_Config<T>(string file1, T obj)
{
XmlSerializer deserializer = new XmlSerializer(obj.GetType());
using (TextReader reader = new StreamReader(file1))
{
return (T)deserializer.Deserialize(reader);
}
}
最后是我的问题。当我反序列化时,它被反序列化为基类IntroductionAction,而不是派生类。
这些IntroductionAction 类只是我正在序列化/反序列化的更大对象的一部分。我尝试将基类抽象化,因为它不包含任何功能,但是在反序列化时出现错误提示
指定的类型是抽象的:name='IntroductionAction'
尽管我的 XmlIncludes 似乎无法找到派生类。
我尝试将类型添加到序列化程序,但没有奏效。
非常感谢任何帮助。
编辑: 这就是我将类型添加到序列化程序的意思
XmlSerializer deserializer = new XmlSerializer(obj.GetType(), new Type [] { typeof(IntroductionActionComplex), typeof(IntroductionActionSimple) });
using (TextReader reader = new StreamReader(file1))
{
return (T)deserializer.Deserialize(reader);
}
我也尝试使用XmlAttributeOverrides:
XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();
var attrs = new XmlAttributes();
XmlElementAttribute attr = new XmlElementAttribute();
attr.ElementName = "IntroductionAction";
attr.Type = typeof(IntroductionActionComplex);
attrs.XmlElements.Add(attr);
attr.ElementName = "IntroductionAction";
attr.Type = typeof(IntroductionActionSimple);
attrs.XmlElements.Add(attr);
attrOverrides.Add(typeof(IntroductionAction), "IntroductionAction", attrs);
XmlSerializer deserializer = new XmlSerializer(obj.GetType(), attrOverrides);
using (TextReader reader = new StreamReader(file1))
{
return (T)deserializer.Deserialize(reader);
}
【问题讨论】:
-
在每个类上方添加一个 [XmlRoot(ElementName = "......")] 与实际标签名称(区分大小写)以指定您想要每个标签的类进入。
-
你能发布你为
I have tried adding the types to the serializer but that didnt work所做的事情吗?我相信你需要覆盖 xml 属性,但我想看看你先做了什么。 -
@jdweng 很确定这不会起作用,因为两个派生对象必须使用相同的标签名称,即
-
您的 XML 没有正确生成——每个
<IntroductionAction>元素上应该有一个xsi:type属性来指定类型,例如<IntroductionAction xsi:type="IntroductionActionComplex">。您是如何生成 XML 的?如果我用XmlSerializer序列化你的类,就会出现类型信息。 -
@dbc 我必须重写 TextWriter 以删除这些标签,因为它们不能出现在文件中。这超出了我的控制范围,这就是它必须的方式。我已经使用存在的那些类型标签对其进行了测试,并且一切正常,因此只有在删除它们时才会成为问题。
标签: c# xml xml-serialization xml-deserialization