First, myXMLFile.Descendants("staff").Descendants("staffName")
is redundant. Descendants returns all the elements at any level within an XDocument
or XElement
. So, myXMLFile.Descendants("staffName")
would give the same result.
Second, you can just use the Element property and the Value property like this:
staffBio = staff.Element("staffBio").Value
staff
will only have one staffBio
element, so there's no need to use the Descendants property. Value
is a string, so you don't need to call Value.ToString
. If the element is empty, then Value will return an empty string, which is what you're looking for!
Third, there is a much better (and I believe more straight forward) way of doing this in VB.NET. Here's a console app that demonstrates how I would do this:
Module Module1
Sub Main()
Dim myXMLFile = <allStaff>
<staff>
<staffName>Test Staff</staffName>
<staffTitle>Slave</staffTitle>
<staffDepartmentName>Finance</staffDepartmentName>
<staffOffice>London</staffOffice>
<staffEmail>[email protected]</staffEmail>
<staffPhone>0207 123 456</staffPhone>
<staffNotes>Working hours Mon to Thurs 9.15 - 5.15</staffNotes>
<staffBio></staffBio>
</staff>
<staff>
<staffName>Other Staff</staffName>
<staffTitle>Master</staffTitle>
<staffDepartmentName>IT</staffDepartmentName>
<staffOffice>Oxford</staffOffice>
<staffEmail>[email protected]</staffEmail>
<staffPhone>0207 123 789</staffPhone>
<staffNotes></staffNotes>
<staffBio>Some guy.</staffBio>
</staff>
</allStaff>
Dim search = "Test"
Dim searchQuery = From staff In myXMLFile...<staff> _
Where staff.<staffName>.Value.Contains(search) _
Select si = New StaffInfo With {.Name = staff.<staffName>.Value, _
.Title = staff.<staffTitle>.Value, _
.Department = staff.<staffDepartmentName>.Value, _
.Office = staff.<staffOffice>.Value, _
.Email = staff.<staffEmail>.Value, _
.Phone = staff.<staffPhone>.Value, _
.Notes = staff.<staffNotes>.Value, _
.Bio = staff.<staffBio>.Value}
For Each staff In searchQuery
Console.WriteLine("Name: {0}", staff.Name)
Console.WriteLine("Title: {0}", staff.Title)
Console.WriteLine("Department: {0}", staff.Department)
Console.WriteLine("Office: {0}", staff.Office)
Console.WriteLine("Email: {0}", staff.Email)
Console.WriteLine("Phone: {0}", staff.Phone)
Console.WriteLine("Notes: {0}", staff.Notes)
Console.WriteLine("Bio: {0}", staff.Bio)
Console.WriteLine()
Next
Console.ReadLine()
End Sub
Private Class StaffInfo
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _title As String
Public Property Title() As String
Get
Return _title
End Get
Set(ByVal value As String)
_title = value
End Set
End Property
Private _department As String
Public Property Department() As String
Get
Return _department
End Get
Set(ByVal value As String)
_department = value
End Set
End Property
Private _office As String
Public Property Office() As String
Get
Return _office
End Get
Set(ByVal value As String)
_office = value
End Set
End Property
Private _email As String
Public Property Email() As String
Get
Return _email
End Get
Set(ByVal value As String)
_email = value
End Set
End Property
Private _phone As String
Public Property Phone() As String
Get
Return _phone
End Get
Set(ByVal value As String)
_phone = value
End Set
End Property
Private _notes As String
Public Property Notes() As String
Get
Return _notes
End Get
Set(ByVal value As String)
_notes = value
End Set
End Property
Private _bio As String
Public Property Bio() As String
Get
Return _bio
End Get
Set(ByVal value As String)
_bio = value
End Set
End Property
End Class
End Module
If you have a schema (.xsd file) for your XML, then you can import a reference to that xmlns to your VB source file, which will give you intellisense for writing your LINQ to XML queries.
(Edit: A quick way to create a schema is to open up an XML file in Visual Studio and choose Create Schema from the XML menu.)
For more information and help, please check out the "How Do I" video series on LINQ by Beth Massi.