?
Solved

Deserializing XML to Class Object

Posted on 2011-09-07
12
Medium Priority
?
2,148 Views
Last Modified: 2012-05-12
Hello everyone,

I am fairly new to serialization/deserialization, but I think I get the general jist. I think the issue I am having is with the actual XML itself, which I may not have much control over, but here goes anyway!

First, the XML

<?xml version="1.0" encoding="utf-8"?>
<MemberQueryResultSet>
	<Member>
		<FirstName>Test</FirstName>
		<LastName>Test</LastName>
		<SSN>999-99-9999</SSN>
		<Gender>M</Gender>
		<DateOfBirth>01/01/1940</DateOfBirth>
		<Address1>Test Rd.</Address1>
		<Address2>Test D1</Address2>
		<City>St Charles</City>
		<State>IL</State>
		<Zip>60175</Zip>
		<PrimaryPhone>000-000-0000</PrimaryPhone>
		<CellPhone>000-000-0000</CellPhone>
		<WorkPhone>000-000-0000</WorkPhone>
		<TerminationDate>09/27/2009</TerminationDate>
		<InsurerState>IL</InsurerState>
		<PlanCode>MPON</PlanCode>
	</Member>
	<Member>
		<FirstName>Test2</FirstName>
		<LastName>Test2</LastName>
		<SSN>888-88-8888</SSN>
		<Gender>F</Gender>
		<DateOfBirth>01/01/1952</DateOfBirth>
		<Address1>Test St</Address1>
		<Address2></Address2>
		<City>Elmhurst</City>
		<State>IL</State>
		<Zip>60126</Zip>
		<PrimaryPhone>111-111-1111</PrimaryPhone>
		<CellPhone>111-111-1111</CellPhone>
		<WorkPhone>111-111-1111</WorkPhone>
		<TerminationDate></TerminationDate>
		<InsurerState>IL</InsurerState>
		<PlanCode>MUWA</PlanCode>
	</Member>
</MemberQueryResultSet>

Open in new window


Now, the Class itself that the XML will deserialize into:

Imports System.Xml.Serialization

<XmlRootAttribute("Member")> _
Public Class MemberInfo

    Private strFirstName As String
    Private strLastName As String
    Private strSSN As String
    Private strGender As String
    Private strDOB As String
    Private strAddress1 As String
    Private strAddress2 As String
    Private strCity As String
    Private strState As String
    Private strZip As String
    Private strPhoneNumber As String
    Private strCellPhone As String
    Private strWorkPhone As String
    Private strTerminationDate As String
    Private strInsurerState As String
    Private strPlanCode As String

    <XmlElementAttribute(ElementName:="FirstName")> _
    Public Property FirstName() As String
        Get
            FirstName = strFirstName
        End Get
        Set(ByVal value As String)
            strFirstName = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="LastName")> _
    Public Property LastName() As String
        Get
            LastName = strLastName
        End Get
        Set(ByVal value As String)
            strLastName = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="SSN")> _
    Public Property SSN() As String
        Get
            SSN = strSSN
        End Get
        Set(ByVal value As String)
            strSSN = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="Gender")> _
    Public Property Gender() As String
        Get
            Gender = strGender
        End Get
        Set(ByVal value As String)
            strGender = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="DateOfBirth")> _
    Public Property DateOfBirth() As String
        Get
            DateOfBirth = strDOB
        End Get
        Set(ByVal value As String)
            strDOB = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="Address1")> _
    Public Property Address1() As String
        Get
            Address1 = strAddress1
        End Get
        Set(ByVal value As String)
            strAddress1 = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="Address2")> _
    Public Property Address2() As String
        Get
            Address2 = strAddress2
        End Get
        Set(ByVal value As String)
            strAddress2 = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="City")> _
    Public Property City() As String
        Get
            City = strCity
        End Get
        Set(ByVal value As String)
            strCity = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="State")> _
    Public Property State() As String
        Get
            State = strState
        End Get
        Set(ByVal value As String)
            strState = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="Zip")> _
    Public Property Zip() As String
        Get
            Zip = strZip
        End Get
        Set(ByVal value As String)
            strZip = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="PrimaryPhone")> _
    Public Property PrimaryPhone() As String
        Get
            PrimaryPhone = strPhoneNumber
        End Get
        Set(ByVal value As String)
            strPhoneNumber = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="CellPhone")> _
    Public Property CellPhone()
        Get
            CellPhone = strCellPhone
        End Get
        Set(ByVal value)
            strCellPhone = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="WorkPhone")> _
    Public Property WorkPhone()
        Get
            WorkPhone = strWorkPhone
        End Get
        Set(ByVal value)
            strWorkPhone = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="TerminationDate")> _
    Public Property TerminationDate()
        Get
            TerminationDate = strTerminationDate
        End Get
        Set(ByVal value)
            strTerminationDate = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="InsurerState")> _
    Public Property InsurerState()
        Get
            InsurerState = strInsurerState
        End Get
        Set(ByVal value)
            strInsurerState = value
        End Set
    End Property

    <XmlElementAttribute(ElementName:="PlanCode")> _
    Public Property PlanCode()
        Get
            PlanCode = strPlanCode
        End Get
        Set(ByVal value)
            strPlanCode = value
        End Set
    End Property
End Class

Open in new window


And finally the code that does the deserialization:

Dim aStreamReader As TextReader

        aStreamReader = New StreamReader("MemberQueryResultSet.xml")
        strDS = aStreamReader.ReadToEnd()

        Dim sr As New IO.StringReader(strDS)
        Dim x As New XmlSerializer(GetType(MemberInfo()))

        Dim Members() As MemberInfo = x.Deserialize(sr)

Open in new window


The exception comes up on the last line (x.Deserialize(sr).  The exception is as follows:

Exception="{"There is an error in XML document (2, 2)."}"
Message=""<MemberQueryResultSet xmlns=''> was not expected."

I thought that I fixed it by setting hte xmlroot element to Member, but it did not help.  I'm assuming its because of hte MemberQueryResultSet element in the XML?

Any help would be great!

Kind regards

Darren Bridle

** Edit exception detail**
0
Comment
Question by:dbridle
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
12 Comments
 

Author Comment

by:dbridle
ID: 36494572
Just a quick addition to the above.  I have tried removing MemberResultSet, so that the root element is member, and it just came up with the same error but with Member instead of MemberResultSet as the culprit!
0
 
LVL 19

Expert Comment

by:Rikin Shah
ID: 36494698
Hi dbridle,
The deserialization responds to "ArrayOf" prefix for the root element.

The thing is when you serialize data; the root element will be having "ArrayOf" prefix with it. Which is required when deserializing the xml.

To overcome this issue, we have attributes like XmlArray and XmlArrayItem.
You need to add-
<XmlArray("MemberQueryResultSet")>
<XmlArrayItem("Member")>
in class definition.

This should solve the problem.

Thanks,
Rikin Shah.
0
 

Author Comment

by:dbridle
ID: 36494740
Hi Rikin,

Thank you for your comment.  I know its going to be something to do with the definition.  I added this to my class, and have the following errors:

Error      4      Attribute 'XmlArrayAttribute' cannot be applied to 'MemberInfo' because the attribute is not valid on this declaration type.

Error      5      Attribute 'XmlArrayItemAttribute' cannot be applied to 'MemberInfo' because the attribute is not valid on this declaration type.      

Here is the new code with the change:

Imports System.Xml.Serialization

<XmlArray("MemberQueryResultSet")> _
<XmlArrayItem("Member")> _
Public Class MemberInfo

    Private strFirstName As String
    Private strLastName As String
    Private strSSN As String
    Private strGender As String
    Private strDOB As String
    Private strAddress1 As String
    Private strAddress2 As String
    Private strCity As String
    Private strState As String
    Private strZip As String
    Private strPhoneNumber As String
    Private strCellPhone As String
    Private strWorkPhone As String
    Private strTerminationDate As String
    Private strInsurerState As String
    Private strPlanCode As String

Open in new window

0
Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

 
LVL 19

Expert Comment

by:Rikin Shah
ID: 36494805
My bad...

Please us it while declaring the array of the class... So, the code should be-

<XmlArray("MemberQueryResultSet")>
<XmlArrayItem("Member")>
Dim Members() As MemberInfo = x.Deserialize(sr)

Open in new window


Thanks,
Rikin Shah.
0
 

Author Comment

by:dbridle
ID: 36494839
Sorry Rikin thats not working either, it wants an _ at the end of each line, as it thinks its a declaration. With an _ the Members declaration just errors.
0
 
LVL 19

Expert Comment

by:Rikin Shah
ID: 36494847
Again my bad... I'm C# guy so thought those would be special characters and I removed them. Can you put them back and try again?


Thanks,
Rikin Shah.
0
 

Author Comment

by:dbridle
ID: 36495063
How would you write it in C#?  Because putting _ to continue the line is just throwing errors.
0
 
LVL 19

Expert Comment

by:Rikin Shah
ID: 36495080
C# doesn't need _ to specify a new line. It just works with a carriage return.

Thanks,
Rikin Shah
0
 

Author Comment

by:dbridle
ID: 36495108
Ok here you go..

        <XmlArray("MemberQueryResultSet")> _
        <XmlArrayItem("Member")> _
        Dim Members() As MemberInfo = x.Deserialize(sr)

Open in new window


Error      4      Attributes cannot be applied to local variables.
0
 

Author Comment

by:dbridle
ID: 36495134
I think that maybe you can only use XMLArray/ArrayItem on member variables in a class, not the class itself?
0
 
LVL 19

Accepted Solution

by:
Rikin Shah earned 2000 total points
ID: 36495372
Alrighty,

Here is the working code (in C#); if you can convert this to VB!! Sorry, don't get VB syntaxes much. :-|

C#
[Serializable()] 
[System.Xml.Serialization.XmlRoot("MemberQueryResultSet")]
public class Members {
  [XmlArray("Member")]
  public MemberInfo[] MembersArray { get; set; } 
}

XmlSerializer s1= new XmlSerializer(typeof(Members[]));
Members ObjMembers = new Members();

ObjMembers = (Members)s1.Deserialize(sr);

Open in new window


I have tried to convert the code in VB!!

VB
<Serializable> _
<System.Xml.Serialization.XmlRoot("MemberQueryResultSet")> _
Public Class Members
	<XmlArray("Member")> _
	Public Property MembersArray() As MemberInfo()
		Get
			Return m_MembersArray
		End Get
		Set
			m_MembersArray = Value
		End Set
	End Property
	Private m_MembersArray As MemberInfo()
End Class

Dim s1 As New XmlSerializer(GetType(Members()))
Dim ObjMembers As New Members()
ObjMembers = DirectCast(s1.Deserialize(sr), Members)

Open in new window


Let me know if you need any more help!

Thanks,
Rikin Shah
0
 

Author Comment

by:dbridle
ID: 36496048
I did not need the XmlArray, instead I used:

Public Class MemberQueryResultSet
    Private _memberList As List(Of MemberInfo)

    'we need this annotation to make it an "inline" list i.e. no "Members" node
    <XmlElementAttribute(ElementName:="Member")> _
    Public Property Members() As List(Of MemberInfo)
        Get
            Return _memberList
        End Get
        Set(ByVal value As List(Of MemberInfo))
            _memberList = value
        End Set
    End Property
End Class

Open in new window


But you got me there! Thanks Rikin, awarding points not :)
0

Featured Post

Understanding Linux Permissions

Linux for beginners: How to view the permissions associated with files and directories and also how you can change them.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question