Hutch_777
Hutch_777

Reputation: 15

LookUp data from XML File

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

Answers (3)

djv
djv

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

Andrew Morton
Andrew Morton

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

dbasnett
dbasnett

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

Related Questions