VB.NET反序列化XML

序列化,是將對象狀態轉換爲可保持或傳輸的格式的過程。

與序列化相反的是反序列化,它將流轉換爲對象。這兩個過程結合起來,就可以存儲和傳輸數據。這就是序列化的意義所在。


在VB.NET中轉換、處理和生成XML文檔時,需要用到一些XML專用名稱空間中的類,這些名稱空間包括:

System.Xml    該名稱空間提供了對各種XML標準(包括DTD、名稱空間、DOM、XDR(XML Data Reduced,XML架構標準的舊版本)、XPath、XSLT和SOAP(以前表示Simple Object Access Protocol標準,現在什麼也不表示))的核心支持。

System.Xml.Serialization    該名稱空間提供的對象使用序列化技術進行對象與XML文檔或流之間的轉換。

System.Xml.Schema    該名稱空間提供一組用於加載、創建和輸出架構的對象,這些對象可以在內存中操作組成XML架構的各種實體

System.Xml.Xpath    該名稱空間爲XPath(XML Path Language)提供語法分析程序和估算引擎。

System.Xml.Xsl    該名稱空間提空了使用XSL(Extensible Stylesheet Language)和XSLT(XSL Transformation)時必須用到的對象。

System.Xml.Linq    該名稱空間提供了使用LINQ查詢XML的支持。

今天我想討論的是VB.NET反序列化XML。

以下是我想反序列化的XML的結構:

<card>
	<sCodeBorder y1='34' y2='120' x2='568' x1='360' />
	<border y1='0' y2='1008' x2='1650' x1='0' />
	<area>
		<question id='1' x1='70' y1='274' x2='180' y2='288' >
			<option id='A' x1='70' y1='274' x2='90' y2='288' />
		</question>
		<question id='2' x1='70' y1='298' x2='180' y2='312' >
			<option id='A' x1='70' y1='298' x2='90' y2='312' />
			<option id='B' x1='100' y1='298' x2='120' y2='312' />
		</question>
		<question id='3' x1='70' y1='322' x2='180' y2='336' >
			<option id='A' x1='70' y1='322' x2='90' y2='336' />
			<option id='B' x1='100' y1='322' x2='120' y2='336' />
			<option id='C' x1='130' y1='322' x2='150' y2='336' />
		</question>
	</area>
</card>

我們首先要做的是創建與XML相對應的對象,然後再把XML轉換成我們想要的對象。

創建的類中需要引用System.Xml.Serialization 命名空間。這一命名空間包含用於將對象序列化爲XML格式文檔或流的類。

Public Class card
    <XmlElementAttribute("sCodeBorder")> Public sCodeBorder As sCodeBorder
    <XmlElementAttribute("border")> Public border As border
    <XmlElementAttribute("area")> Public area As area

    Public Sub New()
    End Sub

    Public Sub New(ByVal sCodeBorder As sCodeBorder, ByVal border As border, ByVal area As area )
        Me.sCodeBorder = sCodeBorder
        Me.border = border
        Me.area = area
    End Sub
End Class

Public Class sCodeBorder
    <XmlAttributeAttribute("x1")> Public x1 As Integer
    <XmlAttributeAttribute("x2")> Public x2 As Integer
    <XmlAttributeAttribute("y1")> Public y1 As Integer
    <XmlAttributeAttribute("y2")> Public y2 As Integer

    Public Sub New()
    End Sub
    Public Sub New(ByVal x1 As Integer, ByVal x2 As Integer, ByVal y1 As Integer, ByVal y2 As Integer)
        Me.x1 = x1
        Me.x2 = x2
        Me.y1 = y1
        Me.y2 = y2
    End Sub
End Class

Public Class border
    <XmlAttributeAttribute("x1")> Public x1 As Integer
    <XmlAttributeAttribute("x2")> Public x2 As Integer
    <XmlAttributeAttribute("y1")> Public y1 As Integer
    <XmlAttributeAttribute("y2")> Public y2 As Integer

    Public Sub New()
    End Sub
    Public Sub New(ByVal x1 As Integer, ByVal x2 As Integer, ByVal y1 As Integer, ByVal y2 As Integer)
        Me.x1 = x1
        Me.x2 = x2
        Me.y1 = y1
        Me.y2 = y2
    End Sub
End Class

Public Class area
    <XmlElementAttribute("question")> Public Ques_List() As question
    Public Sub New()
    End Sub

    Public Sub New(ByVal multiQ() As question)
        Me.Ques_List = multiQ
    End Sub
End Class


question類中維護了option類的對象集合。
Public Class question
    <XmlAttributeAttribute("x1")> Public x1 As Integer
    <XmlAttributeAttribute("x2")> Public x2 As Integer
    <XmlAttributeAttribute("y1")> Public y1 As Integer
    <XmlAttributeAttribute("y2")> Public y2 As Integer
    <XmlAttributeAttribute("id")> Public id As String
    <XmlElementAttribute("option")> Public multiOptions_List() As option_
    Public Sub New()
    End Sub

    Public Sub New(ByVal x1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer, ByVal y1 As Integer, ByVal id As String, ByVal multiO() As option_)
        Me.x1 = x1
        Me.x2 = x2
        Me.y2 = y2
        Me.y1 = y1
        Me.id = id
        Me.multiOptions_List = multiO
    End Sub
End Class

Public Class option_
    <XmlAttributeAttribute("x1")> Public x1 As Integer
    <XmlAttributeAttribute("x2")> Public x2 As Integer
    <XmlAttributeAttribute("y1")> Public y1 As Integer
    <XmlAttributeAttribute("y2")> Public y2 As Integer
    <XmlAttributeAttribute("id")> Public id As String

    Public Sub New()
    End Sub

    Public Sub New(ByVal x1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer, ByVal y1 As Integer, ByVal id As String)
        Me.x1 = x1
        Me.x2 = x2
        Me.y2 = y2
        Me.y1 = y1
        Me.id = id
    End Sub
End Class

這樣XML要反序列化的類就建立好了。雖然說有些複雜,但是有了這些類,我們就不用一個一個地處理XML的節點了~

具體到反序列化的代碼,就很簡單了。代碼如下:

Dim cardXML As FileStream = New FileStream(xmlPath, FileMode.Open)
'card是類名,也是根節點
Dim serialize As XmlSerializer = New XmlSerializer(GetType(card))
Dim wholeCard As card = serialize.Deserialize(cardXML)
cardXML.Close()

上面代碼的xml來源是磁盤上的文件。

但有的時候,xml是以字符串的形式給出的。這時候我們該如何處理呢?

從反序列化的定義可知,反序列化是把流轉爲對象。

上面的代碼是以文件流的形式來反序列化。如果是字符串的話,我們就需要把字符串存入內存流中,再把內存流反序列化。

Dim descBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(xmlString)
Dim serialize As XmlSerializer = New XmlSerializer(GetType(card))
Dim wholeCard As card = serialize.Deserialize(New MemoryStream(descBytes))

以上就是xml反序列化的過程。


xml序列化:

'去掉xml聲明
Dim settings As XmlWriterSettings = New XmlWriterSettings()
settings.OmitXmlDeclaration = True
settings.Encoding = Encoding.Default
Dim mem As System.IO.MemoryStream = New MemoryStream()
Using writer As XmlWriter = XmlWriter.Create(mem, settings)

	'去除默認命名空間xmlns:xsd和xmlns:xsi
	Dim nss As XmlSerializerNamespaces = New XmlSerializerNamespaces()
	nss.Add("", "")
	Dim formatter As XmlSerializer = New XmlSerializer(wholeCardA.GetType())
	formatter.Serialize(writer, wholeCardA, nss)
End Using
Dim resultStr as string = Encoding.Default.GetString(mem.ToArray())

該方法實現了序列化xml對象及去掉xml聲明和默認命名空間。


參考文獻:Visual.Basic.2010 & NET 4 高級編程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章