Search code examples
xmlvb.netxmlreaderxmlwriterreadxml

VB.NET: Read Multiple Properties and Tables from XML File


I have decided to save some application data using XML files. I am very new to XML files, so bear with me.

I have a class like this):

Public Class config
    Public Property name As String
    Public Property type As String

    Public Property inputsTable As DataTable
    Public Property outputsTable As DataTable

    Public Sub WriteXML(filePath As String)
        Using writer As XmlWriter = XmlWriter.Create(filePath)
            writer.WriteStartDocument()
            writer.WriteStartElement("config")

            writer.WriteElementString("name", Me.name)
            writer.WriteElementString("type", Me.type)

            Me.inputsTable.WriteXml(writer)
            Me.outputstable.WriteXml(writer)

            writer.WriteEndElement()
            writer.WriteEndDocument()
        End Using
    End Sub
End Class

WriteXML sub results in a file like:

<?xml version="1.0" encoding="utf-8"?>
<config>
    <name>testConfigName</name>
    <type>testConfigType</type>
    <DocumentElement>
        <inputs>
            <inputName>testInputName1</inputName>
            <inputValue>testInputValue1</inputValue>
        </inputs>
        <inputs>
            <inputName>testInputName2</inputName>
            <inputValue>testInputValue2</inputValue>
        </inputs>
    </DocumentElement>
    <DocumentElement>
        <outputs>
            <outputName>testOutputName1</outputName>
            <outputValue>testOutputValue1</outputValue>
        </outputs>
    </DocumentElement>
</config>

I have several questions:

  1. What is the purpose of the "root node" in the XML file? Here I created a node "config" in order to get my code working, but I don't really understand why it is necessary.

  2. Is WriteStartDocument/WriteEndDocument required?

  3. How can I write a sub to read this file back into my application? I am particularly having trouble getting the tables out. I am able to get the single elements out using:

    Using reader As XmlReader = XmlReader.Create(filePath)
        While reader.Read()
            Select Case reader.NodeType
                Case XmlNodeType.Element
                    Select Case reader.Name
                        Case "name"
                            name = reader.ReadElementContentAsString()
                        Case "type"
                            type = reader.ReadElementContentAsString()
                    End Select    
            End Select
        End While
    End Using
    

    but I don't know how (or if it is possible) to combine this with:

    inputsTable.ReadXml(reader)
    outputsTable.ReadXml(reader)
    

    It seems like the ReadXml may not actually work for what I'm trying to do (reading specific tables) and is meant for simpler single-table XML structures, but I could not confirm that definitively.

Any help will be greatly appreciated!


Solution

  • Try this code, .Net serializer does a lot of work for you.

    Public Class config
        Public Property name As String
        Public Property type As String
    
        Public Property inputsTable As DataTable
        Public Property outputsTable As DataTable
    
        Public Sub WriteXML(filePath As String)
    
            Dim writer As New XmlSerializer(GetType(config))
            Dim file As New StreamWriter(filePath)
            writer.Serialize(file, Me)
            file.Close()
        End Sub
    
        Public Shared Function ReadXML(filePath As String) As config
    
            Dim reader = New XmlSerializer(GetType(config))
            Dim file = New StreamReader(filePath)
            Dim fileData = CType(reader.Deserialize(file), config)
    
            Return fileData
    
        End Function
    
    End Class
    

    BTW these code patterns are snippets you can easily reach by right clicking and: Clicking Insert Snippet -> Data - LINQ -XML etc... -> XML -> XML Read / XML Write -> from / to class.

    How to Ignore a property

    <XmlIgnore>
    Public Property inputsTable As DataTable