Problem Writing Multiple Values to XML File via XMLWriter in VB.NET

Hello Experts.

I've been working on learning how to read and write from/to a custom XML file within my project.

At this point, it works, but only knows how to replace the entire file on the write operation. Let me explain...

I have a Public Class UserPrefs which iterates eight items that the user can maintain via checkboxes on a small dialog. Let's say for the moment that if the user clicks "AutoSelect", my setXML subroutine successfully creates the UserPreferences.xml file in bin/debug with the one line <AutoSelect>True</AutoSelect>. Next, the user unchecks "Countdown", so my setXML happily re-creates UserPreferences.xml with the line <Countdown>False</Countdown> sending AutoSelect to bit heaven. My desire is that I can keep track of all eight items. Any thoughts on what I might be doing wrong?

Imports System.Configuration
Imports System.IO
Imports System.Xml.Serialization
Imports SNAP.GlobalVars

Public Module iXML

    Sub setXML(ByVal SetKey As String, ByVal SetVal As String)
            Dim xmlFile As New StreamWriter(xmlPath)
            Dim xmlWriter As New XmlSerializer(GetType(UserPrefs))
            Dim xmlSetKey As New UserPrefs
            Select Case SetKey
                Case "AutoSelect" : xmlSetKey.AutoSelect = SetVal
                Case "Countdown" : xmlSetKey.Countdown = SetVal
                Case "LagPrompt" : xmlSetKey.LagPrompt = SetVal
                Case "MyTeam" : xmlSetKey.MyTeam = SetVal
                Case "NoMatches" : xmlSetKey.NoMatches = SetVal
                Case "SkipIntro" : xmlSetKey.SkipIntro = SetVal
                Case "SwapPlayers" : xmlSetKey.SwapPlayers = SetVal
                Case "GeneralHelp" : xmlSetKey.GeneralHelp = SetVal
            End Select
            xmlWriter.Serialize(xmlFile, xmlSetKey)
        End Try
    End Sub

    Public Function getXML(ByVal GetKey As String)
        If Not (File.Exists(xmlPath)) Then Return Nothing
        Dim xmlRtnVal As String = ""
            Dim xmlFile As New StreamReader(xmlPath)
            Dim xmlReader As New XmlSerializer(GetType(UserPrefs))
            With CType(xmlReader.Deserialize(xmlFile), UserPrefs)
                Select Case GetKey
                    Case "AutoSelect" : xmlRtnVal = .AutoSelect
                    Case "Countdown" : xmlRtnVal = .Countdown
                    Case "LagPrompt" : xmlRtnVal = .LagPrompt
                    Case "MyTeam" : xmlRtnVal = .MyTeam
                    Case "NoMatches" : xmlRtnVal = .NoMatches
                    Case "SkipIntro" : xmlRtnVal = .SkipIntro
                    Case "SwapPlayers" : xmlRtnVal = .SwapPlayers
                    Case "GeneralHelp" : xmlRtnVal = .GeneralHelp
                End Select
            End With
        End Try
        Return xmlRtnVal
    End Function

End Module

Public Class UserPrefs
    Public AutoSelect As String
    Public Countdown As String
    Public LagPrompt As String
    Public MyTeam As String
    Public NoMatches As String
    Public SkipIntro As String
    Public SwapPlayers As String
    Public GeneralHelp As String
End Class

Open in new window

And the subroutine that calls it:
    Private Sub chkQuikTip1_CheckedChanged(sender As Object, e As EventArgs) Handles _
        chkQuikTip1.CheckedChanged, chkQuikTip2.CheckedChanged, chkQuikTip3.CheckedChanged, chkQuikTip4.CheckedChanged,
         chkQuikTip5.CheckedChanged, chkQuikTip6.CheckedChanged, chkQuikTip7.CheckedChanged, chkQuikTip8.CheckedChanged
        Dim WhatWasChecked As String = sender.Tag
        If WhatWasChecked IsNot Nothing Then
            Call setXML(WhatWasChecked, sender.Checked.ToString)
        End If
    End Sub

Open in new window

Tony GardnerSr. Programmer/AnalystAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AndyAinscowFreelance programmer / ConsultantCommented:
Your culprit it the following:             Select Case SetKey

Because of how you have coded things you only ever write one setting to the file, all others are thrown away.  You need to set ALL of your settings by writing each and every one of them to the file, not just the one changed.
ste5anSenior DeveloperCommented:
I've been working on learning how to read and write from/to a custom XML file within my project.
At this point, it works, but only knows how to replace the entire file on the write operation. Let me explain...
As XML is structured markup which affects the entire file, you must replace the entire file. This necessary especially as it is a text file with possible encodings different from ASCII. Thus binary access and moving data is pretty hard. I'm not aware of an implementation doing this.

Furthermore, you're using the built-in .NET de-/serialization. Thus you already do a "single" read or write of the entire file. You just need to rearrange your code.

As a beginner:
- Don't use try/catch to hide exceptions.
- Get/Set are special verbs and should be only used for explicitly implemented getter/setter methods for properties, but never for normal methods.
- Be verbose in naming your objects and variables and parameter etc. This increases readability drastically. Avoid using abbreviations. Only use well-known one. Hint: they are only well-known when even the first day trainee knows them. When using abbreviations, the common spelling is upper-case it only when they consist of two letters, when having more use Camel/Pascal case. Thus Xml instead of XML.
- Check always the declaration of used classes, whether they implement IDisposable. In this case use using.
- Avoid double negation. Use positive If/Do/While conditions whenever possible. They are easier to understand.


Imports System.IO
Imports System.Xml.Serialization

Public Class UserPreferences
    Public AutoSelect As String

    Public Overrides Function ToString() As String
        Return String.Format($"AutoSelect: {Me.AutoSelect}")
    End Function
End Class

Module Program
    Sub Main(args As String())
        Const FILE_NAME As String = "C:\Temp\user.xml"
        Dim userPreferences = ReadUserPreferences(FILE_NAME)
        userPreferences.AutoSelect += "Added some text.."
        WriteUserPreferences(userPreferences, FILE_NAME)

    End Sub

    Sub WriteUserPreferences(userPreferences As UserPreferences, fileName As String)
        Using fileStream As New StreamWriter(fileName)
            Dim serializer As New XmlSerializer(GetType(UserPreferences))
            serializer.Serialize(fileStream, userPreferences)
        End Using
    End Sub

    Public Function ReadUserPreferences(fileName As String) As UserPreferences
        Dim result As UserPreferences = Nothing
        If File.Exists(fileName) Then
            Using fileStream As New StreamReader(fileName)
                Dim serializer As New XmlSerializer(GetType(UserPreferences))
                result = CType(serializer.Deserialize(fileStream), UserPreferences)
            End Using
        End If

        Return result
    End Function
End Module

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Tony GardnerSr. Programmer/AnalystAuthor Commented:
Sorry for the long wait, gentlemen. To be perfectly honest, implementing XML read/write has been shelved until I can sort out some more pressing matters.

Granting points based on contribution.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.