Hi,
I have
VB.NET form that reads and updates a simple XML file (people.xml), but I'm not sure how to modify it read a more complex XML file (people2.xml). I want the form to show a varying number of family members and be able to add families that may have from one to five members.
Thanks for any assistance,
kyma
people2.xml --- more complex XML in which a lastname is only used one for all members of a family and each firstname, age, gender is part of a member.
<?xml version="1.0"?>
<FamilyList xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Families>
<Family>
<LastName>Flanders</LastName>
<Member>
<FirstName>Ned</FirstName>
<Age>60</Age>
<Gender>Male</Gender>
</Member>
<Member>
<FirstName>Maude</FirstName>
<Age>34</Age>
<Gender>Female</Gender>
</Member>
<Member>
<FirstName>Rod</FirstName>
<Age>10</Age>
<Gender>Male</Gender>
</Member>
<Member>
<FirstName>Todd</FirstName>
<Age>8</Age>
<Gender>Male</Gender>
</Member>
</Family>
<Family>
<LastName>Lovejoy</LastName>
<Member>
<FirstName>Timothy</FirstName>
<Age>37</Age>
<Gender>Male</Gender>
</Member>
<Member>
<FirstName>Helen</FirstName>
<Age>36</Age>
<Gender>Female</Gender>
</Member>
<Member>
<FirstName>Jessica</FirstName>
<Age>10</Age>
<Gender>Female</Gender>
</Member>
</Family>
</Families>
</FamilyList>
people.xml --- simple XML file
<?xml version="1.0"?>
<FamilyList xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Families>
<Family>
<LastName>Flanders</LastName>
<FirstName>Ned</FirstName>
<Age>60</Age>
<Gender>Male</Gender>
</Family>
<Family>
<LastName>Flanders</LastName>
<FirstName>Maude</FirstName>
<Age>34</Age>
<Gender>Female</Gender>
</Family>
<Family>
<LastName>Flanders</LastName>
<FirstName>Rod</FirstName>
<Age>10</Age>
<Gender>Male</Gender>
</Family>
<Family>
<LastName>Flanders</LastName>
<FirstName>Todd</FirstName>
<Age>8</Age>
<Gender>Male</Gender>
</Family>
<Family>
<LastName>Lovejoy</LastName>
<FirstName>Timothy</FirstName>
<Age>37</Age>
<Gender>Male</Gender>
</Family>
<Family>
<LastName>Lovejoy</LastName>
<FirstName>Helen</FirstName>
<Age>36</Age>
<Gender>Female</Gender>
</Family>
<Family>
<LastName>Lovejoy</LastName>
<FirstName>Jessica</FirstName>
<Age>10</Age>
<Gender>Female</Gender>
</Family>
</Families>
</FamilyList>
frmFamilyList.
vb --- form itself
Public Class frmFamilyList
Inherits System.Windows.Forms.Form
...
'Members
Public FamilyList As FamilyList
Private _currentFamilyIndex As Integer
'Current Family
ReadOnly Property CurrentFamily() As Family
Get
Return FamilyList.Items(CurrentFamilyIndex - 1)
End Get
End Property
'Current Address Index
Property CurrentFamilyIndex() As Integer
Get
Return _currentFamilyIndex
End Get
Set(ByVal Value As Integer)
'Set family
_currentFamilyIndex = Value
'Update display
PopulateFormFromFamily(CurrentFamily)
'Record number information
lblRecordNumber.Text = _currentFamilyIndex & " of " & FamilyList.Items.Count
End Set
End Property
'Data location
Public ReadOnly Property DataFilename() As String
Get
'Working folder
Dim folder As String
folder = Environment.CurrentDirectory
'Return folder with name of file
Return folder & "\people.xml"
End Get
End Property
'Populate Family from form fields
Public Sub PopulateFamilyFromForm(ByVal family As Family)
'Copy values
family.LastName = txtLastName.text
family.FirstName = txtFirstName.text
family.Age = txtAge.text
family.Gender = txtGender.text
End Sub
'Populate form from Family
Public Sub PopulateFormFromFamily(ByVal family As Family)
'Copy values
txtLastName.Text = family.LastName
txtFirstName.Text = family.FirstName
txtAge.Text = family.Age
txtGender.Text = family.Gender
End Sub
Private Sub frmFamilyList_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
'load family list
FamilyList = SerializableData.load(DataFilename, GetType(FamilyList))
'Make sure family list contains items
If FamilyList.Items.Count = 0 Then FamilyList.AddFamily()
'Select first item
CurrentFamilyIndex = 1
End Sub
Private Sub frmFamilyList_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
'Save changes as form closes
UpdateCurrentFamily()
SaveChanges()
End Sub
'Save to XML file
Public Sub SaveChanges()
FamilyList.Save(DataFilename)
End Sub
'Ensure file has current values entered into form
Private Sub UpdateCurrentFamily()
PopulateFamilyFromForm(CurrentFamily)
End Sub
Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
AddNewFamily()
End Sub
Public Function AddNewFamily() As Family
'Save current family
UpdateCurrentFamily()
'Create new family
Dim newFamily As Family = FamilyList.AddFamily
'Update display
CurrentFamilyIndex = FamilyList.Items.Count
'Return
Return newFamily
End Class
FamilyList.
vb ---
Imports System.Xml.Serialization
Public Class FamilyList
Inherits SerializableData
'Members
<XmlIgnore()> Public Items As New ArrayList
'Add new family
Public Function AddFamily() As Family
'Declare
Dim newFamily As New Family
'Add
Items.Add(newFamily)
'Return
Return newFamily
End Function
'Works with items collection as an array
Public Property Families() As Family()
Get
'New Array
Dim familyArray(Items.Count - 1) As Family
Items.CopyTo(familyArray)
Return familyArray
End Get
Set(ByVal Value As Family())
'Reset array list
Items.Clear()
'Any values?
If Not Value Is Nothing Then
'process array and populate items
Dim family As Family
For Each family In Value
Items.Add(family)
Next
End If
End Set
End Property
End Class
SerializableData.
vb ---
Imports System.IO
Imports System.Xml.Serialization
Public Class SerializableData
'Save object to file
Public Function Save(ByVal filename As String)
'Temporary
Dim tempFilename As String
tempFilename = filename & ".tmp"
'Verify file exists
Dim tempFileInfo As New FileInfo(tempFilename)
If tempFileInfo.Exists = True Then tempFileInfo.Delete()
'Open file
Dim stream As New FileStream(tempFilename, FileMode.Create)
'Save object
Save(stream)
'Close file
stream.Close()
'Remove existing file and rename temp file
tempFileInfo.CopyTo(filename, True)
tempFileInfo.Delete()
End Function
'Perform save
Public Function Save(ByVal stream As Stream)
'Create serializer
Dim serializer As New XmlSerializer(Me.GetType)
'Save file
serializer.Serialize(stream, Me)
End Function
'Load from file
Public Shared Function load(ByVal filename As String, ByVal newType As Type) As Object
'Verify file exists
Dim fileInfo As New FileInfo(filename)
If fileInfo.Exists = False Then
'Create and return blank version of object
Return System.Activator.CreateInstance(newType)
End If
'Open file
Dim stream As New FileStream(filename, FileMode.Open)
'Load object from stream
Dim newObject As Object = load(stream, newType)
'Close stream
stream.Close()
'Return
Return newObject
End Function
Public Shared Function Load(ByVal stream As Stream, ByVal newType As Type) As Object
'Create serializer and load object
Dim serializer As New XmlSerializer(newType)
Dim newObject As Object = serializer.Deserialize(stream)
'Return
Return newObject
End Function
End Class
Family.
vb --- Family class
Public Class Family
Inherits SerializableData
'Members
Public LastName As String
Public FirstName As String
Public Age As String
Public Gender As String
End Class