Deserializar cadena XML a tipo complejo

My Xml (which I can't change):

<result>
    <type>MAZDA</type>
    <make>RX-8</type>
    <country>JAPAN</country>
</result>

Mi modelo:

[Serializable, XmlRoot("result")]
public class VehicleDetails
{
    public string Type { get; set; }
    public string Make { get; set; }
    public string Country { get; set; }
}

de-serializing this XML works as expected but I want to change the Country property to a complex type, like so:

public Country Country { get; set; }

and put the country name, "JAPAN", in the Country.Name property, any ideas?

preguntado el 01 de julio de 12 a las 16:07

2 Respuestas

Podrías decorar el Name propiedad de tu Country clase con el [XmlText] atributo como este:

[XmlRoot("result")]
public class VehicleDetails
{
    public string Type { get; set; }
    public string Make { get; set; }
    public Country Country { get; set; }
}

public class Country
{
    [XmlText]
    public string Name { get; set; }
}

Also notice that I have gotten rid of the [Serializable] attribute. It is useless for XML serialization. This attribute is used for binary/remoting serialization.

And here's a full example that will print JAPAN como se esperaba:

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

[XmlRoot("result")]
public class VehicleDetails
{
    public string Type { get; set; }
    public string Make { get; set; }
    public Country Country { get; set; }
}

public class Country
{
    [XmlText]
    public string Name { get; set; }
}

class Program
{
    static void Main()
    {
        var serializer = new XmlSerializer(typeof(VehicleDetails));
        var xml = 
        @"<result>
            <Type>MAZDA</Type>
            <Make>RX-8</Make>
            <Country>JAPAN</Country>
        </result>";
        using (var reader = new StringReader(xml))
        using (var xmlReader = XmlReader.Create(reader))
        {
            var result = (VehicleDetails)serializer.Deserialize(xmlReader);
            Console.WriteLine(result.Country.Name);
        }
    }
}

Respondido 01 Jul 12, 16:07

Thanks Darin, works great. Can I amalgrate two XML nodes into one complex type? e.g. <result><errorcode>0</errorcode><errormessage>error</errormessage>, put these two properties into one public Error Error { get; set; } property, where the type Error tiene dos propiedades, code y message? - eth0

Here is the VB 2010 equivalent...

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

Public Module Module1

    Public Sub Main()
        Dim serializer = New XmlSerializer(GetType(VehicleDetails))
        Dim xml = "<result>             <Type>MAZDA</Type>             <Make>RX-8</Make>             <Country>JAPAN</Country>         </result>"

        Using reader = New StringReader(xml)
            Using xmlReader__1 = XmlReader.Create(reader)
                Dim result = DirectCast(serializer.Deserialize(xmlReader__1), VehicleDetails)
                Console.WriteLine(result.Country.Name)
            End Using
        End Using
    End Sub

    <XmlRoot("result")> _
    Public Class VehicleDetails

        Public Property Type() As String
            Get
                Return m_Type
            End Get
            Set(value As String)
                m_Type = value
            End Set
        End Property
        Private m_Type As String


        Public Property Make() As String
            Get
                Return m_Make
            End Get
            Set(value As String)
                m_Make = value
            End Set
        End Property
        Private m_Make As String
        Public Property Country() As Country
            Get
                Return m_Country
            End Get
            Set(value As Country)
                m_Country = value
            End Set
        End Property
        Private m_Country As Country

    End Class
    Public Class Country
        <XmlText()> _
        Public Property Name() As String
            Get
                Return m_Name
            End Get
            Set(value As String)
                m_Name = value
            End Set
        End Property
        Private m_Name As String
    End Class

End Module

Respondido 25 Jul 12, 15:07

Problem is, I would like to be able to do this on the fly, not hard code everything before hand. Would like to be able to call a function with an XML object as the parameter and have it return an object or have the XML object itself be adressable like we have it. Without being able to create properties from strings discovered at runtime, I cannot make this function.. :( - Newby

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.