CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Jun 2001
    Location
    Melbourne/Aus (C# .Net 4.0)
    Posts
    686

    Serialization from Xml into Object

    First, I should state that this post refers to a Silverlight 4 application. Silverlight 4 seems to have a cut-down version of the Serialization model.

    I have an XML file in the following format:
    Code:
    <?xml version="1.0" standalone="yes"?>
    <TeamTable>
      <TeamRow Id="1" Name="Arsenal" />
      <TeamRow Id="2" Name="Aston Villa" />
      <TeamRow Id="3" Name="Blackburn Rovers" />
      <TeamRow Id="4" Name="Bolton Wanderers" />
      <TeamRow Id="5" Name="Chelsea" />
      ...
    </TeamTable>
    I read the XML into an XDocument and then call the Load(...) member on my TeamTable Class:
    Code:
        public class TeamTable : List<TeamRow>
        {
            public void Load(XDocument document)
            {
                foreach (XElement element in document.Descendants("TeamRow"))
                    this.Add(TeamRow.Load(element));
            }
        }
    For each of the TeamRow elements in the document, this function calls the Load(...) member of my TeamRow class:
    Code:
        [DataContract]
        public class TeamRow
        {
            [DataMember]
            public Int32 Id { get; set; }
    
            [DataMember]
            public String Name { get; set; }
    
            public TeamRow() { }
    
            public static TeamRow Load(XElement element)
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(TeamRow));
    
                using (XmlReader reader = element.CreateReader())
                {
                    return serializer.ReadObject(reader) as TeamRow;
                }
            }
        }
    All appears to be well, the first element passed to this function contains

    <TeamRow Id="1" Name="Arsenal" />

    as I would expect.

    However the ReadObject(...) function is throwing the following exception.
    Code:
    Expecting element 'TeamRow' from namespace 'http://schemas.datacontract.org/2004/07/...'..
     Encountered 'Element'  with name 'TeamRow', namespace".
    This is my first attempt at this type of serialization. Can anyone help me fix the exception?
    Last edited by rliq; May 23rd, 2010 at 08:54 PM.
    Rob
    -
    Ohhhhh.... Old McDonald was dyslexic, E O I O EEEEEEEEEE.......

  2. #2
    Join Date
    Oct 2009
    Location
    Harrisburg, PA
    Posts
    23

    Re: Serialization from Xml into Object

    try changing your DataContractSerializer to this:

    Code:
    DataContractSerializer serializer = new DataContractSerializer(typeof(TeamRow), "TeamRow", "");

  3. #3
    Join Date
    Jun 2001
    Location
    Melbourne/Aus (C# .Net 4.0)
    Posts
    686

    Re: Serialization from Xml into Object

    Thanks Joe.

    That has cleared the exception and now I have a list of 20 (the number of teams) TeamRow's. However, each entry in the list has:

    Id = 0
    Name = null

    I'll continue on with my trial and error to see if I can work out why, but any further help is appreciated.
    Rob
    -
    Ohhhhh.... Old McDonald was dyslexic, E O I O EEEEEEEEEE.......

  4. #4
    Join Date
    Jun 2001
    Location
    Melbourne/Aus (C# .Net 4.0)
    Posts
    686

    Re: Serialization from Xml into Object

    Debugging confirms that the 'set' accessor on the TeamRow.Id property NEVER gets called.

    I was assuming that the DataContractSerializer would call those to set their values during the ReadObject() call.

    Still stuck.
    Rob
    -
    Ohhhhh.... Old McDonald was dyslexic, E O I O EEEEEEEEEE.......

  5. #5
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Serialization from Xml into Object

    Does Silverlight support the XmlSerializer class?

    If so, create a couple of classes with Xml attributes:

    Code:
    namespace CG
    {
      #region Using Directives
      using System;
      using System.Collections.Generic;
      using System.Xml;
      using System.Xml.Serialization;
      #endregion Using Directives
     
      ///<summary>
      /// Serialization class used to read the teamtable
      ///</summary>
      [Serializable]
      [XmlType( AnonymousType = true )]
      [XmlRoot( ElementName = "TeamTable", Namespace = "", IsNullable = false )]
      publicclassTeams
      {
        ///<summary/>
        publicstaticTeams Open( string configFile )
        {
          var serializer = newXmlSerializer( typeof( Teams ) );
    
          using ( var reader = XmlReader.Create( configFile ) )
          {
            return ( Teams ) serializer.Deserialize( reader );
          }
        }
     
        ///<remarks/>
        [XmlElement( "TeamRow", IsNullable = false )]
        publicTeam [ ] Rows
        {
          get
          {
            return _rows.ToArray( );
          }
          set
          {
            if ( null == _rows )
            {
              _rows = newList<Team>( );
            }
            _rows.AddRange( value );
          }
        }
        
        privateList<Team> _rows = newList<Team>( );
      }
     
      ///<remarks/>
      [Serializable]
      [XmlType( AnonymousType = true )]
      publicclassTeam
      {
        ///<remarks/>
        [XmlAttribute( AttributeName = "Id" )]
        publicint Id { get { return _id; } set { _id = value; } }
     
        ///<remarks/>
        [XmlAttribute( AttributeName = "Name" )]
        publicstring Name { get { return _name; } set { _name = value; } }
    
    
        privateint _id;
        privatestring _name;
      }
    }


    Then loading up the xml is:

    Code:
    var teamList = newList<Team>( );
     
    // Loads the xml into a Teams instance
    var teams = Teams.Open("teams.xml");  
     
    // Retrieve the TeamRows
    teamList.AddRange( teams.Rows );



    Attached Files Attached Files

  6. #6
    Join Date
    Jun 2001
    Location
    Melbourne/Aus (C# .Net 4.0)
    Posts
    686

    Re: Serialization from Xml into Object

    Arjay... the reason I looked in to serialization as an option for solving my problem was due to a similar post you posted the other day on another thread

    No, I don't believe XmlSerializers are supported fully in Silverlight, however DataContract's are. After much messing about (especially with namespaces in the XML) I solved my problem and then refactored again and again to arrive at this fairly neat and generic solution.

    Example XML:
    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <Table xmlns:S8="http://schemas.datacontract.org/2004/07/MyAppName" xmlns="S8">
    	<Row>
    		<S8:Id>1</S8:Id>
    		<S8:SectionId>4</S8:SectionId>
    		<S8:Name>Arsenal</S8:Name>
    	</Row>
    	<Row>
    		<S8:Id>2</S8:Id>
    		<S8:SectionId>2</S8:SectionId>
    		<S8:Name>Aston Villa</S8:Name>
    	</Row>
    </Table>
    My Team class:
    Code:
        [DataContract(Name="Row")]
        public class Team
        {
            [DataMember(Order = 0)]
            public Int32 Id { get; set; }
    
            [DataMember(Order = 1)]
            public Int32 SectionId { get; set; }
    
            [DataMember(Order = 2)]
            public String Name { get; set; }
        }
    And my new generic Table class replacing TeamTable (as I will have many more tables).
    Code:
        [CollectionDataContract(Namespace = "S8")]
        public class Table<T> : List<T>
        {
            public static Table<T> Load(String tableXml)
            {
                using (StringReader stringReader = new StringReader(tableXml))
                {
                    DataContractSerializer serializer = new DataContractSerializer(typeof(Table<T>), "Table", "S8");
    
                    using (XmlReader xmlReader = XmlReader.Create(stringReader))
                    {
                        return (serializer.ReadObject(xmlReader) as Table<T>);
                    }
                }
            }
        }
    Now all I have to do is create XML files in similar format to the above Table/Row tags and namespaces and create a supporting class similar to Team and from my main code I can do the following:
    Code:
            private Table<Team> _teams;
            private Table<Section> _sections;
            private Table<Entry> _entries;
    
            _teams = Table<Team>.Load(teamTableXml);
            _sections = Table<Section>.Load(sectionTableXml);
            _entries = Table<Entry>.Load(entryXml);
    Last edited by rliq; May 24th, 2010 at 06:50 PM.
    Rob
    -
    Ohhhhh.... Old McDonald was dyslexic, E O I O EEEEEEEEEE.......

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Serialization from Xml into Object

    Quote Originally Posted by rliq View Post
    Arjay... the reason I looked in to serialization as an option for solving my problem was due to a similar post you posted the other day on another thread
    Cool. I consider a day that I can avoid any xml document work a good day.


    -------------------------------------------
    Arjay

    See my latest series on using WCF to communicate between a Windows Service and WPF task bar application.
    Tray Notify - Part I Tray Notify - Part II

    Need a little help with Win32 thread synchronization? Check out the following CG articles and posts:
    Sharing a thread safe std::queue between threads w/progress bar updating
    Simple Thread: Part I [Simple Thread: Part II
    Win32 Thread Synchronization, Part I: Overview Win32 Thread Synchronization, Part 2: Helper Classes

    www.iridyn.com

    Last edited by Arjay; May 31st, 2010 at 11:54 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured