This isn't exactly what you're asking, but I find that dealing with raw XML leads to lots of headache. What you might consider instead is to just deal with a Shift class that lets you perform logic on your login/logout, and let .NET do the serialization/deserialization for you.
That way you are not bound to specific XML Paths if your business objects and relationships change.
Again, not what you asked, but here is how I would solve the business case you're dealing with.
First, create a shift class that I can put business logic in. Simple example here:
Public Class Shift
Public Property Name As String
Public Property DateString As String
Public Property Login As String
Public Property Logout As String
End Class
Next, create a collection of shifts. I called this class TimeCollection, but call it whatever you want. Mark it Serializable so that .NET can do the work of turning it from an object to XML and vice versa.
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.IO
Imports System.Xml.Serialization
<Serializable()> Public Class TimeCollection
Public Property Path As String
<XmlArray("Shifts")>
<XmlArrayItem(GetType(Shift))>
Public Property Shift As Shift()
Public Function Serialize(FileInfo As System.IO.FileInfo)
Try
If File.Exists(FileInfo.FullName) Then
File.Delete(FileInfo.FullName)
End If
If Not Directory.Exists(FileInfo.DirectoryName) Then
Directory.CreateDirectory(FileInfo.DirectoryName)
End If
Me.Path = FileInfo.FullName
Dim serializer As XmlSerializer = New XmlSerializer(GetType(TimeCollection))
Dim writer As StreamWriter = New StreamWriter(FileInfo.FullName)
serializer.Serialize(writer, Me)
writer.Close()
Catch ex As Exception
Throw
End Try
End Function
Public Shared Function Deserialize(FileInfo As FileInfo) As TimeCollection
Dim serializedType As TimeCollection = Nothing
Dim path As String = FileInfo.FullName
If (Not File.Exists(path)) Then
Deserialize = serializedType
Else
Try
Dim serializer As XmlSerializer = New XmlSerializer(GetType(TimeCollection))
Dim reader As StreamReader = New StreamReader(path)
serializedType = serializer.Deserialize(reader)
reader.Close()
Deserialize = serializedType
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End If
End Function
End Class
Now. If you have some code that generates a series of shifts, like this:
Dim tc As TimeCollection = New TimeCollection()
Dim first As Shift = New Shift()
first.Name = "Philipp"
first.Login = "14:11"
first.Logout = "14:45"
first.DateString = "3/31/2013"
Dim second As Shift = New Shift()
second.Name = "Phillip"
second.Login = "14:09"
' second.Logout = "15:01" (note 2nd shift has no logout)
second.DateString = "4/1/2013"
tc.Shift = New Shift(1) {first, second}
You can easily serialize the TimeCollection object like so:
tc.Serialize(New FileInfo("C:\SomePath\TimeCollectionA.xml"))
which creates the following contents:
<?xml version="1.0" encoding="utf-8"?>
<TimeCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Path>C:\Temp\Tc.xml</Path>
<Shifts>
<Shift>
<Name>Philipp</Name>
<DateString>3/31/2013</DateString>
<Login>14:11</Login>
<Logout>14:45</Logout>
</Shift>
<Shift>
<Name>Phillip</Name>
<DateString>4/1/2013</DateString>
<Login>14:09</Login>
</Shift>
</Shifts>
</TimeCollection>
Then, to deserialize the contents and turn the file back into a collection of objects you can do something with:
Dim tc As TimeCollection
tc = TimeCollection.Deserialize(New FileInfo("C:\SomePath\TimeCollectionA.xml"))
Now you can iterate through the tc.Shift array, etc.
InnerTextshould be justText