Solved

Deserializing XML to Class Object

Posted on 2011-09-07
12
2,003 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
Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

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

How our DevOps Teams Maximize Uptime

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us. Read the use case whitepaper.

Question has a verified solution.

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

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

762 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