Link to home
Start Free TrialLog in
Avatar of Richard Kreidl
Richard KreidlFlag for United States of America

asked on

Editing a XML file

Yesterday I got help from S-Twilley on how to add, search and delete an element from a XML file. His code listed below. What I forgot to ask is how to edit an element in the XML file. So, let's  say I do a search and it populates the textboxes. I then make my changes and then click an 'Edit' command button which would then save my changes. Another thing I need is if the Server name already exists in the XML file it will let you know so it doesn't add it again.

 Private Sub cmdAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAdd.Click
        AddServer()
    End Sub

    Private Sub cmdSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSearch.Click
        LoadServer(txtSearch.Text)
    End Sub

    Private Sub cmdDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDelete.Click
        DeleteServer(txtSearch.Text)
    End Sub

    Private Sub cmdEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdEdit.Click
        EditServer()
    End Sub

    Sub EditServer()
       'Code needed
    End Sub

    Sub AddServer()
        Dim doc As New XmlDocument
        doc.Load("c:\VB Testing\UMZ\UMZ.xml")

        Dim root As XmlNode = doc.DocumentElement
        Dim EleName As XmlElement = doc.CreateElement("Server")
        Dim ElePreMVS As XmlElement = doc.CreateElement("PreMVS")
        Dim ElePostMVS As XmlElement = doc.CreateElement("PostMVS")
        Dim ElePreCS As XmlElement = doc.CreateElement("PreCS")
        Dim ElePostCS As XmlElement = doc.CreateElement("PostCS")
        Dim EleMisc As XmlElement = doc.CreateElement("Misc")

        EleName.SetAttribute("name", txtName.Text)
        ElePreMVS.InnerText = txtPreMVS.Text
        ElePostMVS.InnerText = txtPostMVS.Text
        ElePreCS.InnerText = txtPreCS.Text
        ElePostCS.InnerText = txtPostCS.Text
        EleMisc.InnerText = txtMisc.Text

        EleName.AppendChild(ElePreMVS)
        EleName.AppendChild(ElePostMVS)
        EleName.AppendChild(ElePreCS)
        EleName.AppendChild(ElePostCS)
        EleName.AppendChild(EleMisc)

        root.AppendChild(EleName)
        doc.Save("c:\VB Testing\UMZ\UMZ.xml")
    End Sub
    Function LoadServer(ByVal desiredServer As String) As Boolean
        Dim doc As New XmlDocument
        doc.Load("c:\VB Testing\UMZ\UMZ.xml")

        Dim root As XmlNode = doc.DocumentElement

        Dim nodeServer As XmlNode
        Dim thisServerName As String
        Dim nodeFound As Boolean = False

        For Each nodeServer In root.ChildNodes
            Try
                thisServerName = nodeServer.Attributes("name").InnerText

                If thisServerName.ToLower = desiredServer.ToLower Then
                    txtName.Text = thisServerName
                    txtPreMVS.Text = nodeServer.SelectSingleNode("PreMVS").InnerText
                    txtPostMVS.Text = nodeServer.SelectSingleNode("PostMVS").InnerText
                    txtPreCS.Text = nodeServer.SelectSingleNode("PreCS").InnerText
                    txtPostCS.Text = nodeServer.SelectSingleNode("PostCS").InnerText
                    txtMisc.Text = nodeServer.SelectSingleNode("Misc").InnerText
                    nodeFound = True
                    Exit For
                End If
            Catch ex As Exception
            End Try
        Next
             Return nodeFound
       
    End Function

    Function DeleteServer(ByVal desiredServer As String) As Boolean
        Dim doc As New XmlDocument
        doc.Load("c:\VB Testing\UMZ\UMZ.xml")

        Dim root As XmlNode = doc.DocumentElement

        Dim nodeServer As XmlNode
        Dim thisServerName As String
        Dim nodeFound As Boolean = False

        For Each nodeServer In root.ChildNodes
            Try
                thisServerName = nodeServer.Attributes("name").InnerText

                If thisServerName.ToLower = desiredServer.ToLower Then
                    nodeFound = True
                    Exit For
                End If
            Catch ex As Exception
            End Try
        Next

        If nodeFound Then
            root.RemoveChild(nodeServer)
            doc.Save("c:\VB Testing\UMZ\UMZ.xml")
        End If

        Return nodeFound
    End Function
Avatar of S-Twilley
S-Twilley

So in your textboxes... if you edit anything other than the servername... it will update the contents of the corresponding node in the xml file?

Also, if you change the servername as well, should it create a new nodeblock since there is no server name with that name (and add the contends as well)
Ok... here's a method called EditServer

===============================

    Function EditServer(ByVal desiredServer As String, Optional ByVal CreateOnNotFound As Boolean = True) As Boolean
        Dim doc As New XmlDocument

        doc.Load(saveFile)

        Dim root As XmlNode = doc.DocumentElement

        Dim nodeServer As XmlNode
        Dim thisServerName As String
        Dim nodeFound As Boolean = False

        For Each nodeServer In root.ChildNodes
            Try
                thisServerName = nodeServer.Attributes("name").InnerText

                If thisServerName.ToLower = desiredServer.ToLower Then
                    nodeServer.SelectSingleNode("PreMVS").InnerText = txtPreMVS.Text
                    nodeServer.SelectSingleNode("PostMVS").InnerText = txtPostMVS.Text
                    nodeServer.SelectSingleNode("PreCS").InnerText = txtPreCS.Text
                    nodeServer.SelectSingleNode("PostCS").InnerText = txtPostCS.Text
                    nodeServer.SelectSingleNode("Misc").InnerText = txtMisc.Text
                    nodeFound = True
                    Exit For
                End If
            Catch ex As Exception
            End Try
        Next

        If Not nodeFound Then
            AddServer()
        End If

        Return nodeFound
    End Function

============================
I also changed the doc.load part for all the methods:

Dim saveFile As String = "c:\VB Testing\UMZ\UMZ.xml"

put that line at outside of a method... so it's easy to change

and replace all the:    doc.Load("c:\VB Testing\UMZ\UMZ.xml")
with                          doc.Load(saveFile)

==========================================

Usage:

Ok... if you call the method with:

EditServer(txtName.Text)           => Searches for existing server, if found, it updates, if not... it adds a new one
EditServer(txtName.Text, True)  => As Above
EditServer(txtName.Text, False)  => Searches for existing, if found, it updates, if not, it does nothing

The method always returns whether it edits an existing server

============================================

CORRECTION:

        If (Not nodeFound) AND CreateOnNotFound Then
            AddServer()
        End If
Was also thinking that when your project loads you should test whether the xml file exists... if it doesnt.. it creates a template.  "<UMZ />"  is all thats needed.

You should probably also put a Try Catch block around the Doc.Load method  or to test whether the file has been removed during execution.
Also... rather than using the AddServer to add a server... you might find it better to just use the EditServer method... as the AddServer method doesn't check for existing servers... where as using the EditServer method, you can check.
Avatar of Richard Kreidl

ASKER

S-Twilley, it's not working for some reason, here is all my code:

Dim saveFile As String = "c:\VB Testing\UMZ\UMZ.xml"
   
    Private Sub cmdAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAdd.Click
        AddServer()
    End Sub
    Private Sub cmdSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSearch.Click
        LoadServer(txtSearch.Text)
    End Sub
    Private Sub cmdDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDelete.Click
        DeleteServer(txtSearch.Text)
    End Sub
    Private Sub cmdEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdEdit.Click
        EditServer(txtSearch.Text)
    End Sub
    Function EditServer(ByVal desiredServer As String, Optional ByVal CreateOnNotFound As Boolean = True) As Boolean
        Dim doc As New XmlDocument

        doc.Load(saveFile)

        Dim root As XmlNode = doc.DocumentElement

        Dim nodeServer As XmlNode
        Dim thisServerName As String
        Dim nodeFound As Boolean = False

        For Each nodeServer In root.ChildNodes
            Try
                thisServerName = nodeServer.Attributes("name").InnerText

                If thisServerName.ToLower = desiredServer.ToLower Then
                    nodeServer.SelectSingleNode("PreMVS").InnerText = txtPreMVS.Text
                    nodeServer.SelectSingleNode("PostMVS").InnerText = txtPostMVS.Text
                    nodeServer.SelectSingleNode("PreCS").InnerText = txtPreCS.Text
                    nodeServer.SelectSingleNode("PostCS").InnerText = txtPostCS.Text
                    nodeServer.SelectSingleNode("Misc").InnerText = txtMisc.Text
                    nodeFound = True
                    Exit For
                End If
            Catch ex As Exception
            End Try
        Next

         If (Not nodeFound) And CreateOnNotFound Then
            AddServer()
        End If

        Return nodeFound
    End Function

    Sub AddServer()
        Dim doc As New XmlDocument
        doc.Load(saveFile)

        Dim root As XmlNode = doc.DocumentElement
        Dim EleName As XmlElement = doc.CreateElement("Server")
        Dim ElePreMVS As XmlElement = doc.CreateElement("PreMVS")
        Dim ElePostMVS As XmlElement = doc.CreateElement("PostMVS")
        Dim ElePreCS As XmlElement = doc.CreateElement("PreCS")
        Dim ElePostCS As XmlElement = doc.CreateElement("PostCS")
        Dim EleMisc As XmlElement = doc.CreateElement("Misc")

        EleName.SetAttribute("name", txtName.Text)
        ElePreMVS.InnerText = txtPreMVS.Text
        ElePostMVS.InnerText = txtPostMVS.Text
        ElePreCS.InnerText = txtPreCS.Text
        ElePostCS.InnerText = txtPostCS.Text
        EleMisc.InnerText = txtMisc.Text

        EleName.AppendChild(ElePreMVS)
        EleName.AppendChild(ElePostMVS)
        EleName.AppendChild(ElePreCS)
        EleName.AppendChild(ElePostCS)
        EleName.AppendChild(EleMisc)

        root.AppendChild(EleName)
        doc.Save(saveFile)
    End Sub
    Function LoadServer(ByVal desiredServer As String) As Boolean
        Dim doc As New XmlDocument
        doc.Load(saveFile)

        Dim root As XmlNode = doc.DocumentElement

        Dim nodeServer As XmlNode
        Dim thisServerName As String
        Dim nodeFound As Boolean = False

        For Each nodeServer In root.ChildNodes
            Try
                thisServerName = nodeServer.Attributes("name").InnerText

                If thisServerName.ToLower = desiredServer.ToLower Then
                    txtName.Text = thisServerName
                    txtPreMVS.Text = nodeServer.SelectSingleNode("PreMVS").InnerText
                    txtPostMVS.Text = nodeServer.SelectSingleNode("PostMVS").InnerText
                    txtPreCS.Text = nodeServer.SelectSingleNode("PreCS").InnerText
                    txtPostCS.Text = nodeServer.SelectSingleNode("PostCS").InnerText
                    txtMisc.Text = nodeServer.SelectSingleNode("Misc").InnerText
                    nodeFound = True
                    Exit For
                End If
            Catch ex As Exception
            End Try
        Next
       Return nodeFound

    End Function

    Function DeleteServer(ByVal desiredServer As String) As Boolean
        Dim doc As New XmlDocument
        doc.Load(saveFile)

        Dim root As XmlNode = doc.DocumentElement

        Dim nodeServer As XmlNode
        Dim thisServerName As String
        Dim nodeFound As Boolean = False

        For Each nodeServer In root.ChildNodes
            Try
                thisServerName = nodeServer.Attributes("name").InnerText

                If thisServerName.ToLower = desiredServer.ToLower Then
                    nodeFound = True
                    Exit For
                End If
            Catch ex As Exception
            End Try
        Next

        If nodeFound Then
            root.RemoveChild(nodeServer)
            doc.Save(saveFile)
        End If

        Return nodeFound
    End Function

I type in an exiting server name in the txtSearch.textbox and click cmdEditServer button and the textboxes don't populate with the data.  Then I tried typing in an existing server and clicking the cmdSearch button which finds the server ok and populates the textboxes. I make my changes to the textboxes and then click cmdEditServer and it doesn't update.

It looks like it should work, but I'm not sure why.
why would the textboxes populate when you click edit server?  isn't it the case that when you click on edit server... that the xml file is updated with the contents of the textboxes?

to populate data from the xml file and update the textboxes... you use the search button (which uses LoadServer).. which you say works

S-Twilley, I think the problem is with this 'if ' statement:

 If (Not nodeFound) AND CreateOnNotFound Then
            AddServer()
        End If

When I removed the 'If' statement and just left AddServer()
 I make my changes and click cmdEditServer and it adds a dup server name.
Your right, I click the search button and it populates the textboxes if the servername  exists. I make my changes and click cmdEditServer and it doesn't update.
The progress of EditServer should be this:

IF SERVER EXISTS IN XML FILE
     UPDATE THAT SERVER WITH VALUES OF TEXTBOXES (txtPreMVS through to txtMisc)

ELSE (if server doesn't exist in file)
     IF USER HAS REQUESTED THAT SERVER SHOULD BE ADDED IF IT DOESNT EXIST
           CREATE SERVER AND USE VALUES OF TEXTBOXES  (txtPreMVS through to txtMisc)
     END IF
END IF
ASKER CERTIFIED SOLUTION
Avatar of S-Twilley
S-Twilley

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yep, that was it. Sorry if i'm not being clear on my description of the problem. Thanks again for your quick response.