Reputation: 15
I have an xml file with a list of clients set up like this:
<?xml version="1.0" encoding="utf-8"?>
<Clients>
<Client>
<Number>10001</Number>
<Name>Apple</Name>
</Client>
<Client>
<Number>20002</Number>
<Name>Microsoft</Name>
</Client>
</Clients>
I have a userform with 2 text boxes on one for client number and the next for client name, when the user enters the client number the second text box should be populated with the client name from the xml file. I cannot get this to work, I tried using the following code (where the variable 'numbers' is pulled from the Client number text box):
doc.Load("C:\Users\Me\ClientList.xml")
Dim acc As String = doc.SelectSingleNode("/Clients/Client/Name=" & numbers).InnerText
Form.txtClientName.Text = acc
Upvotes: 0
Views: 201
Reputation: 15774
Using Xml Serialization
Create classes to define your data
<XmlRoot>
Public Class Clients
<XmlElement("Client")>
Public Property Clients As List(Of Client)
End Class
Public Class Client
<XmlElement>
Public Property Number As Integer
<XmlElement>
Public Property Name As String
End Class
Deserialize the file once, and check for matching client in TextBox_TextChanged using LINQ
Private myClients As Clients
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim serializer As New Xml.Serialization.XmlSerializer(GetType(Clients))
Using sr As New System.IO.StreamReader("C:\Users\Me\ClientList.xml")
myClients = serializer.Deserialize(sr)
End Using
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
Dim number As Integer
If Integer.TryParse(TextBox1.Text, number) Then
Dim matchingClient = myClients?.Clients?.FirstOrDefault(Function(c) c.Number = number)
If matchingClient IsNot Nothing Then
TextBox2.Text = matchingClient.Name
End If
End If
End Sub
Now you have strong-typed objects you can do even more with, instead of working with XDocuments and XElements
Upvotes: 0
Reputation: 25013
You want a node which is a sibling of a particular node. Referring to this answer, you can use
Dim acc As String = doc.SelectSingleNode("/Clients/Client[Number='" & numbers & "']/Name").InnerText
(I suggest that "numbers" is not a good name for a variable which holds only one value.)
Upvotes: 1
Reputation: 11773
Using XElement and LINQ. You should be able to adapt to your needs.
Dim xe As XElement
' xe = XElement.Load("path here")
' or use literal for testing
xe = <Clients>
<Client>
<Number>10001</Number>
<Name>Apple</Name>
</Client>
<Client>
<Number>20002</Number>
<Name>Microsoft</Name>
</Client>
</Clients>
'select a client by number
Dim selC As XElement = (From el In xe...<Number> Where el.Value = "10001" Select el.Parent Take 1).FirstOrDefault
Dim nm As String
Dim num As String
'get data from selection
If selC IsNot Nothing Then
nm = selC.<Name>.FirstOrDefault.Value
num = selC.<Number>.FirstOrDefault.Value
End If
Upvotes: 0