0

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!

Kevin
  • 172
  • 1
  • 12

1 Answers1

3

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
Kelly Barnard
  • 1,131
  • 6
  • 8
  • Thanks for the answer! Do you know a way to prevent certain properties from being serialized? – Kevin Mar 21 '16 at 18:44
  • 1
    To have the serializer ignore a property just put the property attribute on the property like: Public Property inputsTable As DataTable – Kelly Barnard Mar 21 '16 at 18:47