Permitiendo emitir encargo serialización XML / Deserialización en ciertos tipos de terreno
-
02-10-2019 - |
Pregunta
he estado trabajando con XML serialización / deserialización en .NET y quería un método en el que el proceso de serialización / deserialización sólo se aplica a ciertas partes de un fragmento de XML. Esto es para que pueda mantener ciertas partes del fragmento en XML después del proceso de deserialización.
Para ello pensé que sería mejor para crear una nueva clase (XmlLiteral) que implementa IXmlSerializable y luego escribió un código específico para el manejo de los métodos IXmlSerializable.ReadXml y IXmlSerializable.WriteXml.
En mi ejemplo, por debajo de esta obra para serializar, sin embargo, durante el proceso de deserialización no se ejecuta para múltiples usos de mi clase XmlLiteral. En mi ejemplo a continuación sTest1 se rellena correctamente, pero sTest2 y sTest3 están vacías.
supongo que tengo que ir mal con las siguientes líneas, pero no puedo entender por qué .. Cualquier idea en absoluto?
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
lista completa:
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
Solución
Gestionado para solucionar este problema mediante el trabajo un poco más sobre el método ReadXml. Después de más investigación descubrí que es muy importante para acabar con el método ReadXml con reader.ReadEndElement () para que el siguiente lector funciona correctamente. Esperamos que este Solutions ayuda a alguien!
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