最近又开始使用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);
} // Print
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的问题的更多相关文章

  1. [.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口 IXmlSerializable 实现XML序列化 及 通用XML类

    [.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口 IXmlSerializable 实现XML序列化 及 通用XML类 本节导读:本节主要介绍通过序列 ...

  2. C# 序列化与反序列化之xml通过实现IXmlSerializable进行序列化的解决方案

    新建控制台console项目,添加XmlPersonIXmlSerializable类,和AddressIXmlSerializable类(实现IXmlSerializable)以及AddressIX ...

  3. c#序列化基类(包含派生类继承DynamicObject和 IXmlSerializable)对象

    直接上代码 using System.Diagnostics; using System.Text; using System.Xml; using System.Xml.Schema; using ...

  4. 解析大型.NET ERP系统数据访问 对象关系映射框架LLBL Gen Pro

    LLBL Gen Pro是一个为.NET开发人员设计的的对象关系映射(ORM)框架,与NHibernate,Entity Framework等框架一样,通过实体与数据表的映射,实现关系数据库持久化. ...

  5. .Net 序列化(去除默认命名空间,添加编码)

    1.序列化注意事项 (1).Net 序列化是基于对象的.所以只有实例字段呗序列化.静态字段不在序列化之中. (2)枚举永远是可序列化的. 2.XML序列化时去除默认命名空间xmlns:xsd和xmln ...

  6. NavisWorks Api 简单使用与Gantt

    相信很多朋友在做BIM项目的时候.都有客户会提出项目计划,形象进度 等需求. 那么当前最主要的问题就是计划与BIM模型的关联问题.那么我在项目中是用户用Project软件编辑计划然后手动跟三维模型关联 ...

  7. C#对象序列化与反序列化zz

      C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍........................ ...

  8. [.net 面向对象程序设计进阶] (1) 开篇

    [.net 面向对象程序设计进阶] (1) 开篇 上一系列文章<.net 面向对象编程基础>写完后,很多小伙伴们希望我有时间再写一点进阶的文章,于是有了这个系列文章.这一系列的文章中, 对 ...

  9. 在.net中读写config文件的各种方法

    阅读目录 开始 config文件 - 自定义配置节点 config文件 - Property config文件 - Element config文件 - CDATA config文件 - Collec ...

随机推荐

  1. PhpStorm中文教程

    PhpStorm中文教程 | 浏览:15972 | 更新:2014-06-10 21:14 1 2 3 4 5 分步阅读 PhpStorm是一款强大的IDE,非常适合于PHP开发人员及前端工程师.提供 ...

  2. ICON文件保存

    这两天想做一下windows系统下图标的修改,让程序有更新的时候能够更新图标的外观,达到提醒的作用,360,QQ经常采用这种方式进行更新的提示,也有采用弹框的方式来提示,用新版QVOD的同事可能见到过 ...

  3. PHP 中获取当前时间[Datetime Now]

    在 PHP 中可以通过date()获取当前时间,在>5.2的版本中最好还是用 datetime 类型 date() <?php echo date('Y-m-d H:i:s'); ?> ...

  4. subclipse安装后从svn资源库视图check out的资源无法创建server

    不要从根目录下check out,只要把根目录下所需要的项目check out即可.

  5. laravel paginate动态分页

    1.router Route::get('product', function(){ $products = App\Product::paginate(10); return view('produ ...

  6. Subset sum problem

    https://en.wikipedia.org/wiki/Subset_sum_problem In computer science, the subset sum problem is an i ...

  7. JS初学者必备的几个经典案例(一)!!!

    一:选中复选框按钮可用    和     倒计时10秒后按钮可用 这是倒计时10秒后按钮可用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...

  8. ajax普通弹窗;Bootstrp弹窗

    1.普通弹窗 主页面: <head> <meta http-equiv="Content-Type" content="text/html; chars ...

  9. 超简单的处理JSON格式和JSON数组格式的String

    现在网站上有不少处理JSON格式的工具类,但是我找了一天,发现大都是需要编写相应对象类来进行处理,比较麻烦,比如:Gson,json-lib.Gson,json-lib这些处理那些接口之类的参数名字和 ...

  10. 基于ace后台管理系统模板--CMS(Thinkphp框架)的筹划

    临近春节,准备自己做一个关于宠物的cms网站,特写下此博客提醒自己,尽量争取在过年前做好.废号少说,先梳理下接下来准备使用的工具.. 由于最近在学习thinkphp,所以打算用这个框架来作为主体,可能 ...