Search code examples
xmlvb.netsubstringstreamreader

VB grab text values and save as variables


I was wondering if there is a quicker way to "search" part of a line's string of text and find non-static values and save them to variables?

For instance, I can't really use Substring and search for part of a line because the values in the " " are never the same length.

Example part of the text file that I am reading in:

<I_Sect IDCode="20001" Description="This is desc" Quantity="1000" InclKind="Inc" />

The id names : IDCode Description Quantity and InclKind never change

The values do change: 20001 ... This is desc... etc

Is there a quicker way to search the "" after I do a substring to find the id name and grab how ever long the string between the "" is?

Current code:

Dim list As New List(Of String)()
Dim file As New System.IO.StreamReader(DisplayFile)
While Not file.EndOfStream
    Dim line As String = file.ReadLine()
    list.Add(line)
End While
file.Close()
Console.WriteLine("{0} lines read", list.Count)
'RichTextBox1.Text = System.IO.File.ReadAllText(DisplayFile)

For counter As Integer = 0 To list.Count

    If list(counter).Substring(0, 7) = "<I_Sect" Then
        'Do a substring of the line to see if I can locate Description ID string

        ' .............

        Dim desc As String = ' .... [the valve I grab will be "This is desc"]
    End If

Next

Solution

  • Using this xml file

    <?xml version="1.0" encoding="utf-8" ?>
    <root>
      <I_SecMain>
        <I_SecTop>
          <I_SecBrac>
            <I_Sect IDCode="20001" Description="This is desc 1" Quantity="10001" InclKind="Inc 1" />
            <I_Sect IDCode="20002" Description="This is desc 2" Quantity="10002" InclKind="Inc 2" />
            <I_Sect IDCode="20003" Description="This is desc 3" Quantity="10003" InclKind="Inc 3" />
            <I_Sect IDCode="20004" Description="This is desc 4" Quantity="10004" InclKind="Inc 4" />
            <I_Sect IDCode="20005" Description="This is desc 5" Quantity="10005" InclKind="Inc 5" />
          </I_SecBrac>
        </I_SecTop>
      </I_SecMain>
    </root>
    

    You can define a corresponding model you can use to deserialize the file.

    Imported namespaces

    Imports System.Xml.Serialization
    

    Model

    <XmlRoot("root")>
    Public Class Root
        <XmlElement>
        Public Property I_SecMain As I_SecMain
    End Class
    
    Public Class I_SecMain
        <XmlElement>
        Public Property I_SecTop As I_SecTop
    End Class
    
    Public Class I_SecTop
        <XmlElement>
        Public Property I_SecBrac As I_SecBrac
    End Class
    
    Public Class I_SecBrac
        <XmlElement("I_Sect")>
        Public Property I_Sects As List(Of I_Sect)
    End Class
    
    Public Class I_Sect
        <XmlAttribute>
        Public Property IDCode As Integer
        <XmlAttribute>
        Public Property Description As String
        <XmlAttribute>
        Public Property Quantity As Integer
        <XmlAttribute>
        Public Property InclKind As String
    End Class
    

    And very simply deserialize the file into strongly typed objects

    Dim DisplayFile = "test.xml"
    
    Dim myRoot As Root
    Dim mySerializer As New XmlSerializer(GetType(Root))
    Using fs As New FileStream(DisplayFile, FileMode.Open)
        myRoot = mySerializer.Deserialize(fs)
    End Using
    

    which can be iterated over.

    For Each isect In myRoot.I_SecMain.I_SecTop.I_SecBrac.I_Sects
        Console.WriteLine(
            String.Format("ID Code: {0}, Description: {1}, Quantity: {2}, InclKind: {3}",
                          isect.IDCode, isect.Description, isect.Quantity, isect.InclKind))
    Next
    

    From here, it's a matter of defining your model accurately (you didn't post it in your question) and just retrieving properties from the deserialized objects.

    Using serialization, it's trivial to write to the file as well, if that's a requirement.

    Using fs As New FileStream(DisplayFile, FileMode.Open)
        mySerializer.Serialize(fs, myRoot)
    End Using