在C#中将XML反序列化为类obj

时间:2010-09-22 14:18:36

标签: c# .net xml xml-serialization

这是我在200多个此类条目的巨大XML文件中的条目之一。

<TradeFills>
 <TradeFill>
  <Broker>xxx</Broker>
  <CustomerAccount/>
  <qwFillTransID>xxxxxxxxxxxxxxxxxxx</qwFillTransID>
  <qwPrevTransID>xxx</qwPrevTransID>
  <qwGroupTransID>xxxxxxxxxxxxxxxxx</qwGroupTransID>
  <GroupTransID>xxxxxxxx</GroupTransID>
  <TransID>x</TransID>
  <Service>xxxxxxxxxxxxxxxx</Service>
  <Symbol>xx</Symbol>
  <Exchange>xxxxx</Exchange>
  <InstClass>xxxxxxxx</InstClass>
  <InstSubClass>xxxxxxx</InstSubClass>
  <ContractSymbol>xxxx</ContractSymbol>
  <ExpirationDate>xxxxxxxx</ExpirationDate>
  <Month>xx</Month>
  <Year>xxxx</Year>
  <Strike>xxx</Strike>
  <TradePCU>xxxx</TradePCU>
  <Buy>x</Buy>
  <Quantity>xx</Quantity>
  <Price>xxxxx</Price>
  <FillTime>xxxxxxxxxxxxxxx</FillTime>
  <PosUpdated>xxxxxxxxxxx</PosUpdated>
  <Description/>
 </TradeFill>
</TradeFills>

我试图将其反序列化为类对象,但每次都失败。

到目前为止,这是我的代码:

using System;

使用System.Collections.Generic; 使用System.Text; 使用System.IO; 使用System.Xml.Serialization;

命名空间DeserializeXML {     公共课程     {

    // This is the class that will be deserialized.
    [Serializable()]
    public class TradeFill
    {
        [XmlElement("Broker")]
        public string broker;

        [XmlElement("qwFillTransID")]
        public string qwFillTransId;

        [XmlElement("qwPrevTransID")]
        public string qwPrevTransId;

        [XmlElement("qwGroupTransID")]
        public string qwGroupTransId;

        [XmlElement("GroupTransID")]
        public string GroupTransID;

        [XmlElement("TransID")]
        public string TransId;

        [XmlElement("Service")]
        public string Service;

        [XmlElement("Exchange")]
        public string Exchange;

        [XmlElement("InstClass")]
        public string InstClass;

        [XmlElement("InstSubClass")]
        public string InstSubClass;

        [XmlElement("ContractSymbol")]
        public string ConSymbol;

        [XmlElement("ExpirationDate")]
        public DateTime ExpDate;

        [XmlElement("Month")]
        public int month;

        [XmlElement("Year")]
        public int year;

        [XmlElement("Strike")]
        public double strike;

        [XmlElement("TradePCU")]
        public string TradePCU;

        [XmlElement("Buy")]
        public int buy;

        [XmlElement("Quantity")]
        public int quantity;

        [XmlElement("Price")]
        public double price;

        [XmlElement("FillTime")]
        public DateTime FillTime;

        [XmlElement("PosUpdated")]
        public string PosUpdated;

    }


    [XmlRootAttribute("TradeFills")]
    public class SIGTrades
    {
        [XmlElement("TradeFills")]
        public TradeFill[] TradeFills{ get; set; }
    }


    [Serializable()]
    public class Test
    {
         public static void Main()
        {
            Test t = new Test();
          // Read a purchase order.
            t.DeserializeObject("c:\\test.xml");
        }

        private void DeserializeObject(string filename)
        {   
            Console.WriteLine("Reading with Stream");
            // Create an instance of the XmlSerializer.
            XmlSerializer serializer =
            new XmlSerializer(typeof(TradeFill));
            // Reading the XML document requires a FileStream.
            Stream reader= new FileStream(filename,FileMode.Open);

            // Declare an object variable of the type to be deserialized.
            TradeFill i;

            // Call the Deserialize method to restore the object's state.
            i = (TradeFill)serializer.Deserialize(reader);

            // Write out the properties of the object.
            Console.Write(i.qwFillTransId);
        }
    }


}

}

当我执行它时,我只在控制台上看到“正在阅读”,而没有别的。

修改

我刚刚意识到我只说“正在阅读”,因为它仍在阅读。大约5秒后,这就是我所得到的:

Unhandled Exception: System.InvalidOperationException: DeserializeXML.Program is
 inaccessible due to its protection level. Only public types can be processed.
   at System.Xml.Serialization.TypeDesc.CheckSupported()
   at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo sourc
e, Boolean directReference, Boolean throwOnError)
   at System.Xml.Serialization.TypeScope.ImportTypeDesc(Type type, MemberInfo me
mberInfo, Boolean directReference)
   at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo sourc
e, Boolean directReference, Boolean throwOnError)
   at System.Xml.Serialization.ModelScope.GetTypeModel(Type type, Boolean direct
Reference)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type
, XmlRootAttribute root, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultName
space)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type)
   at DeserializeXML.Program.Test.DeserializeObject(String filename) in c:\docum
ents and settings\sobti\my documents\visual studio 2010\Projects\DeserializeXML\
DeserializeXML\Program.cs:line 109
   at DeserializeXML.Program.Test.Main() in c:\documents and settings\sobti\my d
ocuments\visual studio 2010\Projects\DeserializeXML\DeserializeXML\Program.cs:li
ne 102

修改

将我的Program类公开后,我现在收到此错误:

Unhandled Exception: System.InvalidOperationException: There was an error reflec
ting type 'DeserializeXML.Program.TradeFill'. ---> System.InvalidOperationExcept
ion: There was an error reflecting field 'GroupTransId'. ---> System.InvalidOper
ationException: The XML element 'qwGroupTransId' from namespace '' is already pr
esent in the current scope. Use XML attributes to specify another XML name or na
mespace for the element.
   at System.Xml.Serialization.XmlReflectionImporter.AddUniqueAccessor(INameScop
e scope, Accessor accessor)
   at System.Xml.Serialization.XmlReflectionImporter.AddUniqueAccessor(MemberMap
ping member, INameScope elements, INameScope attributes, Boolean isSequence)
   at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(Str
uctMapping mapping, StructModel model, Boolean openModel, String typeName, Recur
sionLimiter limiter)

修改

对我的代码进行了一系列更改(如上所示)。有一些项目列出两次,双重检查案件等我现在得到这个错误:

Unhandled Exception: System.InvalidOperationException: There is an error in XML
document (2, 2). ---> System.InvalidOperationException: <TradeFills xmlns=''> wa
s not expected.
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderTradeF
ill.Read3_TradeFill()
   --- End of inner exception stack trace ---

6 个答案:

答案 0 :(得分:5)

尝试更改此内容:

class Program
    {

到这个

public class Program
    {

如果您未指定访问修饰符,则它使用默认值internal

答案 1 :(得分:3)

这是一个反序列化函数,它采用XML字符串。

public %object% DeserializeGSFiles(string content)
    {
        Type type = typeof(%object%);
        XmlSerializer xmlSerializer;
        byte[] byteArray = Encoding.UTF8.GetBytes(content);
        MemoryStream stream = new MemoryStream(byteArray);
        try
        {
            xmlSerializer = new XmlSerializer(type);
            %object% objectFromXml = (%object%)xmlSerializer.Deserialize(stream);
            return objectFromXml;
        }
        catch (Exception Ex)
        {
            throw Ex;
        }
    }

将%object%替换为您的类对象。

答案 2 :(得分:2)

  1. 元素qwGroupTransId被提及两次。你有它自己的元素和GroupTransId上的名字,所以反序列化器不知道在哪里放置值。
  2. FillTime的值无效。
  3. 您正在尝试反序列化TradeFill,但实际的xml是CarCollection

答案 3 :(得分:1)

  1. 外壳在xml中非常重要。您的某些XmlElement标记框与源不同。
  2. 在代码中构造类Program的测试对象并对其进行序列化。将结果与您的来源进行比较,看看你哪弄错了。

答案 4 :(得分:1)

对于第二次编辑,您需要执行以下操作:

        // ... 

        [XmlElement ("qwGroupTransId")] // Or just leave off
        public string qwGroupTransId;

        [XmlElement ("GroupTransId")] // Or just leave off
        public string GroupTransId;

        // ...

答案 5 :(得分:1)

我曾经遇到过XmlSerializer中的一个错误,它在某些情况下显然不喜欢嵌套元素的大型列表,并且给出了您正在观察的相同症状。

当时我发现了对此的确认,但我找不到链接了。 Here(向下滚动到John Saunder的答案)你可以阅读这个问题。