Solved

Deserializing XML to Class Object

Posted on 2011-09-07
12
1,863 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
  • 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
 
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

743 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now