比如我的XML長這樣:
1: <?xml version="1.0" encoding="utf-8"?>
2: <Order>
3: <OrderId>1</OrderId>
4: <OrderDate>2009/12/2</OrderDate>
5: </Order>
所以我就建了一個用來序列化這個XML的Class,如下:
1: Public Class Order
2: Private _OrderId As String
3: Private _OrderDate As String
4:
5: Public Property OrderId() As String
6: Get
7: Return _OrderId
8: End Get
9: Set(ByVal value As String)
10: _OrderId = value
11: End Set
12: End Property
13:
14: Public Property OrderDate() As String
15: Get
16: Return _OrderDate
17: End Get
18: Set(ByVal value As String)
19: _OrderDate = value
20: End Set
21: End Property
22: End Class
當然XML文件要怎麼對應成這個Class?最簡單的方法是透過.Net Framework所提供的xsd.exe工具來作,xsd工具可以從XML文件產生XML Schema(就是此份XML的定義檔),然後再從XML Schema產生出Class,詳細用法大家可以參考MSDN文件的說明.
為了方便起見,我寫了個小Function用來做XML序列化的動作,如下面程式:
1: Public Function SerializeToXml(ByVal targetObject As Object) As String
2: Dim ser As New XmlSerializer(targetObject.GetType)
3: Dim mem As New IO.MemoryStream
4: Dim writer As New Xml.XmlTextWriter(mem, System.Text.Encoding.UTF8)
5: ser.Serialize(writer, targetObject)
6: mem = CType(writer.BaseStream, IO.MemoryStream)
7: Return Encoding.UTF8.GetString(mem.ToArray)
8: End Function
要用時只要傳入塞好值的物件,就可以吐出我要的XML了,如下面程式:
1: Dim obj As New Order
2: obj.OrderId = "1"
3: obj.OrderDate = Now.ToString
4:
5: Console.WriteLine(SerializeToXml(obj))
吐出來的XML如下:
1: <?xml version="1.0" encoding="utf-8"?>
2: <Order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
3: <OrderId>1</OrderId>
4: <OrderDate>2009/12/2 下午 03:33:50</OrderDate>
5: </Order>
很簡單吧,不過仔細看看,在Order中多了2個Namespace的宣告,xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"跟xmlns:xsd="http://www.w3.org/2001/XMLSchema",不理他嗎?當初跟廠商談XML格式沒有說要加這2個namespace,萬一傳回去對方驗證錯誤怎辦?所以為了保險起見,還是要想辦法去掉這2個Namespace宣告,要控制序列化的結果當然就是從XML序列化的相關Attribute著手,看有沒有那個Attribute能去掉這2個宣告的,試了XmlRoot,XmlType這幾個跟Root有關的屬性都不行,正想放棄用Replace大法直接把這2串字去掉時,想到萬一未來版本Microsoft把序列化的Default Namespace給改了怎辦?那我不就要改程式,這麼苟且好像不太好,所以就上網goole一下看有沒有解,還好讓我找到原來可以透過XmlSerializerNamespaces來去掉或是變更序列化的Namespace的方法,所以把剛才的函式修改如下(重點是第4,5及第7行):
1: Public Function SerializeToXml(ByVal targetObject As Object) As String
2: Dim ser As New XmlSerializer(targetObject.GetType)
3: Dim mem As New IO.MemoryStream
4: Dim ns As New XmlSerializerNamespaces()
5: ns.Add("", "")
6: Dim writer As New Xml.XmlTextWriter(mem, System.Text.Encoding.UTF8)
7: ser.Serialize(writer, targetObject, ns)
8: mem = CType(writer.BaseStream, IO.MemoryStream)
9: Return Encoding.UTF8.GetString(mem.ToArray)
10: End Function
改好後,吐出來的XML果然就跟我想要的XML 100%相同了.YA!
沒有留言:
張貼留言