电脑爱好者,提供IT资讯信息及各类编程知识文章介绍,欢迎大家来本站学习电脑知识。 最近更新 | 联系我们 RSS订阅本站最新文章
电脑爱好者
站内搜索: 
当前位置:首页>> XML专区>>.NET使XML串行化易如反掌:

.NET使XML串行化易如反掌

来源:远方网络 | 2006-2-28 | (有1833人读过)

人们一直高喊XML是解决系统互联问题的关键, 而.NET framework 也为处理XML数据提供了许多不同的类库. XmlDocument 类能让你像处理文件一样处理XML 数据, 而XmlReader, XmlWriter, 和它们的派生类使你能够将XML 数据做为数据流处理. XmlSerializer 则提供了另外的方法, 它使你能够将自己的对象串行和反串行化为XML. 串行化数据既能够让你像处理文件一样对数据进行随机存取, 同时又能够跳过你不感兴趣的元素. 在本文中, 我将向你展示如何使用XmlSerializer类以及如何在你的类中添加属性来控制串行化过程.

XmlSerializer
XmlSerializer类存在于System.Xml.Serialization命名空间的System.Xml.dll中, 它用一种高度松散耦合的方式提供串行化服务. 你的类不需要继承特别的基类, 而且它们也不需要实现任何特别的接口. 相反的, 你只需要在你的类或者这些类的公共域以及读/写属性里加上自定义的属性. XmlSerializer 通过相反映射读取这些属性并用它们将你的类和类成员映射到XML元素和属性.

将XML 映射到对象
考虑表A中的XML语句, 哪一个正确的描述了一家电影院中上映的电影呢?

表A

<?xml version="1.0" encoding="utf-8" ?>
<theater>
<name>The Camelot</name>
<phone>(888)665-2222</phone>
<movie minutes="120" stars="2">
<title>The Score</title>
<rating>R</rating>
<showing>16:15:00</showing>
<showing>19:05:00</showing>
<showing>21:40:00</showing>
</movie>
<movie minutes="100">
<title>Shrek</title>
<rating>PG-13</rating>
<showing>16:00:00</showing>
<showing>19:00:00</showing>
<showing>21:40:00</showing>
</movie>
</theater>



表B中定义了一个Theater(电影院)类, 它包含了XmlSerializer使用的属性映射.

表B

using System;
using System.Xml.Serialization;

namespace Articles.TechRepublic.XmlSerialization
{
[XmlRoot( "theater" )]
public class Theater
{
[XmlElement( "name" )]
public string Name = "";

[XmlElement( "phone" )]
public string Phone = "";

[XmlElement( "movie" )]
public Movie[] Movies;

public override string ToString()
{
string movies = "";
if ( Movies != null )
foreach ( Movie movie in Movies )
movies += "\n" + movie.ToString();

return String.Format( "{0}\n {1}\n{2}",
Name, Phone, movies );
}
}

 



XmlRoot 属性将类Theater映射到XML的根元素theater. XmlElement 属性将Name, Phone, 和 Movies数据域映射到嵌套在theater元素中的name, phone, 和 movie XML元素上去. 因为Movies是Movie数组, 所以XmlSerializer将它映射到多个XML movie元素.

表C展示了一个带有属性映射的Movie类

表C

public class Movie
{
[XmlElement( "title" )]
public string Title = "";

[XmlAttribute( "minutes" )]
public uint Minutes = 0;

[XmlElement( "showing", DataType="time" )]
public DateTime[] Showings;

public override string ToString()
{
string showings = "";
if ( Showings != null )
{
showings = "shows at ";
foreach ( DateTime showing in Showings )
showings += showing.ToShortTimeString() + " ";
}
else
{
showings = "- No showings";
}

return String.Format( " {0} ({1} min) {2}",
Title, Minutes, showings );
}
}

 

XmlElement 属性将Title和Showings数据域映射到movie元素内的title 和showing XML元素.就象 Theater.Movie一样, 做为DateTime数组的Movie.Showings 被映射到多个XML showing 元素. showing 数据域的属性包括位置属性参数DataType="time". 它将DateTime值映射到一个XML time值, 其间去掉了日期信息而只保留了时间信息. XmlAttribute 属性将Minutes 数据域映射到XML属性而不是XML元素.

XML数据中的moviestars(影星)属性和rating(上座率)元素没有被映射到Movie类中的任何东西上去. 当反串行化XML数据的时候, XmlSerializer只是简单的跳过它不能映射的项目. 当串行化一个对象的时候, 你可以在公共数据域和你希望XmlSerializer跳过的属性里加上XmlIgnore 属性.

XmlRoot, XmlElement, 和 XmlAttribute的属性类都应包括后缀"Attribute." 在我的属性申明里, 我使用了没有后缀的缩写形式. Theater和Movie类中的公共属性可以被改写成公共属性以求得更好的封装性. XmlSerializer 可以用相同的方式使用它们. 我在这里将它们做为数据域使用是为了使代码更紧凑.

将XML数据反串行化成对象
将XML数据加载到一个Theater对象里现在已经变得非常容易. 表D中的程序, XmlIn, 通过反串行化movie showings XML 数据创建一个Theater对象. 这个程序通过命令行执行, 你需要指明一个输入的XML文件.

表D

using System;
using System.Xml.Serialization;
using System.IO;
using Articles.TechRepublic.XmlSerialization;

public class XmlIn
{
public static void Main( string[] args )
{
if ( args.Length != 1 )
{
Console.WriteLine( "Usage: XmlIn infile.xml" );
return;
}

try
{
// Deserialize the specified file to a Theater object.
XmlSerializer xs = new XmlSerializer( typeof ( Theater ) );
FileStream fs = new FileStream( args[0], FileMode.Open );

Theater theater = (Theater)xs.Deserialize( fs );

// Display the theater object.
Console.WriteLine ( theater );
}
catch ( Exception x )
{
Console.WriteLine( "Exception: " + x.Message );
}
}
}

Output:
>XmlIn theaterIn.xml
The Camelot
(888)665-2222

The Score (120 min) shows at 4:15 PM 7:05 PM 9:40 PM
Shrek (100 min) shows at 4:00 PM 7:00 PM 9:40 PM
 


主要的程序代码都放在Main 函数的try代码段里. 首先创建一个XmlSerializer对象并指明一个System.Type 对象来告诉反串行化程序要创建的对象的类型. typeof操作符为Theater类返回一个System.Type 对象. 然后, 打开一个文件流读取输入的XML文件. 调用XmlSerializer的Deserialize方法, 并把文件流传递给它. Deserialize 返回对Theater对象的引用. Theater和Movie 对象中的ToString方法能够让你简单的输出它们.

将对象串行化到XML里
从一个Theater对象生成XML数据同样是容易的. 表E中的程序,XmlOut, 就是将一个Theater对象串行化到XML 文件里. 这个程序通过命令行执行, 你需要指明输出的XML文件.

表E

using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using Articles.TechRepublic.XmlSerialization;

public class XmlOut
{
// Returns a populated Theater object.
public static Theater GetTheater()
{
Movie movie = new Movie();
movie.Title = "O Brother, Where Art Thou?";
movie.Minutes = 102;
movie.Showings = new DateTime[3];
movie.Showings[0] = new DateTime( 2001, 8, 2, 13, 15, 0 );
movie.Showings[1] = new DateTime( 2001, 8, 2, 16, 30, 0 );
movie.Showings[2] = new DateTime( 2001, 8, 2, 19, 55, 0 );

Theater theater = new Theater();
theater.Name = "Hollywood Movies 10";
theater.Phone = "(972)555-154";
theater.Movies = new Movie[1];
theater.Movies[0] = movie;

return theater;
}

public static void Main( string[] args )
{
if ( args.Length != 1 )
{
Console.WriteLine( "Usage: XmlOut outfile.xml" );
return;
}

try
{
Theater theater = GetTheater();

// Serialize the Theater object to an XML file.
XmlSerializer xs = new XmlSerializer( typeof ( Theater ) );
FileStream fs = new FileStream( args[0], FileMode.Create );

xs.Serialize( fs, theater );
}
catch ( Exception x )
{
Console.WriteLine( "Exception: " + x.Message );
}
}
}

Invocation:
>XmlOut theaterOut.xml

theaterOut.xml contents:

<?xml version="1.0"?>
<theater
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<name>Hollywood Movies 10</name>
<phone>(972)555-154</phone>
<movie minutes="102">
<title>O Brother, Where Art Thou?</title>
<showing>13:15:00.0000000-06:00</showing>
<showing>16:30:00.0000000-06:00</showing>
<showing>19:55:00.0000000-06:00</showing>
</movie>
</theater>

 

主要的程序代码都放在Main 函数的try代码段里. 首先通过GetTheater帮助函数创建一个Theater对象. 然后, 打开一个文件流来生成输出的XML 文件. 调用XmlSerializer的Serialize方法, 传递给它文件流和Theater对象. 就是这样简单--XML文件生成了!

输出的theater 元素包含了为模板和模板实例命名空间生成的XML命名空间属性(xmlns), 虽然在这两个命名空间里这些数据并不代表任何东西. showing元素中的-06:00 指的是美国中部时间, 或者说GMT时间再减去个小时, 也就是我所在的时区.

移动数据是小菜一碟
XmlSerializer 使得在对象和XML间移动数据变得非常容易, 只要在类里加上XML映射属性. 但是对于更复杂的对象模型, 手工的创建XML映射会变得非常的麻烦而且容易出错. 在我的下一篇文章里, 我将告诉你如何自动化这个工作并实现对你的XML数据的更严格的控制.




XML专区热门文章排行
网站赞助商
购买此位置

 

关于我们 | 网站地图 | 文档一览 | 友情链接| 联系我们

Copyright © 2003-2024 电脑爱好者 版权所有 备案号:鲁ICP备09059398号