1

我一直在使用.net中的Xml序列化/反序列化,並希望一種方法,其中序列化/反序列化過程只應用於Xml片段的某些部分。這樣我就可以在反序列化過程之後在Xml中保留片段的某些部分。問題允許在某些類型的字段上自定義Xml序列化/反序列化

爲此,我認爲最好創建一個實現IXmlSerializable的新類(XmlLiteral),然後編寫特定的代碼來處理IXmlSerializable.ReadXml和IXmlSerializable.WriteXml方法。

在我的下面這個示例中,它適用於序列化,但是在反序列化過程中,它無法運行以用於我的XmlLiteral類的多次使用。在我的示例中,sTest1正確填充,但sTest2和sTest3是空的。

我猜我必須出錯以下幾行,但無法弄清楚爲什麼..任何想法呢?

Private Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements IXmlSerializable.ReadXml 
     Dim StringType As String = "" 
     If reader.IsEmptyElement OrElse reader.Read() = False Then 
      Exit Sub 
     End If 
     _src = reader.ReadOuterXml() 
    End Sub 

全面上市:

Imports System 
Imports System.Xml.Serialization 
Imports System.Xml 
Imports System.IO 
Imports System.Text 

Public Class XmlLiteralExample 
    Inherits System.Web.UI.Page 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 

     Dim MyObjectInstance As New MyObject 

     MyObjectInstance.aProperty = "MyValue" 
     MyObjectInstance.XmlLiteral1 = New XmlLiteral("<test1>Some Value</test1>") 
     MyObjectInstance.XmlLiteral2 = New XmlLiteral("<test2>Some Value</test2>") 
     MyObjectInstance.XmlLiteral3 = New XmlLiteral("<test3>Some Value</test3>") 

     ' quickly serialize the object to Xml 
     Dim sw As New StringWriter(New StringBuilder()) 
     Dim s As New XmlSerializer(MyObjectInstance.[GetType]()), xmlnsEmpty As New XmlSerializerNamespaces 
     xmlnsEmpty.Add("", "") 
     s.Serialize(sw, MyObjectInstance, xmlnsEmpty) 
     Dim XElement As XElement = XElement.Parse(sw.ToString()) 

     ' XElement reads as the following, so serialization works OK 
     '<MyObject> 
     ' <aProperty>MyValue</aProperty> 
     ' <XmlLiteral1> 
     ' <test1>Some Value</test1> 
     ' </XmlLiteral1> 
     ' <XmlLiteral2> 
     ' <test2>Some Value</test2> 
     ' </XmlLiteral2> 
     ' <XmlLiteral3> 
     ' <test3>Some Value</test3> 
     ' </XmlLiteral3> 
     '</MyObject> 

     ' quickly deserialize the object back to an instance of MyObjectInstance2 
     Dim MyObjectInstance2 As New MyObject 
     Dim xmlReader As XmlReader, x As XmlSerializer 
     xmlReader = XElement.CreateReader 
     x = New XmlSerializer(MyObjectInstance2.GetType()) 
     MyObjectInstance2 = x.Deserialize(xmlReader) 

     Dim sProperty As String = MyObjectInstance2.aProperty ' equal to "MyValue" 
     Dim sTest1 As String = MyObjectInstance2.XmlLiteral1.Text ' contains <test1>Some Value</test1> 
     Dim sTest2 As String = MyObjectInstance2.XmlLiteral2.Text ' is empty 
     Dim sTest3 As String = MyObjectInstance2.XmlLiteral3.Text ' is empty 

     ' sTest3 and sTest3 should be populated but are not? 

     xmlReader = Nothing 

    End Sub 

    Public Class MyObject 
     Private _aProperty As String 
     Private _XmlLiteral1 As XmlLiteral 
     Private _XmlLiteral2 As XmlLiteral 
     Private _XmlLiteral3 As XmlLiteral 

     Public Property aProperty As String 
      Get 
       Return _aProperty 
      End Get 
      Set(ByVal value As String) 
       _aProperty = value 
      End Set 
     End Property 

     Public Property XmlLiteral1 As XmlLiteral 
      Get 
       Return _XmlLiteral1 
      End Get 
      Set(ByVal value As XmlLiteral) 
       _XmlLiteral1 = value 
      End Set 
     End Property 

     Public Property XmlLiteral2 As XmlLiteral 
      Get 
       Return _XmlLiteral2 
      End Get 
      Set(ByVal value As XmlLiteral) 
       _XmlLiteral2 = value 
      End Set 
     End Property 

     Public Property XmlLiteral3 As XmlLiteral 
      Get 
       Return _XmlLiteral3 
      End Get 
      Set(ByVal value As XmlLiteral) 
       _XmlLiteral3 = value 
      End Set 
     End Property 

     Public Sub New() 
      _XmlLiteral1 = New XmlLiteral 
      _XmlLiteral2 = New XmlLiteral 
      _XmlLiteral3 = New XmlLiteral 
     End Sub 

    End Class 

    <System.Xml.Serialization.XmlRootAttribute(Namespace:="", IsNullable:=False)> _ 
    Public Class XmlLiteral 
     Implements IXmlSerializable 
     Private _src As String 

     Public Property Text() As String 
      Get 
       Return _src 
      End Get 
      Set(ByVal value As String) 
       _src = value 
      End Set 
     End Property 

     Public Sub New() 
      _src = "" 
     End Sub 

     Public Sub New(ByVal Text As String) 
      _src = Text 
     End Sub 

#Region "IXmlSerializable Members" 

     Private Function GetSchema() As System.Xml.Schema.XmlSchema Implements IXmlSerializable.GetSchema 
      Return Nothing 
     End Function 

     Private Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements IXmlSerializable.ReadXml 
      Dim StringType As String = "" 
      If reader.IsEmptyElement OrElse reader.Read() = False Then 
       Exit Sub 
      End If 
      _src = reader.ReadOuterXml() 
     End Sub 

     Private Sub WriteXml(ByVal writer As System.Xml.XmlWriter) Implements IXmlSerializable.WriteXml 
      writer.WriteRaw(_src) 
     End Sub 

#End Region 

    End Class 

End Class 

回答

1

管理人的工作更上ReadXml方法一定要解決這個問題。經過更多的研究後,我發現使用reader.ReadEndElement()來結束ReadXml方法非常重要,以便下一個閱讀器能夠正常工作。希望這個解決方案可以幫助別人!

Private Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements IXmlSerializable.ReadXml 
     If reader.IsEmptyElement OrElse reader.Read() = False Then 
      Exit Sub 
     End If 
     While reader.NodeType <> System.Xml.XmlNodeType.EndElement 
      _src = reader.ReadOuterXml 
     End While 
     reader.ReadEndElement() 
    End Sub