Windows phone 之XML序列化与反序列化
为什么要做序列化和反序列化?
一个回答:
我们都知道对象是不能在网络中直接传输的,不过还有补救的办法。XML(Extensible Markup Language)可扩展标记语言,本身就被设计用来存储数据,任何一个对象都可以用XML来描述。XML是可以作为对象信息的载体在网络中传输,因为它是文本形式的。
怎么进行XML文档与对象的相互转换呢?
XmlSerializer类就是干这个活的。
命名空间:System.Xml.Serialization
程序集:System.Xml(在 system.xml.dll 中)
现在这里展示了一个提供序列化与反序列化方法的EncodeHelper类(在文章最后,并且会讲解如何使用)。
Deserialize方法将XML字符串转换为指定类型的对象;(反序列化)
Serialize方法则将对象转换为XML字符串。(序列化)
另一个回答:
class Program
{
static void Main(string[] args)
{
;
//声明Xml序列化对象实例serializer
XmlSerializer serializer = new XmlSerializer(typeof(int));
//执行序列化并将序列化结果输出到控制台
serializer.Serialize(Console.Out, i);
Console.Read();
}
}
上面代码对int i进行了序列化,并将序列化的结果输出到了控制台,输出结果如下:
<?xml version="1.0" encoding="gb2312"?> <</int>
可以将上述序列化的xml进行反序列化,如下代码:
static void Main(string[] args)
{
using (StringReader rdr = new StringReader(@"<?xml version=""1.0"" encoding=""gb2312""?>
<int>10</int>"))
{
//声明序列化对象实例serializer
XmlSerializer serializer = new XmlSerializer(typeof(int));
//反序列化,并将反序列化结果值赋给变量i
int i = (int)serializer.Deserialize(rdr);
//输出反序列化结果
Console.WriteLine("i = " + i);
Console.Read();
}
}
以上代码用最简单的方式说明了xml序列化和反序列化的过程,.Net系统类库为我们做了大量的工作,序列化和反序列化都非常简单。但是在现实中业务需求往往比较复杂,不可能只简单的序列化一个int变量,显示中我们需要对复杂类型进行可控制的序列化。
[XmlRoot("cat")]
//要求不序列化Speed属性[XmlIgnore][XmlAttribute][XmlElement]
可以使用XmlElement指定属性序列化为子节点(默认情况会序列化为子节点);或者使用XmlAttribute特性制定属性序列化为Xml节点的属性;还可以通过XmlIgnore特性修饰要求序列化程序不序列化修饰属性。
一、序列化对象
首先我们先定义实体类:
public class People
{
//XmlAttribute:指定XmlSerializer将该类成员序列化为XML属性
[XmlAttribute]
public string Name { get; set; }
[XmlAttribute]
public int Age { get; set; }
}
[XmlRoot]
public class Student : People
{
//定义SClass属性的序列化为Student节点的属性 [XmlElement]
public string SClass { get; set; }
[XmlElement]
public int Number { get; set; }
}
第一步:将实体类序列化为XML文档,代码如下:
Student stu = , Number = , Name = "张三", SClass = "高一(2)班" }; XmlSerializer ser = new XmlSerializer(typeof(Student)); StringWriter writer = new StringWriter(); ser.Serialize(writer,stu); MessageBox.Show(writer.ToString());
在弹出框,出现的结果是:

这样,我们就序列化成功了啊。。
第二步:现在我们来进行反序列化测试:
//将Xml反序列为Student对象 StringReader reader = new StringReader(writer.ToString()); //Deserialize反序列化指定TextReader包含的Xml文档,当然,不仅仅可以是TextReader,还可以是Stream等等,具体看起构造函数参数即可知道 Student stu2= (Student)ser.Deserialize(reader);
我们用上面得到XML数据进行反序列化测试。查看运行结果,ok的啦!
二、序列化列表
和上面一样,序列化学生列表(People类和Student类和上面代码一样)
List<Student> stuList = new List<Student>(); stuList.Add(, Number = , Name = "Tom", SClass = "Class One" }); stuList.Add(, Number = , Name = "Jay", SClass = "Class Two" }); stuList.Add(, Number = , Name = "Pet", SClass = "Class One" }); stuList.Add(, Number = , Name = "May", SClass = "Class Three" }); stuList.Add(, Number = , Name = "Soy", SClass = "Class Two" }); //序列化 XmlSerializer ser = new XmlSerializer(typeof(List<Student>)); StringWriter writer = new StringWriter(); //将学生列表序列化为Xml数据 ser.Serialize(writer, stuList); //反序列化 //要先将构造StringReader,作为Deserialize()的初始化参数 StringReader reader = new StringReader(writer.ToString()); //别忘了从Object到List<Student>,否则会报错。。 List<Student> stuList2 = (List<Student>)ser.Deserialize(reader);
运行结果是(注意:根是ArrayOfStudent不是Student了):

三、序列化字典(键/值对)
在XmlSerializer中,不支持Dirctionary<>类型的对象,所以在序列化这种最常见类型的时候,只能按照它的格式先创建一个可以序列化的类型,然后,将数据存储在该可序列化的类型中,然后再进行序列化即可。
Dictionary<string, int> dic = new Dictionary<string, int>();
dic.Add();
dic.Add();
dic.Add();
dic.Add();
List<DictionaryList> dicList = new List<DictionaryList>();
foreach (var a in dic)
{
DictionaryList dicl = new DictionaryList() { Name=a.Key, Value=a.Value};
dicList.Add(dicl);
}
//序列化
XmlSerializer ser = new XmlSerializer(typeof(List<DictionaryList>));
StringWriter writer = new StringWriter();
//序列化为Xml数据
ser.Serialize(writer, dicList);
MessageBox.Show(writer.ToString());
//反序列化
StringReader reader = new StringReader(writer.ToString());
List<DictionaryList> stuList2 = (List<DictionaryList>)ser.Deserialize(reader);
运行结果是:

四、序列化图片
补充:XmlArray和XmlArrayItem的使用,用在数组中
先构造实体类:
[XmlRoot("cats")]
public class CatCollection
{
[XmlArray("items"), XmlArrayItem("item")]
public Cat[] Cats { get; set; }
}
//[XmlRoot("cat")] 加不加都无所谓的。
public class Cat
{
//定义Color属性的序列化为cat节点的属性
[XmlAttribute("color")]
public string Color { get; set; }
//要求不序列化Speed属性
[XmlIgnore]
public int Speed { get; set; }
//设置Saying属性序列化为Xml子元素
[XmlElement("saying")]
public string Saying { get; set; }
}
现在,进行序列化:
//声明一个猫咪对象
, Saying = "White or black, so long as the cat can catch mice, it is a good cat" };
, Saying = "White or black, so long as the cat can catch mice, it is a good cat" };
CatCollection cc = new CatCollection { Cats = new Cat[] { cWhite, cBlack } };
//序列化这个对象
XmlSerializer serializer = new XmlSerializer(typeof(CatCollection));
StringWriter writer = new StringWriter();
serializer.Serialize(writer,cc);
MessageBox.Show(writer.ToString());
运行结果是:
XmlSerializer内存泄漏问题:
多谢chenlulouis,仔细看了下msdn,确实存在泄漏的情况,msdn说明如下:
动态生成的程序集
为了提高性能,XML 序列化基础结构将动态生成程序集,以序列化和反序列化指定类型。此基础结构将查找并重复使用这些程序集。此行为仅在使用以下构造函数时发生:
XmlSerializer(Type) XmlSerializer.XmlSerializer(Type, String)
如果使用任何其他构造函数,则会生成同一程序集的多个版本,且绝不会被卸载,这将导致内存泄漏和性能降低。最简单的解决方案是使用先前提到的两个构造函数的其中一个。否则,必须在 Hashtable 中缓存程序集,如以下示例中所示。
也就是说我们在使用XmlSerializer序列化,初始化XmlSerializer对象时最好使用下面两个构造函数否则会引起内存泄漏。
XmlSerializer(Type) XmlSerializer.XmlSerializer(Type, String)
C#处理Xml的相关随笔:
/// <summary>
/// 提供xml文档序列化 反序列化
/// </summary>
public sealed class EncodeHelper
{
/// <summary>
/// 反序列化XML字符串为指定类型
/// </summary>
public static object Deserialize(string Xml, Type ThisType)
{
XmlSerializer xmlSerializer = new XmlSerializer(ThisType);
object result;
try
{
using (StringReader stringReader = new StringReader(Xml))
{
result = xmlSerializer.Deserialize(stringReader);
}
}
catch (Exception innerException)
{
bool flag = false;
if (Xml != null)
{
if (Xml.StartsWith(Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble())))
{
flag = true;
}
}
throw new ApplicationException(string.Format("Couldn't parse XML: '{0}'; Contains BOM: {1}; Type: {2}.",
Xml, flag, ThisType.FullName), innerException);
}
return result;
}
/// <summary>
/// 序列化object对象为XML字符串
/// </summary>
public static string Serialize(object ObjectToSerialize)
{
string result = null ;
try
{
XmlSerializer xmlSerializer = new XmlSerializer(ObjectToSerialize.GetType());
using (MemoryStream memoryStream = new MemoryStream())
{
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false));
xmlTextWriter.Formatting = Formatting.Indented;
xmlSerializer.Serialize(xmlTextWriter, ObjectToSerialize);
xmlTextWriter.Flush();
xmlTextWriter.Close();
UTF8Encoding uTF8Encoding = new UTF8Encoding(false, true);
result= uTF8Encoding.GetString(memoryStream.ToArray());
}
}
catch (Exception innerException)
{
throw new ApplicationException("Couldn't Serialize Object:" + ObjectToSerialize.GetType().Name, innerException);
}
return result;
}
}
http://hi.baidu.com/jackeyrain/item/79ad923564fa94f1e6bb7a11
http://www.cnblogs.com/John-Connor/archive/2012/04/12/2440352.html
Windows phone 之XML序列化与反序列化的更多相关文章
- XML 序列化与反序列化
XML序列化与反序列化 1.将一个类转化为XML文件 /// <summary> /// 对象序列化成XML文件 /// </summary> /// <param na ...
- XmlSerializer 对象的Xml序列化和反序列化
http://www.cnblogs.com/yukaizhao/archive/2011/07/22/xml-serialization.html 这篇随笔对应的.Net命名空间是System.Xm ...
- C#的XML序列化及反序列化
webservice在工作中用到的很多,基本都是以XML格式问通讯内容,其中最关键的就是XML串的序列化及反序列化. XML的运用中有两种信息传递,一种为XML的请求信息,另一种为返回信息,要运用XM ...
- .NET XML序列化与反序列化
闲着没事,写了两个通用的XML序列化与反序列化的方法. 贴出来当作笔记吧! /// <summary> /// XML序列化 /// </summary> /// <ty ...
- XmlSerializer 对象的Xml序列化和反序列化,XMLROOT别名设置
这篇随笔对应的.Net命名空间是System.Xml.Serialization:文中的示例代码需要引用这个命名空间. 为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中:内存中 ...
- c# XML序列化与反序列化
c# XML序列化与反序列化 原先一直用BinaryFormatter来序列化挺好,可是最近发现在WinCE下是没有办法进行BinaryFormatter操作,很不爽,只能改成了BinaryWrite ...
- Xml序列化、反序列化帮助类
之前从网络上找了一个Xml处理帮助类,并整理了一下,这个帮助类针对Object类型进行序列化和反序列化,而不需要提前定义Xml的结构,把它放在这儿供以后使用 /// <summary> / ...
- C#操作Xml:XmlSerializer 对象的Xml序列化和反序列化
这篇随笔对应的.Net命名空间是System.Xml.Serialization:文中的示例代码需要引用这个命名空间. 为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中:内存中的对 ...
- C#实现接口xml序列化与反序列化
C#实现接口xml序列化与反序列化 C#中接口无法被xml序列化,提示不支持.百度和bing也搜不到,只好自己动手写了 原理上肯定支持,.Net自己的xml序列化有一个IXmlSerializab ...
随机推荐
- HW4.27
public class Solution { public static void main(String[] args) { int count = 0; for(int i = 2001; i ...
- jmeter http get 登录
登录页url:http://www.ablesky.com/login.do?fromurl=http%3A%2F%2Fwww.ablesky.com%2Findex.do 登录参数用firebu ...
- CSharp - Comparison between IComparer and IComparable
/* Author: Jiangong SUN */ I've already written an article introducing the usage of comparer here. I ...
- ZooKeeper监控
http://jm-blog.aliapp.com/?p=1450 在公司内部,有不少应用已经强依赖zookeeper,zookeeper的工作状态直接影响它们的正常工作.目前开源世界中暂没有一个比较 ...
- cf 85 E. Petya and Spiders
http://codeforces.com/contest/112/problem/E 轮廓线dp.每一个格子中的蜘蛛选一个去向.终于,使每一个蜘蛛都有一个去向,同一时候保证有蜘蛛的格子最少.须要用4 ...
- QuaZip实现多文件打包
项目需求: 在Goldenfarm客户端中当用户选择了本地场景文件,并进行本地场景文件分析后会产生分析结果,分析结果主要包括:贴图纹理.可渲染层等,其中贴图纹理指出了在场景文件中使用到的贴图或其它文件 ...
- 关于XCode5打开工程闪退的一种解决方案
今天同事遇到一个问题,是关于xcode5打开工程文件一直闪退的问题.后来查看了一下崩溃日志.有如下描述: xception Type: EXC_CRASH (SIGABRT) Exception Co ...
- android开发之bitmap使用
bitmap是android中重要的图像处理工具类,通过bitmap可以对图像进行剪切.旋转.缩放等操作,同时还可以指定格式和压缩质量保存图像文件. 一.拿到一个Bitmap对象 查看源码我们知道,B ...
- Java基础知识强化之集合框架笔记60:Map集合之TreeMap(TreeMap<Student,String>)的案例
1. TreeMap(TreeMap<Student,String>)的案例 2. 案例代码: (1)Student.java: package cn.itcast_04; public ...
- Android(java)学习笔记181:利用Service在后台播放背景音乐
1.在android应用程序里,有一种没有UI的类(android.app.Service)——Service.简单来说,Service是一个 background process(背景程序),通过背 ...