【问题标题】:Deserialize XML string to complex type将 XML 字符串反序列化为复杂类型
【发布时间】:2012-07-01 15:02:56
【问题描述】:

我的 Xml(我无法更改):

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

我的模特:

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

反序列化此 XML 可以按预期工作,但我想将 Country 属性更改为复杂类型,如下所示:

public Country Country { get; set; }

Country.Name 属性中输入国家名称“JAPAN”,有什么想法吗?

【问题讨论】:

    标签: c# xml deserialization


    【解决方案1】:

    您可以使用[XmlText] 属性来装饰Country 类的Name 属性,如下所示:

    [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; }
    }
    

    还要注意我已经去掉了[Serializable] 属性。它对 XML 序列化毫无用处。该属性用于二进制/远程序列化。

    这是一个完整的示例,将按预期打印JAPAN

    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);
            }
        }
    }
    

    【讨论】:

    • 谢谢达林,效果很好。我可以将两个 XML 节点合并为一种复杂类型吗?例如&lt;result&gt;&lt;errorcode&gt;0&lt;/errorcode&gt;&lt;errormessage&gt;error&lt;/errormessage&gt;,把这两个属性合为一个public Error Error { get; set; }属性,其中Error类型有两个属性codemessage?
    【解决方案2】:

    这是 VB 2010 的等价物...

    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
    

    【讨论】:

    • 问题是,我希望能够即时执行此操作,而不是事先对所有内容进行硬编码。希望能够以 XML 对象作为参数调用函数并让它返回一个对象,或者让 XML 对象本身像我们拥有的那样可寻址。由于无法从运行时发现的字符串创建属性,我无法创建此功能.. :(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多