【问题标题】:Cannot parse simple XML into an object?无法将简单的 XML 解析为对象?
【发布时间】:2014-10-08 12:34:48
【问题描述】:

XML

<MeterWalkOrder>
  <Name>Red Route</Name>
  <Meters>
    <Meter>
      <MeterID>1</MeterID>
      <SerialNumber>12345</SerialNumber>
    </Meter>
    <Meter>
      <MeterID>2</MeterID>
      <SerialNumber>SE</SerialNumber>
    </Meter>
  </Meters>
</MeterWalkOrder>

我无法使用任何序列化程序将简单的 XML 放入对象中

var xml = File.ReadAllText("WalkOrder.xml");
var xmlSerializer = new NFormats.Xml.XmlSerializer();
var obj = xmlSerializer.Deserialize<MeterWalkOrder>(new StringReader(xml));

我刚取回 2 米长的物体,没有设置任何属性,甚至没有按步行顺序设置名称。

 public partial class MeterWalkOrder
 {
        public MeterWalkOrder()
        {
            Meters = new List<Meter>();
        }

        [DataMember]
        public String Name { get; set; }
     }
}

using System;
using System.Xml.Serialization;

namespace WindowsFormsApplication1.Classes
{    
    public class Meter : IMeter
    {
        [XmlAttribute]
        public int MeterID { get; set; }

        [XmlAttribute]
        public String SerialNumber { get; set; }
    }
}

我愿意尝试任何 xml 序列化程序。

【问题讨论】:

  • MeterIDSerialNumber 不是 Meter 对象的属性;它们是元素。尝试用[XmlElement] 替换[XmlAttribute] 标签。

标签: c# xml xml-serialization xml-deserialization


【解决方案1】:

首先我建议你阅读Introducing XML Serialization on MSDN 您犯了几个错误,导致在运行代码时引发未提及的异常。

  1. 在您的 Xml MeterID 和 SerialNumber 中不是属性,它们是元素。 (正如 Wyat Earp 评论的那样)
  2. 如果你想序列化某些东西,你必须告诉它应该是 [Serializable]
  3. 序列化需要一个已实现的公共空构造函数
  4. 不关闭流时不要打开流(使用“使用”)
  5. 要测试您的序列化是否效果最好,首先进行序列化,然后检查输出,然后实施反序列化

在下面找到一个完整的示例:

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

namespace X123
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            MeterWalkOrder mo = new MeterWalkOrder();
            mo.Name = "name";
            mo.Meters.Add(new Meter { MeterID = 1, SerialNumber = "kdkdkd" });
            mo.Meters.Add(new Meter { MeterID = 2, SerialNumber = "holladrio" });

            var xmlSerializer = new XmlSerializer(typeof(MeterWalkOrder), new Type[] { typeof(Meter) });
            {
                xmlSerializer.Serialize(File.CreateText("hello.xml"), mo);
                using (Stream s = File.OpenRead("hello.xml"))
                {
                    var obj = xmlSerializer.Deserialize(s);
                }
            }
        }



    }

    [Serializable]
    public class MeterWalkOrder
    {
        public MeterWalkOrder()
        {
        }

        public string Name { get; set; }
        public List<Meter> Meters { get { return meters; } set { meters = value; } }
        private List<Meter> meters = new List<Meter>();
    }

    [Serializable]
    public class Meter
    {
        public Meter()
        {
        }

        [XmlAttribute]
        public int MeterID { get; set; }

        [XmlAttribute]
        public string SerialNumber { get; set; }
    }

【讨论】:

  • 谢谢,可惜我不能勾选 2!!
【解决方案2】:

我使用您的示例 XML 并使用 Paste Special -&gt; Paste XML as Classes 在 VisualStudio 中生成了类,对它们进行了一些修改以使其更具可读性,并从中获得了以下类定义:

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public class MeterWalkOrder
{
  public string Name { get; set; }

  [System.Xml.Serialization.XmlArrayItemAttribute("Meter", IsNullable = false)]
  public List<MeterWalkOrderMeter> Meters { get; set; }
}

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public class MeterWalkOrderMeter
{
  public int MeterID { get; set; }
  public string SerialNumber { get; set; }
}

使用上面的类和下面的代码,它生成的对象没有错误。

string inputXml = File.ReadAllText(@"C:\Temp\SOTest.xml");
//using System.Xml.Serialization;
System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(MeterWalkOrder));
MeterWalkOrder outputObject = xmlSerializer.Deserialize(new StringReader(inputXml)) as MeterWalkOrder;

【讨论】:

  • 非常感谢!我勾选了其他回复,因为您的回复非常适合我的确切问题,但其他回复可以帮助其他犯同样错误的人!
  • 这一切都很好,我也错过了属性部分,但这就是为什么我们都在这里提供帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-16
  • 2016-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多