将 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; }
}
}
或者有更好的方法吗?
items 应该是 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>();
}
或者只为项目class设置类型属性(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; }
}
当然还有制作属性public
变量需要 public.
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:Deserializing nested lists with 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; }
}
}
另请注意,我将字符串 reader 封装在一个 using 块中,以便在读取结束后处理该对象。
我有以下 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; }
}
}
或者有更好的方法吗?
items 应该是 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>();
}
或者只为项目class设置类型属性(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; }
}
当然还有制作属性public
变量需要 public.
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:Deserializing nested lists with 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; }
}
}
另请注意,我将字符串 reader 封装在一个 using 块中,以便在读取结束后处理该对象。