Десериализация XML в класс obj в C # - PullRequest
1 голос
/ 22 сентября 2010

Это одна из моих записей в огромном XML-файле, содержащем более 200 таких записей.

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

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


}

}

Когда я выполняю его, я вижу только «Чтение с потоком» на консоли и ничего больше.

EDIT

Я только что понял, что говорю только «Чтение с потоком», потому что он все еще читал. Примерно через 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

EDIT

После обнародования моего класса 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)

EDIT

произвел кучу изменений в моем коде (как показано выше). Если бы некоторые пункты были перечислены дважды, дважды отмечены, я теперь получаю эту ошибку:

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 ]

5 голосов
/ 22 сентября 2010

Попробуйте изменить это:

class Program
    {

к этому

public class Program
    {

Если вы не укажете модификатор доступа, он будет использовать значение по умолчанию internal

3 голосов
/ 22 сентября 2010

это функция десериализации, она принимает строку 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 голосов
/ 22 сентября 2010
  1. Элемент qwGroupTransId упоминается дважды. Вы имеете его в своем собственном элементе и в качестве имени в GroupTransId, поэтому десериализатор не знает, куда поместить значения для него.
  2. Ваше значение для FillTime недопустимо.
  3. Вы пытаетесь десериализовать TradeFill, но фактический xml - это CarCollection.
1 голос
/ 22 сентября 2010

Однажды я столкнулся с ошибкой в ​​XmlSerializer, которая, по-видимому, не любит большие списки вложенных элементов при некоторых обстоятельствах и дает те же симптомы, которые вы наблюдаете.

Тогда я нашел подтверждение этому, но больше не могу найти ссылку. Здесь (прокрутите вниз до ответов Джона Сандера), вы можете прочитать об этой проблеме.

1 голос
/ 22 сентября 2010

Для второго редактирования вам необходимо сделать следующее:

        // ... 

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

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

        // ...
1 голос
/ 22 сентября 2010
  1. Оболочка имеет большое значение в XML.Некоторые из ваших тегов XmlElement отличаются от исходного.
  2. Построить тестовый объект класса Program в коде и сериализовать его.Сравните результат с вашим источником, чтобы увидеть, где вы ошиблись.
...