前言

呃,已经是第八篇了,怎么感觉Xml还有好多东西没讲。。。还是先挑比较重要的东西讲一下吧,今天的主角是.net的Xml序列化。

在主角出现前,先回想一下,平时什么地方用了Xml序列化吧:

第一个想到的当然是Web Service和更进一步的WCF,没有Xml序列化的话,就需要手动处理Soap协议的各种输入和输出,其复杂性将会成倍的增长。

第二个想到的就是Xml序列化其实就是一个Xml与对象之间的桥梁,可以把一个实例Xml变成一个实例对象,也可以把一个实例对象变成一个实例Xml,这在需要持久化的场合非常有用。

工具

工欲善其事,必先利其器。首先来看看关于Xml序列化的工具吧。

这些工具通常在X:\Program Files\Microsoft SDKs\Windows\v6.0A\bin目录下,其中和Xml序列关系比较大的有xsd.exe、wsdl.exe、svcutil.exe。当然其他工具在.net里面也是非常重要的,可以在这里察看所有工具的用途和使用方式。这里重点要用到的是xsd.exe。

当然这个工具有三种用法,分别是:

  • Xml First,先有Xml实例,适合先想好Xml是什么样,或者已经有Xml实例的情况
  • Xsd First,先有Xsd,适合于可以获得Xsd,或者熟悉Xsd的人,并且对Xml有很强的控制欲的人(某人飘过)
  • Class First,先有c#类型,适合于先有c#代码的情况

接下来将分别介绍这3种方式的。

Xml First

这种情况首先有一个Xml实例,例如:

<?xml version="1.0" encoding="utf-8" ?>
<persons><person name="Zhenway, Yan"><goodat>Xml</goodat><goodat>Reflection</goodat></person><person name="Allen, Lee"><goodat>Ruby</goodat><goodat>F#</goodat><goodat>Windows Mobile</goodat><goodat>Linq</goodat></person>
</persons>

利用Xsd命令:“xsd XmlFirst.xml”,就可以根据这个实例获得xsd(当然不会是非常精确的,但基本上能用):

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="persons" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"><xs:element name="persons" msdata:IsDataSet="true" msdata:Locale="en-US"><xs:complexType><xs:choice minOccurs="0" maxOccurs="unbounded"><xs:element name="person"><xs:complexType><xs:sequence><xs:element name="goodat" nillable="true" minOccurs="0" maxOccurs="unbounded"><xs:complexType><xs:simpleContent msdata:ColumnName="goodat_Text" msdata:Ordinal="0"><xs:extension base="xs:string"></xs:extension></xs:simpleContent></xs:complexType></xs:element></xs:sequence><xs:attribute name="name" type="xs:string" /></xs:complexType></xs:element></xs:choice></xs:complexType></xs:element>
</xs:schema>

当然,如果对这个Xsd不太满意的话,还可以修改一下。这样就把Xml First转换成Xsd First。

Xsd First

这里首先需要一个Xsd(某个控制欲极强的人重新写了一下xsd)

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="persons" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:complexType name="Person"><xs:sequence><xs:element name="goodat" type="xs:string" minOccurs="1" maxOccurs="unbounded"/></xs:sequence><xs:attribute name="name" type="xs:string"/></xs:complexType><xs:complexType name="Persons"><xs:sequence><xs:element name="person" type="Person" minOccurs="0" maxOccurs="unbounded"/></xs:sequence></xs:complexType><xs:element name="persons" type="Persons"/>
</xs:schema>

这里要求每个person的goodat至少要有一项。

然后利用xsd命令:“xsd XsdFirst.xsd /c”,这样就可以获得一个cs文件,整理后,如下:

using System;
using System.CodeDom.Compiler;
using System.ComponentModel;
using System.Diagnostics;
using System.Xml.Schema;
using System.Xml.Serialization;[GeneratedCodeAttribute("xsd", "2.0.50727.1432")]
[SerializableAttribute()]
[DebuggerStepThroughAttribute()]
[DesignerCategoryAttribute("code")]
[XmlRootAttribute("persons", Namespace = "", IsNullable = false)]
public partial class Persons
{private Person[] personField;[System.Xml.Serialization.XmlElementAttribute("person", Form = XmlSchemaForm.Unqualified)]public Person[] person{get { return this.personField; }set { this.personField = value; }}
}[GeneratedCodeAttribute("xsd", "2.0.50727.1432")]
[SerializableAttribute()]
[DebuggerStepThroughAttribute()]
[DesignerCategoryAttribute("code")]
public partial class Person
{private string[] goodatField;private string nameField;[XmlElementAttribute("goodat", Form = XmlSchemaForm.Unqualified)]public string[] goodat{get { return this.goodatField; }set { this.goodatField = value; }}[XmlAttributeAttribute()]public string name{get { return this.nameField; }set { this.nameField = value; }}
}

这样就可以获得一个类型与这个Xsd对应,在对象实例与这个Xsd实例之间建立一座桥梁。

Class First

这种情况适合于先有类型,然后想持久化的情况,例如拥有一个下列的类型:

[XmlRoot("persons")]
public class ClassFirst
{[XmlElement("person")]public Person[] PersonCollection { get; set; }
}public class Person
{[XmlAttribute("name")]public string Name { get; set; }[XmlElement("goodat")]public string[] GoodAt { get; set; }
}

Build以后,执行命令:“xsd ClassFirstSample.dll”,就可以获得这样一个xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="persons" nillable="true" type="ClassFirst" /><xs:complexType name="ClassFirst"><xs:sequence><xs:element minOccurs="0" maxOccurs="unbounded" name="person" type="Person" /></xs:sequence></xs:complexType><xs:complexType name="Person"><xs:sequence><xs:element minOccurs="0" maxOccurs="unbounded" name="goodat" type="xs:string" /></xs:sequence><xs:attribute name="name" type="xs:string" /></xs:complexType><xs:element name="Person" nillable="true" type="Person" />
</xs:schema>

这个xsd就是序列化出来的xml的Schema,基本上与。

XmlSerializer

前面的三种方式都只是在OOP与Xml之间建立一个契约,现在来介绍这个桥梁——XmlSerializer

废话就不说了,先来看看如何把对象转换成xml:

XmlSerializer serializer = new XmlSerializer(typeof(Persons));
serializer.Serialize(Console.Out, new Persons
{person = new Person[]{new Person{name = "Zhenway, Yan",goodat = new string[] { "Reflection", "Xml" },},new Person{name = "Allen, Lee",goodat = new string[] { "Ruby", "F#", "Windows Mobile", "Linq" },},}
});

来看看输出:

很好,接下来看看如何反过来,从Xml获得对象实例:

XmlSerializer serializer = new XmlSerializer(typeof(Persons));
using (var reader = File.OpenText("XmlFirst.xml"))
{Persons ps = (Persons)serializer.Deserialize(reader);foreach (var p in ps.person){Console.WriteLine("name='{0}', good at={1}",p.name, string.Join(", ", p.goodat));}
}

看看输出:

不过需要注意的一点是,如果需要反序列化对象的话,需要对临时目录(根据Windows的TEMP环境变量定义)的写入权限。

另外,XmlSerializer会自动生成一个Assembly用于加速序列化和反序列化,不过要注意由于AppDomain无法单独卸载一个Assembly的特性,所以当产生过多的Assembly时,就会导致内存占用过多。

尽管XmlSerializer也会尽量利用现有的Assembly,不过这仅仅发生在(Type)构造函数,和(Type,String)构造函数时才会发生,而其他构造函数将再次创建Assembly,如果放置在循环中,这样将导致AppDomain中Assembly数量激增,因此缓存XmlSerializer在某些场合下是非常必要的。

另外msdn上对XmlSerializer的描述有一处非常特别的地方,“此类型是线程安全的”,这在整个msdn中并不多见,也就是说,不用对缓存的XmlSerializer对象做任何的同步处理。

更多控制

XmlSerializer本身支持很多扩展,其中包括使用属性控制 XML 序列化,和更加可定制化的IXmlSerializable接口,这里限于篇幅就省略相关的内容。

下集预告?

第八篇了,还要下集?这个系列暂时就到这里吧,虽然感觉还有很多内容要讲。。。之后将推出难度较高的进阶系列。

系列目录

另外整理出本系列之前几篇连接和主要内容:

(一)——Dom

(二)——Dom with Namespace

(三)——Linq to Xml

(四)——Linq to Xml with Namespace

(五)——XStreamingElement

(六)——XmlWriter

(七)——XmlReader

c#操作Xml(八)相关推荐

  1. 使用Dom4j操作XML数据

    --------------siwuxie095 dom4j 是一个非常优秀的 Java XML 的 API, 用来读写 XML 文件 和操作 XML 数据 特点:性能优异.功能强大.极端易用 dom ...

  2. 在C#.net中如何操作XML

    在C#.net中如何操作XML 需要添加的命名空间: using System.Xml; 定义几个公共对象: XmlDocument xmldoc ; XmlNode xmlnode ; XmlEle ...

  3. ActionScript 3操作XML 详解

    AS3引入了E4X ,它是根据ECMAScript标准处理XML 数据的全新机制.这使得程序员在程序中无缝地操作XML.在AS3中可以使用XML字面值将XML数据直接写入代码,该字面值将被自动解析. ...

  4. 我错了,有个叫 SelectSingleNode 的可以操作 xml

    我错了,有个叫 SelectSingleNode 的可以操作 xml http://blog.csdn.net/wf520pb/article/details/2644549 ------------ ...

  5. android xml文件操作类,android操作xml

    android操作xml封装后的类,包括创建xml和读xml. public class XmlParserUtil { //创建xml文件 public static void createXmlF ...

  6. c#操作xml实例 2009-03-13 20:00

    在C#.net中如何操作XML 需要添加的命名空间: using System.Xml; 定义几个公共对象: XmlDocument xmldoc ; XmlNode xmlnode ; XmlEle ...

  7. C#操作XML总结1

    C#操作XML总结1 网上很多C#操作XML的文章,但是都是东拼西凑,把简单的问题复杂化,不参考罢了.如若照搬硬套,不但达不到目标,反而浪费时间.原本以前做过操作XML的程序,但是忘了,所以今天下午就 ...

  8. VC++中操作XML(MFC、SDK)

    VC++中操作XML(MFC.SDK) XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini.VC++里操作 ...

  9. Repeater、GridView等 操作XML

    Repeater.GridView等 操作XML文件 在项目中需要对XML文件进行管理,我用了Repeater 的方式来实现了实时的更新 希望对阅读这篇随笔的您有所帮助,我用的Repeater,您也可 ...

  10. ASP.net Xml: ASP.net操作Xml

    专题图编号:ylbtechASPnetXml100010010 XML课件PPT[在线PPT课件倡导者-ylb]  http://wenku.baidu.com/view/bfac3ebe1a37f1 ...

最新文章

  1. linux安装metasploit,centos如何安装metasploit
  2. linux bash shell for 循环使用简介
  3. 台式电脑可以连wifi吗_[Windows] wifi音箱:台式电脑也可以连接蓝牙音箱了
  4. Pv4、IPv6 、域名 正则表达式
  5. param.requires_grad = False的作用
  6. CAP定理(CAP theorem)
  7. SqlServer将数据表中的数据生成添加语句
  8. Git:本地Git仓库连接码云并新建分支提交
  9. [NLP] 中文文本相似度实战
  10. 时速云Kubernetes进阶培训 第三期
  11. 线性代数 第四章 线性方程组 知识点总结(Jeff自我感悟)
  12. 工序能力指数Cp判定标准(附免费CPK计算工具)
  13. 饥荒联机云服务器_饥荒steam联机版专用服务器搭建
  14. 无人机飞控 ardupilot Copter-4.0.7 库简介
  15. 【Python】字符串转换为ASCII码
  16. 阿拉伯数字和汉字对照表
  17. 计算机用户分配盘符,盘符划分不求人 Win7硬盘分区多面看
  18. 群晖NAS搭建WebDav服务,并内网穿透实现公网访问
  19. 对话驴评网CEO崔继蓉:在线旅游的前途在移动端
  20. 分享一下我的阿里3面+HR面面经,附上我总结的面试真题!

热门文章

  1. Oracle Library Cache 的 lock 与 pin 说明
  2. 数据结构-编程实现一个双链表的建立,双链表的打印,双链表的测长
  3. python的xlwt模块的常用方法
  4. java栈实现简易计算器算法
  5. 【POJ2387】Til the Cows Come Home (最短路)
  6. php select socket
  7. poj 2914(stoer_wanger算法求全局最小割)
  8. js浏览器窗口大小改变时事件
  9. 3、java基础:抽象类与接口的区别
  10. 人生的主干,提及程序化