Sample XML
<Drawer_System_1>
<DrawerSystemID>1</DrawerSystemID>
<DrawerSysName>Drawer_System_1</DrawerSysName>
<DrawerSysLocation>North Wall (2nd from left)</DrawerSysLocation>
<Drawers>
<DrawerID>1-01</DrawerID>`enter code here`
<Contents>Contents of Drawer 1-01</Contents>
</Drawers>
<Drawers>
<DrawerID>1-02</DrawerID>
<Contents>Contents of Drawer 1-02</Contents>
</Drawers>
</Drawer_System_1>
My Question
How do I retrieve the values of child and parent XML nodes simultaneously?
I have populated a TreeView control with my XML file, and I want to retrieve certain values (as Strings) between nodes and subnodes as I select them in the control.
My Expected Results
If I select the Drawer_System_1 node or any subnode, I want to retrieve the values between the DrawerSystemID, DrawerSysName, and DrawerSysLocation nodes.
If I select a Drawers node or any subnode, I want to keep the previously mentioned values and also retrieve the values of the DrawerID and Contents nodes.
The value of each node should be displayed in an individual label, but if it's easier to display my requested data in a multi-line text box (or label), that's fine too.
Notes
I am using VB.NET, but if you can think of a solution in C#, that's fine too--I should be able to convert the answer into VB using an online converter.
If necessary, I can re-structure my XML file to make it easier for my program to read.
EDIT: Here's my code so far:
Imports System
Imports System.Xml
Imports System.Xml.Serialization
Imports System.IO
Public Class My_LEGO_Elements
Private Sub My_LEGO_Elements_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim serializer As New SimpleXmlSerializer()
Dim data As LEGOElementsData = serializer.DeSerialize(Of LEGOElementsData)(File.ReadAllText("C:\Users\Steven\Documents\Visual Studio 2012\Projects\My_LEGO_Elements\My_LEGO_Elements\Drawer_Systems_5.xml"))
ListBox1.Items.AddRange(data.DrawerSystems.ToArray())
End Sub
Private Sub ListBox1_SelectedValueChanged(ByVal sender As Object, ByVal e As EventArgs) Handles ListBox1.SelectedValueChanged
Dim drawerSystem As DrawerSystem = CType(ListBox1.SelectedItem, DrawerSystem)
DrawerSysIDLabel.Text = drawerSystem.Id
DrawerSysNameLabel.Text = drawerSystem.Name
DrawerSysLocLabel.Text = drawerSystem.Location
'retrieve specific drawer system image from resources
Dim pictureResource = My.Resources.ResourceManager.GetObject(String.Format("{0}", drawerSystem.Id))
'convert pictureResource to type Image and display in DrawerSysPictureBox
DrawerSysPictureBox.Image = CType(pictureResource, Image)
End Sub 'My_LEGO_Elements_Load
Private Sub ListBox2_SelectedValueChanged(ByVal sender As Object, ByVal e As EventArgs) Handles ListBox2.SelectedValueChanged
Dim drawer As Drawer = CType(ListBox2.SelectedItem, Drawer)
DrawerNumberLabel.Text = drawer.Id
DrawerContentsLabel.Text = drawer.Contents
End Sub
End Class 'My_LEGO_Elements
Public Class LEGOElementsData
Public Property DrawerSystems() As List(Of DrawerSystem)
Get
Return _drawerSystems
End Get
Set(ByVal value As List(Of DrawerSystem))
_drawerSystems = value
End Set
End Property
Private _drawerSystems As List(Of DrawerSystem)
End Class
Public Class DrawerSystem
Public Property Id() As String
Get
Return _id
End Get
Set(ByVal value As String)
_id = value
End Set
End Property
Private _id As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _name As String
Public Property Location() As String
Get
Return _location
End Get
Set(ByVal value As String)
_location = value
End Set
End Property
Private _location As String
Public Property Drawers() As List(Of Drawer)
Get
Return _drawers
End Get
Set(ByVal value As List(Of Drawer))
_drawers = value
End Set
End Property
Private _drawers As List(Of Drawer)
Public Overrides Function ToString() As String
Return _name
End Function
End Class
Public Class Drawer
Public Property Id() As String
Get
Return _id
End Get
Set(ByVal value As String)
_id = value
End Set
End Property
Private _id As String
Public Property Contents() As String
Get
Return _contents
End Get
Set(ByVal value As String)
_contents = value
End Set
End Property
Private _contents As String
End Class
Public Class SimpleXmlSerializer
Public Function Serialize(ByVal objectToSerialize As Object) As String
Dim serializer As XmlSerializer = New XmlSerializer(objectToSerialize.GetType())
Using stream As MemoryStream = New MemoryStream()
Dim namespaces As XmlSerializerNamespaces = New XmlSerializerNamespaces()
namespaces.Add("", "")
serializer.Serialize(stream, objectToSerialize, namespaces)
Using reader As StreamReader = New StreamReader(stream)
stream.Position = 0
Return reader.ReadToEnd()
End Using
End Using
End Function
Public Function DeSerialize(Of T)(ByVal serializedObject As String) As T
Dim serializer As XmlSerializer = New XmlSerializer(GetType(T))
Using reader As StringReader = New StringReader(serializedObject)
Return CType(serializer.Deserialize(reader), T)
End Using
End Function
End Class
I re-structured my XML file as suggested. I got the the drawer systems information to display properly. Is there a way to display information about individual drawers in the second ListBox (or another type of control) upon selecting a drawer system? Also, for some reason my image won't display in the PictureBox.