您的位置:首页 > 其它

XML 序列化示例

2010-01-16 09:00 169 查看
XML 序列化可以采用从简单到复杂的多种形式。例如,可以序列化只包含公共字段和公共属性的类,如 XML 序列化简介中所示。下面的代码示例讨论各种高级方案,包括如何使用 XML 序列化生成符合特定 XML 架构 (XSD) 文档的 XML 流。

序列化数据集

除了序列化公共类的实例外,还可序列化 DataSet 的实例,如下面的代码示例所示。

private void SerializeDataSet(string filename){
XmlSerializer ser = new XmlSerializer(typeof(DataSet));

// Creates a DataSet; adds a table, column, and ten rows.
DataSet ds = new DataSet("myDataSet");
DataTable t = new DataTable("table1");
DataColumn c = new DataColumn("thing");
t.Columns.Add(c);
ds.Tables.Add(t);
DataRow r;
for(int i = 0; i<10;i++){
r = t.NewRow();
r[0] = "Thing " + i;
t.Rows.Add(r);
}
TextWriter writer = new StreamWriter(filename);
ser.Serialize(writer, ds);
writer.Close();
}

序列化 XmlElement 和 XmlNode

还可序列化 XmlElement 或 XmlNode 类的实例

private void SerializeElement(string filename){
XmlSerializer ser = new XmlSerializer(typeof(XmlElement));
XmlElement myElement=
new XmlDocument().CreateElement("MyElement", "ns");
myElement.InnerText = "Hello World";
TextWriter writer = new StreamWriter(filename);
ser.Serialize(writer, myElement);
writer.Close();
}

private void SerializeNode(string filename){
XmlSerializer ser = new XmlSerializer(typeof(XmlNode));
XmlNode myNode= new XmlDocument().
CreateNode(XmlNodeType.Element, "MyNode", "ns");
myNode.InnerText = "Hello Node";
TextWriter writer = new StreamWriter(filename);
ser.Serialize(writer, myNode);
writer.Close();
}


序列化包含返回复杂对象的字段的类

如果属性或字段返回一个复杂对象(如数组或类实例),则 XmlSerializer 将其转换为嵌套在主 XML 文档内的元素。例如,以下代码示例中的第一个类返回第二个类的实例。

public class PurchaseOrder
{
public Address MyAddress;
}
public class Address
{
public string FirstName;
}

已序列化的 XML 输出可能如下所示。

复制代码
<PurchaseOrder>
<Address>
<FirstName>George</FirstName>
</Address>
</PurchaseOrder>


序列化对象数组

还可以序列化返回对象数组的字段,如下面的代码示例所示

public class PurchaseOrder
{
public Item [] ItemsOrders
}

public class Item
{
public string ItemID
public decimal ItemPrice
}


如果两个项已排序,则已序列化的类实例可能如下所示。

<PurchaseOrder xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Items>
<Item>
<ItemID>aaa111</ItemID>
<ItemPrice>34.22</ItemPrice>
<Item>
<Item>
<ItemID>bbb222</ItemID>
<ItemPrice>2.89</ItemPrice>
<Item>
</Items>
</PurchaseOrder>


序列化实现 ICollection 接口的类

您可以通过实现 ICollection 接口创建自己的集合类,并使用 XmlSerializer 序列化这些类的实例。请注意,当类实现 ICollection 接口时,只序列化该类包含的集合,而不会序列化添加至该类的任何公共属性或字段。该类必须包含 Add 方法和 Item 属性(C# 索引器)才能被序列化。

using System;
using System.IO;
using System.Collections;
using System.Xml.Serialization;

public class Test{
static void Main(){
Test t = new Test();
t.SerializeCollection("coll.xml");
}

private void SerializeCollection(string filename){
Employees Emps = new Employees();
// Note that only the collection is serialized -- not the
// CollectionName or any other public property of the class.
Emps.CollectionName = "Employees";
Employee John100 = new Employee("John", "100xxx");
Emps.Add(John100);
XmlSerializer x = new XmlSerializer(typeof(Employees));
TextWriter writer = new StreamWriter(filename);
x.Serialize(writer, Emps);
}
}
public class Employees:ICollection{
public string CollectionName;
private ArrayList empArray = new ArrayList();

public Employee this[int index]{
get{return (Employee) empArray[index];}
}

public void CopyTo(Array a, int index){
empArray.CopyTo(a, index);
}
public int Count{
get{return empArray.Count;}
}
public object SyncRoot{
get{return this;}
}
public bool IsSynchronized{
get{return false;}
}
public IEnumerator GetEnumerator(){
return empArray.GetEnumerator();
}

public void Add(Employee newEmployee){
empArray.Add(newEmployee);
}
}

public class Employee{
public string EmpName;
public string EmpID;
public Employee(){}
public Employee(string empName, string empID){
EmpName = empName;
EmpID = empID;
}
}


结果如下:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfEmployee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Employee>
<EmpName>John</EmpName>
<EmpID>100xxx</EmpID>
</Employee>
</ArrayOfEmployee>

using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

// The XmlRootAttribute allows you to set an alternate name
// (PurchaseOrder) for the XML element and its namespace. By
// default, the XmlSerializer uses the class name. The attribute
// also allows you to set the XML namespace for the element. Lastly,
// the attribute sets the IsNullable property, which specifies whether
// the xsi:null attribute appears if the class instance is set to
// a null reference.
[XmlRootAttribute("PurchaseOrder", Namespace="http://www.cpandl.com",
IsNullable = false)]
public class PurchaseOrder
{
public Address ShipTo;
public string OrderDate;
// The XmlArrayAttribute changes the XML element name
// from the default of "OrderedItems" to "Items".
[XmlArrayAttribute("Items")]
public OrderedItem[] OrderedItems;
public decimal SubTotal;
public decimal ShipCost;
public decimal TotalCost;
}

public class Address
{
// The XmlAttribute instructs the XmlSerializer to serialize the
// Name field as an XML attribute instead of an XML element (the
// default behavior).
[XmlAttribute]
public string Name;
public string Line1;

// Setting the IsNullable property to false instructs the
// XmlSerializer that the XML attribute will not appear if
// the City field is set to a null reference.
[XmlElementAttribute(IsNullable = false)]
public string City;
public string State;
public string Zip;
}

public class OrderedItem
{
public string ItemName;
public string Description;
public decimal UnitPrice;
public int Quantity;
public decimal LineTotal;

// Calculate is a custom method that calculates the price per item
// and stores the value in a field.
public void Calculate()
{
LineTotal = UnitPrice * Quantity;
}
}

public class Test
{
public static void Main()
{
// Read and write purchase orders.
Test t = new Test();
t.CreatePO("po.xml");
t.ReadPO("po.xml");
}

private void CreatePO(string filename)
{
// Creates an instance of the XmlSerializer class;
// specifies the type of object to serialize.
XmlSerializer serializer =
new XmlSerializer(typeof(PurchaseOrder));
TextWriter writer = new StreamWriter(filename);
PurchaseOrder po=new PurchaseOrder();

// Creates an address to ship and bill to.
Address billAddress = new Address();
billAddress.Name = "Teresa Atkinson";
billAddress.Line1 = "1 Main St.";
billAddress.City = "AnyTown";
billAddress.State = "WA";
billAddress.Zip = "00000";
// Sets ShipTo and BillTo to the same addressee.
po.ShipTo = billAddress;
po.OrderDate = System.DateTime.Now.ToLongDateString();

// Creates an OrderedItem.
OrderedItem i1 = new OrderedItem();
i1.ItemName = "Widget S";
i1.Description = "Small widget";
i1.UnitPrice = (decimal) 5.23;
i1.Quantity = 3;
i1.Calculate();

// Inserts the item into the array.
OrderedItem [] items = {i1};
po.OrderedItems = items;
// Calculate the total cost.
decimal subTotal = new decimal();
foreach(OrderedItem oi in items)
{
subTotal += oi.LineTotal;
}
po.SubTotal = subTotal;
po.ShipCost = (decimal) 12.51;
po.TotalCost = po.SubTotal + po.ShipCost;
// Serializes the purchase order, and closes the TextWriter.
serializer.Serialize(writer, po);
writer.Close();
}

protected void ReadPO(string filename)
{
// Creates an instance of the XmlSerializer class;
// specifies the type of object to be deserialized.
XmlSerializer serializer = new XmlSerializer(typeof(PurchaseOrder));
// If the XML document has been altered with unknown
// nodes or attributes, handles them with the
// UnknownNode and UnknownAttribute events.
serializer.UnknownNode+= new
XmlNodeEventHandler(serializer_UnknownNode);
serializer.UnknownAttribute+= new
XmlAttributeEventHandler(serializer_UnknownAttribute);

// A FileStream is needed to read the XML document.
FileStream fs = new FileStream(filename, FileMode.Open);
// Declares an object variable of the type to be deserialized.
PurchaseOrder po;
// Uses the Deserialize method to restore the object's state
// with data from the XML document. */
po = (PurchaseOrder) serializer.Deserialize(fs);
// Reads the order date.
Console.WriteLine ("OrderDate: " + po.OrderDate);

// Reads the shipping address.
Address shipTo = po.ShipTo;
ReadAddress(shipTo, "Ship To:");
// Reads the list of ordered items.
OrderedItem [] items = po.OrderedItems;
Console.WriteLine("Items to be shipped:");
foreach(OrderedItem oi in items)
{
Console.WriteLine("/t"+
oi.ItemName + "/t" +
oi.Description + "/t" +
oi.UnitPrice + "/t" +
oi.Quantity + "/t" +
oi.LineTotal);
}
// Reads the subtotal, shipping cost, and total cost.
Console.WriteLine(
"/n/t/t/t/t/t Subtotal/t" + po.SubTotal +
"/n/t/t/t/t/t Shipping/t" + po.ShipCost +
"/n/t/t/t/t/t Total/t/t" + po.TotalCost
);
}

protected void ReadAddress(Address a, string label)
{
// Reads the fields of the Address.
Console.WriteLine(label);
Console.Write("/t"+
a.Name +"/n/t" +
a.Line1 +"/n/t" +
a.City +"/t" +
a.State +"/n/t" +
a.Zip +"/n");
}

protected void serializer_UnknownNode
(object sender, XmlNodeEventArgs e)
{
Console.WriteLine("Unknown Node:" +   e.Name + "/t" + e.Text);
}

protected void serializer_UnknownAttribute
(object sender, XmlAttributeEventArgs e)
{
System.Xml.XmlAttribute attr = e.Attr;
Console.WriteLine("Unknown attribute " +
attr.Name + "='" + attr.Value + "'");
}
}


<?xml version="1.0" encoding="utf-8"?>
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.cpandl.com">
<ShipTo Name="Teresa Atkinson">
<Line1>1 Main St.</Line1>
<City>AnyTown</City>
<State>WA</State>
<Zip>00000</Zip>
</ShipTo>
<OrderDate>2010年1月16日</OrderDate>
<Items>
<OrderedItem>
<ItemName>Widget S</ItemName>
<Description>Small widget</Description>
<UnitPrice>5.23</UnitPrice>
<Quantity>3</Quantity>
<LineTotal>15.69</LineTotal>
</OrderedItem>
</Items>
<SubTotal>15.69</SubTotal>
<ShipCost>12.51</ShipCost>
<TotalCost>28.20</TotalCost>
</PurchaseOrder>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: