views:

76

answers:

6

This is one of the entries I have in a huge XML file of over 200 such entries.

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

I am attempting to deserialize this into a class object but failing every time.

This is my code so far:

using System;

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

namespace DeserializeXML { public class Program {

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


}

}

When I execute it, I only see "Reading with Stream" on the console, and nothing else.

EDIT

I just realized I say only 'Reading with stream" because it was still reading. After about 5 seconds, this is what I got:

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

After making my Program class public, I now get this error:

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

made a bunch of changes to my code (as reflected above). Had some items listed twice, double checked case etc. I now get this error:

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 ---
+3  A: 

Try changing this:

class Program
    {

to this

public class Program
    {

If you don't specify an access modifier then it uses the default of internal

Abe Miessler
Thanks, that did solve part of the problem. I'm getting another error now, though. See the edit.
xbonez
You have qwGroupTransId used for two elements. See my answer
SwDevMan81
A: 
  1. The casing matters greatly in xml. Some of your XmlElement tags casing differs from source.
  2. Construct a test object of class Program in the code and serialize it. Compare the result to your source to see where you got it wrong.
Goran
+1  A: 
  1. Element qwGroupTransId is mentioned twice. You have it in its own element and as a name on GroupTransId, so the deserializer doesn't know where to put values for it.
  2. Your value for the FillTime is invalid.
  3. You're trying to deserialize a TradeFill, but the actual xml is a CarCollection.
Yuriy Faktorovich
Taken care of all points, and edited my question
xbonez
@xbonez: I don't think you did. It looks like your serializer is still of the wrong type.
Yuriy Faktorovich
Do you mean I need to change this: public class SIGTrades to this: public class TradeFill ?
xbonez
@xbonez [Here](http://pastebin.com/y3e2Pq0X) Are the changes I've made to make everything work. I also changed it to static, you don't need an instance of your `Program`.
Yuriy Faktorovich
Hey...thanks a lot for taking the time to help me out. I made the changes as per your program, but I now get this error: Unhandled Exception: System.InvalidOperationException: There is an error in XMLdocument (26, 4). ---> System.FormatException: The string '2010-09-20 11:40:08'is not a valid AllXsd value.
xbonez
@xbonez DateTime serialized looks like 0001-01-01T00:00:00. So that date would look like 2010-09-22T11:40:08
Yuriy Faktorovich
oh....and what if the XML file (which is produced by a 3rd party s/w in my case) does not output in that format), is there anything I can do about it?
xbonez
@xbonez you could deserialize it to a string property. Implement the `IDeserializationCallback ` which parses it using `DateTime.Parse` and places it into the correct property.
Yuriy Faktorovich
woot! Its working now!! Thanks a ton!
xbonez
@xbonez use `Console.Write(i.TradeFills[0].qwFillTransID);`. Note the difference in capitalization of ID between your class and the xml file.
Yuriy Faktorovich
A: 

For you second edit, you need to do the following:

        // ... 

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

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

        // ...
SwDevMan81
+1  A: 

Hello, this is a Deserializing function, it takes an XML string .

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

Replace %object% with your class object .

Arrabi
Tried your function. I now get this error
xbonez
Unhandled Exception: System.InvalidOperationException: There is an error in XMLdocument (1, 1). ---> System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.
xbonez
are you giving any null values in your xml ? because int or bool cant be null.
Arrabi
Nope, no null values
xbonez
if can add this to the root node you have which is <TradeFills xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
Arrabi
Unhandled Exception: System.InvalidOperationException: There is an error in XMLdocument (1, 1). ---> System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.
xbonez
there is something wrong with your xml or the class , so why dont you try to remove all your class properties so the xml will have just one node : <TradeFills> <TradeFill> <Broker>xxx</Broker> </TradeFill> </TradeFills> , just one string property . just to try our function
Arrabi
A: 

I once ran into a bug in XmlSerializer that apparently does not like large lists of nested elements under some circumstances and gives the same symptoms you are observing.

Back then I found a confirmation of this, but I cannot find the link anymore. Here (scroll down to John Saunder's answers) you can read about that issue.

Francesco De Vittori