.NET(C#):XML序列化时派生类的处理
原文 www.cnblogs.com/mgen/archive/2011/12/03/2275014.html
注意:
运行代码请注意添加如下命名空间:
using System.Xml;
using System.Xml.Serialization;
using System.IO;
1. 针对基类的XmlSerializer序列化派生类
派生类将会序列化成这样的XML:
<基类名称xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xsi:type="派生类名称">
<!-- 基类和派生类的内容 -->
</基类名称>
第一种方法是在基类添加XmlInclude特性,这样的话基类的XmlSerializer可以序列化派生类了。
代码:
//基类加入XmlInclude
[XmlInclude(typeof(b))]
publicclassa
{
publicint aaa;
}
publicclassb : a
{
publicint bbb;
}
classProgram
{
staticvoid Main()
{
var xs =newXmlSerializer(typeof(a));
using (var textWriter =newStringWriter())
{
xs.Serialize(textWriter, newb());
Console.WriteLine(textWriter);
}
}
}
输出XML:
<axmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xsi:type="b">
</aaa>
</bbb>
</a>
第二种方法就是在XmlSerializer的构造函数内指定派生类型,然后序列化,这样就不用在基类上加入XmlInclude特性了。
代码:
//无需加入XmlInclude
publicclassa
{
publicint aaa;
}
publicclassb : a
{
publicint bbb;
}
classProgram
{
staticvoid Main()
{
var xs =newXmlSerializer(typeof(a), newType[] { typeof(b) });
using (var textWriter =newStringWriter())
{
xs.Serialize(textWriter, newb());
Console.WriteLine(textWriter);
}
}
}
输出和上面一样!
2. 类内成员是派生类的序列化
还是上面的类a和b,现在再加入一个c类,这个c类中有一个a的对象:
publicclassa
{
publicint aaa;
}
publicclassb : a
{
publicint bbb;
}
publicclassc
{
publica objA =newa();
}
此时直接XML序列化一个c对象,结果是这样的XML:
<cxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<objA>
</aaa>
</objA>
</c>
下面搞得复杂些,把c中的a对象改成这样:
publicclassc
{
publica objA =newb();
}
此时仿佛又回到了文章第一个标题,如果直接序列化c的话,会抛出异常。那么按照上面第一个方法,先在a上加入XmlInclude特性,然后再序列化c对象。
全部代码:
[XmlInclude(typeof(b))]
publicclassa
{
publicint aaa;
}
publicclassb : a
{
publicint bbb;
}
publicclassc
{
publica objA =newb();
}
classProgram
{
staticvoid Main()
{
var xs =newXmlSerializer(typeof(c));
using (var textWriter =newStringWriter())
{
xs.Serialize(textWriter, newc());
Console.WriteLine(textWriter);
}
}
}
输出XML(根节点c省略):
<objAxsi:type="b">
</aaa>
</bbb>
</objA>
和标题1的第一个方法类似!
但是标题1的第二个方法在这里没法使用的,因为c类和b类没有任何继承关系,在针对c的XmlSerializer不可能加入b的类型。这里其实还 有一种方法,加入XmlElement特性,其中ElementName属性是最终的Xml元素名称,而Type属性是针对的类型,这里加入b类型,不过 最好把a类型也加入(因为字段类型是a,有可能被赋值为a的对象)。
全部代码:
//不需要加XmlInclude
publicclassa
{
publicint aaa;
}
publicclassb : a
{
publicint bbb;
}
publicclassc
{
[XmlElement(ElementName ="b", Type =typeof(b))]
[XmlElement(ElementName ="a", Type =typeof(a))]
publica objA =newb();
}
classProgram
{
staticvoid Main()
{
var xs =newXmlSerializer(typeof(c));
using (var textWriter =newStringWriter())
{
xs.Serialize(textWriter, newc());
Console.WriteLine(textWriter);
}
}
}
生成XML:
<cxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<b>
</aaa>
</bbb>
</b>
</c>
作者:Mgen
出处:www.cnblogs.com/mgen
.NET(C#):XML序列化时派生类的处理的更多相关文章
- c# 中xml序列化时相同节点存入不同类型值
先上需要序列话的类定义: [System.Xml.Serialization.XmlIncludeAttribute(typeof(DescriptionType))] [System.CodeDom ...
- XML序列化反序列化—常用类
public class XMLSerializer { #region (public) xml序列化 /// <summary> /// ...
- 在XML序列化时去除默认命名空间xmlns:xsd和xmlns:xsi
摘 自: http://blog.csdn.net/fxhflower/article/details/7276820 可使用以下代码: //Create our own namespaces for ...
- C#中将xml文件反序列化为实例时采用基类还是派生类的问题
基类: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...
- .NET中XML序列化和反序列化常用类和用来控制XML序列化的属性总结(XmlSerializer,XmlTypeAttribute,XmlElementAttribute,XmlAttributeAttribute,XmlArrayAttribute...)
序列化和反序列化是指什么? 序列化(seriallization): 将对象转化为便于传输的数据格式, 常见的序列化格式:二进制格式,字节数组,json字符串,xml字符串.反序列化(deserial ...
- 关于C# XML序列化的一个BUG的修改
关于C# XML序列化的一个BUG的修改 在我前一篇博客中提到用XML序列化作为数据库的一个方案,@拿笔小心 提到他们在用XML序列化时,遇到了一个比较严重的bug,即XML不闭合,系统不能正确的加载 ...
- Windows phone 之XML序列化与反序列化
为什么要做序列化和反序列化? 一个回答: 我们都知道对象是不能在网络中直接传输的,不过还有补救的办法.XML(Extensible Markup Language)可扩展标记语言,本身就被设计用来存储 ...
- C#操作Xml:XmlSerializer 对象的Xml序列化和反序列化
这篇随笔对应的.Net命名空间是System.Xml.Serialization:文中的示例代码需要引用这个命名空间. 为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中:内存中的对 ...
- Xml 序列化
1 XML序列化只能序列化对象的公有属性,并且要求对象有一个无参的构造方法,否者无法反序列化. 2 [Serializable]和[NonSerialized]特性对XML序列化无效!所以使用XML序 ...
随机推荐
- c/c++:内存泄露和野指针的概念
内存泄漏 用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元.直到程序结束.即所谓内存泄漏. 注意:内存泄漏是指堆内存的泄漏. 简单的说就是申请了一块内存空间,使用 ...
- 如何在IE8下调试OCX控件
第一种方式 多进程模式下, 在IE8打开web页面, 然后在调试菜单选择附加到进程, 这时看到2个IE进程, 选择没有带标题的, 也就是主进程, 就可以正常调试了. 此方式比较麻烦, 不能F5直接启动 ...
- Android 开发ListView适配器优化
我们都知道Android中Adapter的作用就是ListView界面与数据之间的桥梁,当列表里的每一项显示到页面时,都会调用Adapter的getView方法返回一个View.想过没有? 在我们的列 ...
- PostgreSQL的存储系统二:REDOLOG文件存储结构二
REDOLOG文件里的用户数据和数据文件里的用户数据存储结构相同 几个月前同事给台湾一家公司培训<pg9 ad admin>时,有个学员提及WAL里记录的内容为Query时的SQL语句(比 ...
- Largest Submatrix(动态规划)
Largest Submatrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- hdu 2102 A计划(双层BFS)(具体解释)
转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm.hdu.edu.cn/showproblem.php ...
- struts2中从数据库中读取数据,并在JSP页面中遍历保存有JavaBean对象的List对象
0x1:前言 前面搭建struts就不说了,大家都能成功完毕. 0x2:Model 这里我们须要一个Model类来接收 <span style="font-size:10px;font ...
- 基于eclipse的mybatis映射代码自动生成的插件
基于eclipse的mybatis映射代码自动生成的插件 分类: JAVA 数据库 工具相关2012-04-29 00:15 2157人阅读 评论(9) 收藏 举报 eclipsegeneratori ...
- IOS开发环境更换后重新制作Provisioning Profile证书详解
新换了台Macbook,又折腾了一遍Provisioning Profile证书,苹果的证书繁锁复杂,每次制作都相当麻烦,而且Provisioning Profile证书是与设备绑定的,所以更换开发环 ...
- mvc下载文件
MVC下载文件方式 方式一: public FileStreamResult DownFile(string filePath, string fileName) { string ab ...