无法将简单的XML解析为对象?

时间:2014-10-08 12:34:49

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

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序列化程序。

2 个答案:

答案 0 :(得分:1)

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

    您的Xml MeterID和SerialNumber中的
  1. 不是它们是元素的属性。 (如Wyat Earp评论)
  2. 如果你想序列化某些东西,你必须告诉它应该是[Serializable]
  3. 序列化需要实现的公共空构造函数
  4. 当你没有关闭它们时不要打开流(使用“使用”)
  5. 要测试序列化是否最佳,首先序列化,然后检查输出然后实现反序列化
  6. 在下面找到一个完整的例子:

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

答案 1 :(得分:1)

我使用了您的示例XML并使用Paste Special -> 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;