繁体   English   中英

将XML反序列化为具有C#中的对象列表的对象

[英]Deserializing XML to objects which has list of objects in C#

我有以下要反序列化为对象的xml。

<result>
    <reporttype>2</reporttype>
    <items>
        <item>
            <sku>0B0005</sku>
            <style>0B0005.DAK.GREY</style>
            <reason>Barcode cannot be moved to different SKUs</reason>
        </item>
        <item>
            <sku>0B0006</sku>
            <style>0B0006.DAK.GREY</style>
            <reason>Barcode cannot be moved to different SKUs</reason>
        </item>
    </items>
</result>

但是下面的代码不会填充项目列表,有人可以指出我在这里做错了吗

string inputString = @"<result><reporttype>2</reporttype><items><item><sku>0B0005</sku><style>0B0005.DAK.GREY</style><reason>Barcode cannot be moved to different SKUs</reason></item><item><sku>0B0005</sku><style>0B0005.DAK.GREY</style><reason>Barcode cannot be moved to different SKUs</reason></item></items></result>";

XmlDocument doc = new XmlDocument();
doc.LoadXml(inputString);

XmlSerializer serializer = new XmlSerializer(typeof(Result));
StringReader rdr = new StringReader(doc.InnerXml);
Result resultingMessage = (Result)serializer.Deserialize(rdr);

public enum ReportType {
    [XmlEnum("0")]
    InternalErrorReport,
    [XmlEnum("1")]
    ErrorReport,
    [XmlEnum("2")]
    InternalSuccessReport
}

[XmlRoot(ElementName = "result")]
public class Result {
    [XmlElement(ElementName = "reporttype")]
    public ReportType reportType { get; set; }
    [XmlElement(ElementName = "items")]
    public List<Item> items = new List<Item>();

    public string error { get; set; }

    public class Item {
        [XmlElement(ElementName = "sku")]
        string sku { get; set; }
        [XmlElement(ElementName = "style")]
        string style { get; set; }
        [XmlElement(ElementName = "reason")]
        string reason { get; set; }
    }
}

还是有更好的方法来做到这一点?

变量需要公开。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(FILENAME);

            XmlSerializer serializer = new XmlSerializer(typeof(Result));
            StringReader rdr = new StringReader(xml);
            Result resultingMessage = (Result)serializer.Deserialize(rdr);


        }
    }
    public enum ReportType
    {
        [XmlEnum("0")]
        InternalErrorReport,
        [XmlEnum("1")]
        ErrorReport,
        [XmlEnum("2")]
        InternalSuccessReport
    }

    [XmlRoot(ElementName = "result")]
    public class Result
    {
        [XmlElement(ElementName = "reporttype")]
        public ReportType reportType { get; set; }
        public Items items { get; set; }
        public string error { get; set; }


    }
    [XmlRoot("items")]
    public class Items
    {
        [XmlElement(ElementName = "item")]
        public List<Item> items = new List<Item>();
    }
    [XmlRoot("item")]
    public class Item
    {
        [XmlElement(ElementName = "sku")]
        public string sku { get; set; }
        [XmlElement(ElementName = "style")]
        public string style { get; set; }
        [XmlElement(ElementName = "reason")]
        public string reason { get; set; }
    }
}

如此处所述,您需要将列表标记为XmlArray并同时指定XmlArrayItem: 使用XmlSerializer反序列化嵌套列表

因此,代码变为:

        string inputString = @"<result><error>error test</error><reporttype>2</reporttype><items><item><sku>0B0005</sku><style>0B0005.DAK.GREY</style><reason>Barcode cannot be moved to different SKUs</reason></item><item><sku>0B0005</sku><style>0B0005.DAK.GREY</style><reason>Barcode cannot be moved to different SKUs</reason></item></items></result>";

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(inputString);

        XmlSerializer serializer = new XmlSerializer(typeof(Result));
        object resultingMessage = null;
        using (StringReader rdr = new StringReader(doc.InnerXml)) {
            resultingMessage = (Result)serializer.Deserialize(rdr);
        }

和类:

public enum ReportType {
    [XmlEnum("0")]
    InternalErrorReport,
    [XmlEnum("1")]
    ErrorReport,
    [XmlEnum("2")]
    InternalSuccessReport
}

[XmlRoot(ElementName = "result")]
public class Result {
    [XmlElement(ElementName = "reporttype")]
    public ReportType reporttype { get; set; }
    [XmlArray("items")]
    [XmlArrayItem("item")]
    public List<Item> items { get; set; }
    [XmlElement(ElementName = "error")]
    public string error { get; set; }

    [XmlRoot(ElementName = "items\\item")]
    public class Item {
        [XmlElement(ElementName = "sku")]
        public string sku { get; set; }
        [XmlElement(ElementName = "style")]
        public string style { get; set; }
        [XmlElement(ElementName = "reason")]
        public string reason { get; set; }
    }

}

还请注意,我将字符串读取器封装在using块中,以便在读取结束后立即处置对象。

项目应该是Xmlroot元素,并且包含XmlElement项目,您必须告诉它何时反序列化为对象。 尝试这个 :

public class Item
{
    [XmlElement(ElementName = "sku")]
    public string Sku { get; set; }
    [XmlElement(ElementName = "style")]
    public string Style { get; set; }
    [XmlElement(ElementName = "reason")]
    public string Reason { get; set; }
}

[XmlRoot(ElementName = "items")]
public class Items
{
    [XmlElement(ElementName = "item")]
    public List<Item> Item { get; set; }
}

[XmlRoot(ElementName = "result")]
public class Result
{
    [XmlElement(ElementName = "reporttype")]
    public string Reporttype { get; set; }
    [XmlElement(ElementName = "items")]
    public Items Items { get; set; }
}

您可以为items属性添加两个属性-满足序列化

[XmlRoot(ElementName = "result")]
public class Result 
{
    [XmlArray("items")]
    [XmlArrayItem("item")]
    public List<Item> items = new List<Item>();
}

或者只需为Item类设置type属性( XmlType )。
这样就足以仅将XmlArray属性用于Result.items属性。 还是根本不使用任何属性,因为属性名称与xml中元素的名称匹配。

[XmlType("item")]
public class Item 
{
    [XmlElement(ElementName = "sku")]
    public string sku { get; set; }
    [XmlElement(ElementName = "style")]
    public string style { get; set; }
    [XmlElement(ElementName = "reason")]
    public string reason { get; set; }
}

当然也要公开物业

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM