• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2274
  • Last Modified:

Deserializing XML to Class Object

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
dbridle
Asked:
dbridle
  • 7
  • 5
1 Solution
 
dbridleAuthor Commented:
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
 
Rikin ShahMicrosoft Dynamics CRM ConsultantCommented:
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
 
dbridleAuthor Commented:
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
Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

 
Rikin ShahMicrosoft Dynamics CRM ConsultantCommented:
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
 
dbridleAuthor Commented:
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
 
Rikin ShahMicrosoft Dynamics CRM ConsultantCommented:
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
 
dbridleAuthor Commented:
How would you write it in C#?  Because putting _ to continue the line is just throwing errors.
0
 
Rikin ShahMicrosoft Dynamics CRM ConsultantCommented:
C# doesn't need _ to specify a new line. It just works with a carriage return.

Thanks,
Rikin Shah
0
 
dbridleAuthor Commented:
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
 
dbridleAuthor Commented:
I think that maybe you can only use XMLArray/ArrayItem on member variables in a class, not the class itself?
0
 
Rikin ShahMicrosoft Dynamics CRM ConsultantCommented:
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
 
dbridleAuthor Commented:
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

Get quick recovery of individual SharePoint items

Free tool – Veeam Explorer for Microsoft SharePoint, enables fast, easy restores of SharePoint sites, documents, libraries and lists — all with no agents to manage and no additional licenses to buy.

  • 7
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now