使用IXmlSerializable的问题
最近又开始使用XML了,但今天遇到一个折腾我一下午加一个晚上的时间,终于从网络上找到相关的资料解决了。
有一个成员是用来存放正则表达式的,由于里面包含其它字符,所以想用CDATA来保存方便查看,所以想到另建一个类再通过继承IXmlSerializable 接口来实现CDATA节点。参照了官方MSDN文档,写了类似以下的代码:
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using System.Diagnostics; namespace BeiBei.Core.Tests
{
[XmlRoot("Worker")]
public class Worker
{
[XmlElement]
public string JobTitle { get; set; } [XmlAttribute("active")]
public bool Active { get; set; } [XmlElement]
public string NextPageEncodingName { get; set; } [XmlElement]
public Person Person { get; set; } [XmlElement]
public Person Person2 { get; set; } } public class Person : IXmlSerializable
{
// Private state
private string personName; // Constructors
public Person(string name)
{
personName = name;
} public Person()
{
personName = null;
} // Xml Serialization Infrastructure
public void WriteXml(XmlWriter writer)
{
writer.WriteString(personName);
} public void ReadXml(XmlReader reader)
{
personName = reader.ReadString();
} public XmlSchema GetSchema()
{
return (null);
public override string ToString()
{
return (personName);
} } [TestClass]
public class IXmlSerializableTests
{
[TestMethod]
public void S_Person_Test()
{
var p = new Person("Shawn"); XmlSerializer serializer = new XmlSerializer(typeof(Person)); string path = "D:\\Test.Person.xml";
string path2 = "D:\\Test.Person.2.xml"; using (var writer = XmlWriter.Create(path))
{
serializer.Serialize(writer, p);
} using (var reader = XmlReader.Create(path))
{
var p2 = serializer.Deserialize(reader) as Person; using (var writer2 = XmlWriter.Create(path2))
{
serializer.Serialize(writer2, p2);
}
} var xml1 = File.ReadAllText(path);
var xml2 = File.ReadAllText(path2);
Assert.AreEqual(xml1, xml2);
Debug.WriteLine(xml2);
} [TestMethod]
public void S_Worker_Test()
{
var p = new Person("Shawn");
var pp = new Person("John"); var w = new Worker()
{
JobTitle = "Boss",
Person = p,
Person2 = pp,
NextPageEncodingName = "gb2312",
}; XmlSerializer serializer = new XmlSerializer(typeof(Worker)); string path = "D:\\Test.Worker.xml";
string path2 = "D:\\Test.Worker.2.xml"; using (var writer = XmlWriter.Create(path))
{
serializer.Serialize(writer, w);
} using (var reader = XmlReader.Create(path))
{
var w2 = serializer.Deserialize(reader) as Worker; using (var writer2 = XmlWriter.Create(path2))
{
serializer.Serialize(writer2, w2);
}
} var xml1 = File.ReadAllText(path);
var xml2 = File.ReadAllText(path2); Debug.WriteLine(xml2);
Assert.AreEqual(xml1, xml2);
}
}
}
结果Serialize出来的文件是正常的,但Deserialize后文件中,第一个Person之后的其它属性都没有了。
尝试了很多次,当个PERSON对象序列化/反序列化都是没有问题的,但当对象包括PERSON,且PERSON属性后还定义了其它的属性,尝试添加<XmlElement>之类的特性都没用。结论就是:第一个PERSON属性之后的其它属性一率都没能正常Deserialize。怪自己对这块不了解,更怪MSDN没有写好例子!
后来在这里找到答案:
http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly
其实跟属性顺序没有关系,而是我们没有把ReadXml的实现正确地实现了。再改成如下就正常了:
public void ReadXml(XmlReader reader)
{
reader.MoveToContent();
var isEmptyElement = reader.IsEmptyElement;
reader.ReadStartElement(); if (!isEmptyElement)
{
personName = reader.ReadString();
reader.ReadEndElement();
}
}
终于搞定了,终于可以继续后面的任务!刚过了十二点!
使用IXmlSerializable的问题的更多相关文章
- [.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口 IXmlSerializable 实现XML序列化 及 通用XML类
[.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口 IXmlSerializable 实现XML序列化 及 通用XML类 本节导读:本节主要介绍通过序列 ...
- C# 序列化与反序列化之xml通过实现IXmlSerializable进行序列化的解决方案
新建控制台console项目,添加XmlPersonIXmlSerializable类,和AddressIXmlSerializable类(实现IXmlSerializable)以及AddressIX ...
- c#序列化基类(包含派生类继承DynamicObject和 IXmlSerializable)对象
直接上代码 using System.Diagnostics; using System.Text; using System.Xml; using System.Xml.Schema; using ...
- 解析大型.NET ERP系统数据访问 对象关系映射框架LLBL Gen Pro
LLBL Gen Pro是一个为.NET开发人员设计的的对象关系映射(ORM)框架,与NHibernate,Entity Framework等框架一样,通过实体与数据表的映射,实现关系数据库持久化. ...
- .Net 序列化(去除默认命名空间,添加编码)
1.序列化注意事项 (1).Net 序列化是基于对象的.所以只有实例字段呗序列化.静态字段不在序列化之中. (2)枚举永远是可序列化的. 2.XML序列化时去除默认命名空间xmlns:xsd和xmln ...
- NavisWorks Api 简单使用与Gantt
相信很多朋友在做BIM项目的时候.都有客户会提出项目计划,形象进度 等需求. 那么当前最主要的问题就是计划与BIM模型的关联问题.那么我在项目中是用户用Project软件编辑计划然后手动跟三维模型关联 ...
- C#对象序列化与反序列化zz
C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍........................ ...
- [.net 面向对象程序设计进阶] (1) 开篇
[.net 面向对象程序设计进阶] (1) 开篇 上一系列文章<.net 面向对象编程基础>写完后,很多小伙伴们希望我有时间再写一点进阶的文章,于是有了这个系列文章.这一系列的文章中, 对 ...
- 在.net中读写config文件的各种方法
阅读目录 开始 config文件 - 自定义配置节点 config文件 - Property config文件 - Element config文件 - CDATA config文件 - Collec ...
随机推荐
- DS实验题 最大最小
题目: 算法设计: 计算最小值算法: 设置一个flag,flag为1的时候代表遇到*号: 遇到数字时: flag为0进栈: flag为1的时候,从栈顶提出一个元素和当前元素运算,结果进栈 最后对栈进行 ...
- mobile cpu上禁用alpha test的相关总结
因为,每家芯片的特性不同,根据向framebuffer写法的不同,分为tile-based的mobile cpu,如ImgTec PowerVR,ARM Mali,一部分老版本Qualcomm ...
- 用thinkphp进行微信开发的整体设计思考
用thinkphp进行微信开发的整体设计思考 http://www.2cto.com/weixin/201504/388423.html 2015-04-09 0个评论 作者:明 ...
- jQuery 利用 $.getJson() 实现跨域
数据量不大时,跨域的不二之选,而且操作简单,易上手. a.com/test.html //这里我假定有一些数据: var formData = form.serialize(); //这里的jsonc ...
- Bootstrap页面布局10 - BS代码
网页中标记代码内容使用code和pre标签 要在HTML中显示标签本来的样子需要转化为实体 在此附上百度的实体字符:http://baike.baidu.com/view/4757776.htm#3 ...
- 去除字符串中空格的方法(2016.1.12P141-2)
// forif来处理空格 // 方法一 String str = " ww sse rr"; String str1;// 定义一个中间变量 String str2 = &quo ...
- Linq&Lumbda (2)
"Lambda表达式"是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式树类型. Lambda 运算符: => 该运算符读为"goes to&quo ...
- zepto源码--插入节点--学习笔记
与生成width和height使用的方法类似,通过`after`, `prepend`, `before`, `append`,这四者之间的共性,生成对应的函数.并根据这四个函数,生成 `insert ...
- ADO.NET中主要对象
ADO.NET是什么? ADO.NET是.Net平台提供和数据库交互的类库集,我们可以通过它对SQLSERVER,XML,Oracle等这样的数据源进行访问. 应用程序可以使用ADO.NET链接到数据 ...
- .Net程序员安卓学习之路1:登陆界面
任何编程学习起步均是HelloWorld,作为稍有>net编程经验的我们来说就跳过这步吧,咱们且从简单登录界面开始.先看看效果: 一.准备知识: 1. 安卓环境:安装好JDK,直接去官网下载AD ...