程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 如何在.net 當中XML序列化一個Collection

如何在.net 當中XML序列化一個Collection

編輯:關於.NET

Collection主要是指像Array, ArrayList, List, Dictionary, HashTable這 些數據類型,大家平時用的很多。如果一個類中有一個Collection類型的成員, 在對這個類進行XML序列化的時候,應該如何處理?應該說在.net當中這是比較 簡單的,只要建立一個XmlSerializer類就可以幫你自動搞定,不過有的時候你 可能需要對自動的序列化過程施加更多的控制,比如XML的結構是實現固定的, 你必須按照要求去生成XML結構。

使用不同的屬性可以靈活的控制生成的XML,這裡我就不多介紹了,主要講一 下如何序列化比較復雜的Collection結構。下面的方法,對於所有實現了 IEnumerable接口的Collection都有效。

我使用MSDN中的例子,不過沒有使用數組或者ArrayList,而是使用了比較高 級的數據類型List<T>,希望在講解如何序列化XML的同時給使用 List<T>的同學提供點參考。

序列化一個List<T>

下面的代碼示范了如何序列化一個List<T>,實際上和序列化其它類一 樣,把這個類扔給Serialize()函數即可。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace SerializeCollection
{
class Program
{
static void Main(string[] args)
{
Program test = new Program();
test.SerializeDocument ("e:\\books.xml");
}

public void SerializeDocument(string filename)
{
// Creates a new XmlSerializer.
XmlSerializer s =
new XmlSerializer(typeof (MyRootClass));

// Writing the file requires a  StreamWriter.
TextWriter myWriter = new StreamWriter (filename);

// Creates an instance of the class  to serialize.
MyRootClass myRootClass = new  MyRootClass();

//create items
Item item1 = new Item();
// Sets the objects' properties.
item1.ItemName = "Widget1";
item1.ItemCode = "w1";
item1.ItemPrice = 231;
item1.ItemQuantity = 3;

Item item2 = new Item();
// Sets the objects' properties.
item2.ItemName = "Widget2";
item2.ItemCode = "w2";
item2.ItemPrice = 800;
item2.ItemQuantity = 2;

// Sets the class's Items property to  the list.
myRootClass.Items.Add(item1);
myRootClass.Items.Add(item2);

/* Serializes the class, writes it to  disk, and closes
the TextWriter. */
s.Serialize(myWriter, myRootClass);
myWriter.Close();
}

}

// This is the class that will be serialized.
[Serializable]
public class MyRootClass
{
public MyRootClass()
{
items = new List<Item>();
}

private List<Item> items;

public List<Item> Items
{
get { return items; }
set { items = value; }
}
}

public class Item
{
[XmlElement(ElementName = "OrderItem")]
public string ItemName;
public string ItemCode;
public decimal ItemPrice;
public int ItemQuantity;
}

}

最後序列化成的XML:

<?xml version="1.0" encoding="utf-8"?>
<MyRootClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Items>
<Item>
<OrderItem>Widget1</OrderItem>
<ItemCode>w1</ItemCode>
<ItemPrice>231</ItemPrice>
<ItemQuantity>3</ItemQuantity>
</Item>
<Item>
<OrderItem>Widget2</OrderItem>
<ItemCode>w2</ItemCode>
<ItemPrice>800</ItemPrice>
<ItemQuantity>2</ItemQuantity>
</Item>
</Items>
</MyRootClass>

如果這個List<T>中的成員的類還有繼承關系

現在把情況變得復雜一點,因為多態,List<T>中的類可能是指定類型 的子類型,這個時候會出現什麼情況呢?

我們增加一個BookItem類,繼承自Item 類。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace SerializeCollection
{
class Program
{
static void Main(string[] args)
{
Program test = new Program();
test.SerializeDocument ("e:\\books.xml");
}

public void SerializeDocument(string filename)
{
// Creates a new XmlSerializer.
XmlSerializer s =
new XmlSerializer(typeof (MyRootClass));

// Writing the file requires a  StreamWriter.
TextWriter myWriter = new StreamWriter (filename);

// Creates an instance of the class  to serialize.
MyRootClass myRootClass = new  MyRootClass();

/* Uses a more advanced method of  creating an list:
create instances of the Item and BookItem,  where BookItem 
is derived from Item. */
Item item1 = new Item();
// Sets the objects' properties.
item1.ItemName = "Widget1";
item1.ItemCode = "w1";
item1.ItemPrice = 231;
item1.ItemQuantity = 3;

BookItem bookItem = new BookItem();
// Sets the objects' properties.
bookItem.ItemCode = "w2";
bookItem.ItemPrice = 123;
bookItem.ItemQuantity = 7;
bookItem.ISBN = "34982333";
bookItem.Title = "Book of Widgets";
bookItem.Author = "John Smith";

// Sets the class's Items property to  the list.
myRootClass.Items.Add(item1);
myRootClass.Items.Add(bookItem);

/* Serializes the class, writes it to  disk, and closes
the TextWriter. */
s.Serialize(myWriter, myRootClass);
myWriter.Close();
}

}

// This is the class that will be serialized.
[Serializable]
public class MyRootClass
{
public MyRootClass()
{
items = new List<Item>();
}

private List<Item> items;

public List<Item> Items
{
get { return items; }
set { items = value; }
}
}

public class Item
{
[XmlElement(ElementName = "OrderItem")]
public string ItemName;
public string ItemCode;
public decimal ItemPrice;
public int ItemQuantity;
}

public class BookItem : Item
{
public string Title;
public string Author;
public string ISBN;
}


}

修改代碼後,我們再運行,出現如下錯誤“不應是類型 SerializeCollection.BookItem。使用 XmlInclude 或 SoapInclude 屬性靜態 指定非已知的類型”,看來是系統在做序列化的時候,搞不清楚List中的成員到 底是什麼類型。這個時候就要使用XmlArrayItem來幫忙了。MyRootClass類的 Item成員前加入XmlArrayItem標志。

[XmlArrayItem(ElementName= "Item", 
IsNullable=true,
Type = typeof(Item),
Namespace = "http://www.aboutdnn.com"),
XmlArrayItem(ElementName = "BookItem", 
IsNullable = true, 
Type = typeof(BookItem),
Namespace = http://www.aboutdnn.com)]

修改後的代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace SerializeCollection
{
class Program
{
static void Main(string[] args)
{
Program test = new Program();
test.SerializeDocument ("e:\\books.xml");
}

public void SerializeDocument(string filename)
{
// Creates a new XmlSerializer.
XmlSerializer s =
new XmlSerializer(typeof (MyRootClass));

// Writing the file requires a  StreamWriter.
TextWriter myWriter = new StreamWriter (filename);

// Creates an instance of the class  to serialize.
MyRootClass myRootClass = new  MyRootClass();

/* Uses a more advanced method of  creating an list:
create instances of the Item and BookItem,  where BookItem 
is derived from Item. */
Item item1 = new Item();
// Sets the objects' properties.
item1.ItemName = "Widget1";
item1.ItemCode = "w1";
item1.ItemPrice = 231;
item1.ItemQuantity = 3;

BookItem bookItem = new BookItem();
// Sets the objects' properties.
bookItem.ItemCode = "w2";
bookItem.ItemPrice = 123;
bookItem.ItemQuantity = 7;
bookItem.ISBN = "34982333";
bookItem.Title = "Book of Widgets";
bookItem.Author = "John Smith";

// Sets the class's Items property to  the list.
myRootClass.Items.Add(item1);
myRootClass.Items.Add(bookItem);

/* Serializes the class, writes it to  disk, and closes
the TextWriter. */
s.Serialize(myWriter, myRootClass);
myWriter.Close();
}

}

// This is the class that will be serialized.
[Serializable]
public class MyRootClass
{
public MyRootClass()
{
items = new List<Item>();
}

private List<Item> items;

[XmlArrayItem(ElementName = "Item",
IsNullable = true,
Type = typeof(Item),
Namespace = "http://www.aboutdnn.com"),
XmlArrayItem(ElementName = "BookItem",
IsNullable = true,
Type = typeof(BookItem),
Namespace = "http://www.aboutdnn.com")]

public List<Item> Items
{
get { return items; }
set { items = value; }
}
}

public class Item
{
[XmlElement(ElementName = "OrderItem")]
public string ItemName;
public string ItemCode;
public decimal ItemPrice;
public int ItemQuantity;
}

public class BookItem : Item
{
public string Title;
public string Author;
public string ISBN;
}


}

序列化後的XML如下:

<?xml version="1.0" encoding="utf-8"?>
<MyRootClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Items>
<Item xmlns="http://www.aboutdnn.com">
<OrderItem>Widget1</OrderItem>
<ItemCode>w1</ItemCode>
<ItemPrice>231</ItemPrice>
<ItemQuantity>3</ItemQuantity>
</Item>
<BookItem xmlns="http://www.aboutdnn.com">
<ItemCode>w2</ItemCode>
<ItemPrice>123</ItemPrice>
<ItemQuantity>7</ItemQuantity>
<Title>Book of Widgets</Title>
<Author>John Smith</Author>
<ISBN>34982333</ISBN>
</BookItem>
</Items>
</MyRootClass>

可以看到,已經根據不同的數據類型,序列化為不同名字的節點。這個時候 ,如果你還想修改XML中<Items>節點的名字或者添加屬性, XmlArrayAttribute可以幫你的忙,這個你可以自己試試。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved