1

Je travaillais avec la sérialisation/désérialisation Xml dans .net et je voulais une méthode où le processus de sérialisation/désérialisation ne serait appliqué qu'à certaines parties d'un fragment Xml. C'est ainsi que je peux garder certaines parties du fragment en Xml après le processus de désérialisation. Pour ce faire, j'ai pensé qu'il serait préférable de créer une nouvelle classe (XmlLiteral) qui a implémenté IXmlSerializable, puis écrit un code spécifique pour gérer les méthodes IXmlSerializable.ReadXml et IXmlSerializable.WriteXml. Dans mon exemple ci-dessous, cela fonctionne pour la sérialisation, mais pendant le processus de désérialisation, il ne fonctionne pas pour plusieurs utilisations de ma classe XmlLiteral. Dans mon exemple ci-dessous, sTest1 est rempli correctement, mais sTest2 et sTest3 sont vides.Problème permettant la sérialisation/désérialisation Xml personnalisée sur certains types de champ

Je suppose que je dois me tromper avec les lignes suivantes, mais ne peux pas comprendre pourquoi .. Des idées du tout?

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 

Fiche complète:

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 

Répondre

1

Réussi à résoudre ce problème en travaillant un peu plus sur la méthode ReadXml. Après plus de recherches, j'ai découvert qu'il est très important de terminer la méthode ReadXml avec reader.ReadEndElement() afin que le lecteur suivant fonctionne correctement. J'espère que cette solution aide quelqu'un!

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