【问题标题】:Deserializing XML into class obj in C#在 C# 中将 XML 反序列化为类 obj
【发布时间】:2010-09-22 14:18:35
【问题描述】:

这是我在一个包含 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;

命名空间反序列化XML { 公开课程序 {

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


}

}

当我执行它时,我只在控制台上看到“Reading with Stream”,没有别的。

编辑

我刚刚意识到我只说“阅读流”,因为它仍在阅读。大约 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 ---

【问题讨论】:

  • 你的 qwGroupTransId 在课堂上列出了两次。
  • 您可能会考虑将这些问题分解为单独的问题?它变成了一个非常长的帖子,每次编辑似乎都是它自己的问题......

标签: c# .net xml xml-serialization


【解决方案1】:

尝试改变这个:

class Program
    {

到这里

public class Program
    {

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

【讨论】:

  • 谢谢,这确实解决了部分问题。不过,我现在又遇到了另一个错误。查看编辑。
  • 您将 qwGroupTransId 用于两个元素。看我的回答
【解决方案2】:

这是一个反序列化函数,它需要一个 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% 替换为您的类 object 。

【讨论】:

  • 未处理异常:System.InvalidOperationException:XML 文档 (1, 1) 中存在错误。 ---> System.Xml.XmlException: 根级别的数据无效。第 1 行,位置 1。
  • 您是否在 xml 中提供任何空值?因为 int 或 bool 不能为 null。
  • 如果可以将此添加到您拥有的根节点,即
  • 未处理异常:System.InvalidOperationException:XML 文档 (1, 1) 中存在错误。 ---> System.Xml.XmlException: 根级别的数据无效。第 1 行,位置 1。
  • 你的 xml 或类有问题,为什么不尝试删除所有类属性,这样 xml 将只有一个节点:xxx ,只有一个字符串属性。只是为了尝试我们的功能
【解决方案3】:
  1. 元素qwGroupTransId 被提及两次。您将它放在自己的元素中并作为 GroupTransId 上的名称,因此反序列化器不知道将值放在哪里。
  2. FillTime 的值无效。
  3. 您正在尝试反序列化 TradeFill,但实际的 xml 是 CarCollection

【讨论】:

  • @xbonez:我认为你没有。看起来你的序列化器仍然是错误的类型。
  • 你的意思是我需要把这个:public class SIGTrades 改成这个:public class TradeFill 吗?
  • @xbonez Here 我所做的更改是为了让一切正常工作。我也将其更改为静态,您不需要 Program 的实例。
  • 嘿...非常感谢您花时间帮助我。我根据您的程序进行了更改,但现在出现此错误:未处理的异常:System.InvalidOperationException:XML 文档中存在错误 (26, 4)。 ---> System.FormatException:字符串 '2010-09-20 11:40:08' 不是有效的 AllXsd 值。
  • @xbonez DateTime 序列化看起来像 0001-01-01T00:00:00。所以那个日期看起来像 2010-09-22T11:40:08
【解决方案4】:
  1. 大小写在 xml 中非常重要。您的某些 XmlElement 标记外壳与源不同。
  2. 在代码中构造类Program的测试对象并序列化。将结果与您的来源进行比较,看看哪里出错了。

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

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

      当时我找到了对此的确认,但我再也找不到链接了。 Here(向下滚动到 John Saunder 的答案)您可以阅读有关该问题的信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-12
        • 2021-11-05
        相关资源
        最近更新 更多