本文主要是介绍.NET XML 串行化讲座,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1,浅串行化:只串行化类的公共字段和属性
公共属性必须是可读且可写的
使用命名空间:using System.Xml.Serialization;
以Book类为例:
串行化模板:
{
XmlSerializer serializer = new XmlSerializer(typeof(Book));
StreamWriter writer = new StreamWriter(filename);
Book myBook = new Book();
serializer.Serialize(writer, myBook);
writer.Close();
}
反串行化模板:
{
XmlSerializer serializer = new XmlSerializer(typeof(Book));
FileStream fs = new FileStream(filename, FileMode.Open);
Book myBook = (Book)serializer.Deserialize(fs);
fs.Close();
}
*使用XmlSerializer的类必须有一个不带参数的默认构造函数——在反串行化中使用
*序列化ArrayList类型字段X的特殊处理:在ctor中 this.X = new ArrayList();
*对于引用关系,如果A中引用了B,那么
在序列化A的时候,会生成如下格式的XML:
<A>
<B>xxxxx</B>
</A>
在反序列化A对象的时候,A中也会包含有具体值的B对象
*浅序列化不支持循环引用,即A引用B的同时,B也引用了A
序列化时,将XML格式定制为SOAP格式:使用XmlSerializer构造函数的另一个重载:
{
SoapReflectionImporter import = new SoapReflectionImporter();
XmlTypeMapping soapMapping = import.ImportTypeMapping(typeof(Book));
XmlSerializer serializer = new XmlSerializer(soapMapping);
StreamWriter writer = new StreamWriter(filename);
Book myBook = new Book();
serializer.Serialize(writer, myBook);
writer.Close();
}
2,深串行化:串行化对象的整个状态
使用命名空间:
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
串行化类的标志:在类前加上[Serializable]特性
两种格式器:BinaryFormatter,SoapFormatter
以BinaryFormatter为例(SoapFormatter与之相同)
串行化模板:
{
Book myBook = new Book();
BinaryFormatter formatter = new BinaryFormatter();
FileStream fs = File.Create(filename);
formatter.Serialize(fs, myBook);
fs.Close();
}
反串行化模板:
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream fs = File.OpenRead(filename);
Book myBook = (Book)formatter.Deserialize(fs);
fs.Close();
}
*在字段上加上[NonSerialized],可以不使该字段被序列化
*对于引用关系,如果A中引用了B,A和B类都要加上[Serializable],才能对A进行串行化
*对于循环引用,只支持对象图的循环引用,不支持广义的对象循环引用
对象图循环引用的例子:
public class Book
{
private BookCatalog includeInBookCatalog;
public BookCatalog IncludeInBookCatalog
{
get { return includeInBookCatalog; }
set { includeInBookCatalog = value; }
}
}
[Serializable]
public class BookCatalog
{
private Book[] books;
public Book[] Books
{
get { return books; }
set
{
books = value;
foreach (Book book in books)
{
book.IncludeInBookCatalog = this;
}
}
}
}
对BookCatalog进行深度序列化,不会造成循环引用,因为格式化器Formatter知道无论对象有多少个引用,保证每个对象只串行化一次——通过System.Runtime.Serialization下的两个类实现:ObjectManager和ObjectIDGenerator。
ObjectManager 负责在对象反串行化时跟踪对象,确定该对象是否串行化过
ObjectIDGenerator 为每个被跟踪的对象加一个唯一的ID以区别,根据对象是否被串行化,ObjectIDGenerator知道是返回已有的ID,还是生成一个新的ID
格式化器不会提前检查所有的对象可串行化,中途如果发生异常,可以已经生成部分对象了。
通过深串行化克隆对象:
先串行化,在内存流上使用二进制深度复制;然后再找到流的开头,进行反串行化
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Context = new StreamingContext(StreamingContextStates.Clone);
formatter.Serialize(stream, source);
stream.Position = 0;
return formatter.Deserialize(stream);
}
3, 3.1 从可串行化的类中定制XML串行化
1.格式化XML文档元素
public class Student
{
//则生成XML文档中,根元素<Pupil xmlns="urn:MyNamespace">
}
2.格式化XML元素
public string Name
{
get { return name; }
set { name = value; }
}
生成XML如下:
< Pupil xmlns:xsd = " http://www.w3.org/2001/XMLSchema "
xmlns:d1p1 = " urn:OtherNamespace " >
< d1p1:FullName > Thomas Smith </ d1p1:FullName >
</ Pupil >
这里的d1p1是自动生成的,在标题4,有办法自己指定Namespace前缀。
3.格式化XML属性
public string Name
{
get { return name; }
set { name = value; }
}
同样还是Name属性,这次是使用XmlAttribute标签,生成XML如下:
< Pupil xmlns:xsd = " http://www.w3.org/2001/XMLSchema "
xmlns:d1p1 = " urn:OtherNamespace "
d1p1:Name = " Thomas Smith " >
</ Pupil >
XML属性在空间利用率上比XML元素略高一些。
4.为元素/属性设计限定的命名空间
使用XmlSerializer的Serialize方法重载,额外带一个XmlSerializerNamespace参数,指定这个命名空间前缀
{
//自定义命名空间
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("xsd", "http://www.w3.org/2001/XMLSchema");
ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
ns.Add("otherNS", "urn:OtherNamespace");
XmlSerializer serializer = new XmlSerializer(typeof(Book));
StreamWriter writer = new StreamWriter(filename);
Book myBook = new Book();
//使用Serialize重载方法
serializer.Serialize(writer, myBook, ns);
writer.Close();
}
从而生成完全自定义的XML:
< Pupil xmlns:xsd = " http://www.w3.org/2001/XMLSchema "
xmlns:otherNS = " urn:OtherNamespace "
xmlns:xsi = " http://www.w3.org/2001/XMLSchema-instance "
otherNS:StudentNumber = " 8007 " xmlns = " urn:MyNamespace " >
< otherNS:FullName > Thomas Smith </ otherNS:FullName >
</ Pupil >
5.格式化文本内容
public string Name
{
get { return name; }
set { name = value; }
}
则Name会生成在<Pupil>XXX(Name)</Pupil>中作为文本
6.为元素/属性定义数据类型
XML Schema类型与.NET数据类型有一个Mapping,比如说type对应System.DateTime
public DateTime EnrollDate
{
get { return enrollDate; }
set { enrollDate = value; }
}
于是生成XML: <EnrollDate>2007-10-19</EnrollDate>
XMLRoot,XmlAttribute,XMLElement,XMLText,XMLArrayItem标签都可以指定DataType
7.为枚举修饰符指定其他名称
{
[XmlEnum(Name="White Color")]
White,
[XmlEnum(Name = "Black Color")]
Black,
[XmlEnum(Name = "Red Color")]
Red
}
private Color showColor;
public Color ShowColor
{
get { return showColor; }
set { showColor = value; }
}
生成XML如下格式:
<ShowColor>White Color</ShowColor>
8.串行化多肽数组
XmlArrayItem(Type = typeof (String), ElementName = " CourceName " ),
XmlArrayItem(Type = typeof (Int32), ElementName = " CourceCode " )]
public Object[] Subjects
{
get { return subjects; }
set { subjects = value; }
}
XmlArrayItem负责指定数组中可能出现的元素类型,以及该类型对应的XML前缀
比如说创建如下的数组:
Object obj = new Object["Physics", 123, "IT"];
生成XML如下格式:
< CourceName > Physics </ CourceName >
< CourceCode > 123 </ CourceCode >
< CourceName > IT </ CourceName >
</ Cources >
9.定义可空的对象引用
如果某属性为null,在串行化时会忽略该属性,可以显示替代的信息,方法如下:
public string Address
{
get { return address; }
set { address = value; }
}
在该位置,生成替代XML:
<Address xsi:nil="true" />
10.定义可忽略的字段/属性
[XmlIgnore()]
3.2 把XML串行化定制为SOAP编码格式
{
SoapReflectionImporter importer = new SoapReflectionImporter();
XmlTypeMapping mapping = importer.ImportMembersMapping(typeof(Student));
XmlTextWriter writer = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
writer.WriteStartElement("MyWrapperElement");
writer.WriteAttributeString("xmlns", "xsd", Nothing, "http://www.w3.org/2001/XMLSchema");
writer.WriteAttributeString("xmlns", "xsi", Nothing, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xmlns", "soap", Nothing, "http://schemas.xmlsoap.org/soap/encoding/");
writer.WriteAttributeString("xmlns", "otherNS", Nothing, "urn:OtherNamespace");
XmlSerializer serializer = new XmlSerializer(mapping);
serializer.Serialize(writer, obj);
writer.WriteEndElement();
writer.Close();
}
于是,生产SOAP格式的XML文件。
Soap编码串行化的属性,无XMLText和XMLArray,其它的对应如下:
SoapType | XmlType |
SoapElement | XmlElement |
SoapAttribute | XmlAttribute |
SoapEnum | XmlEnum |
SoapIgnore | XmlIgnore |
SoapInclude | XmlInclude |
这篇关于.NET XML 串行化讲座的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!