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
¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top