locked
XML...add new XML elements to existing document RRS feed

  • Question

  • I asked this earlier, but didn't get an answer.  I'd really like to figure this out.  It seems like it shouldn't be too hard to do.  I'm making an application to keep track of recipes.  I'm able to add two recipes, but when I add a third, it overwrites the last one in the file with the new one I'm adding.  Can anyone give me any suggestions on how to do this?  Here's my code.

    Private Sub Save_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Save.Click
            Dim newdoc As Xml.XmlDataDocument
            Dim olddoc As New Xml.XmlDocument
            Dim xtwcurrent As Xml.XmlTextWriter
            xtwcurrent = New Xml.XmlTextWriter("C:\recipe\myrecipe.xml", System.Text.Encoding.UTF8)
            If Not System.IO.File.Exists("C:\recipe\myrecipe.xml") Then
                With xtwcurrent
                    For x = 0 To Ingredients.Items.Count - 1
                        .WriteStartElement("Item")
                        .WriteValue(Ingredients.Items.Item(x))
                        .WriteEndElement()
                    Next x
                    .WriteEndElement()
                    .WriteStartElement("Directions")
                    For y As Integer = 0 To lines.GetUpperBound(0)
                        .WriteStartElement("Step")
                        .WriteValue(lines(y))
                        .WriteEndElement()
                    Next y
                    .WriteEndElement()
                    .WriteStartElement("Comments")
                    For z As Integer = 0 To clines.GetUpperBound(0)
                        .WriteStartElement("Step")
                        .WriteValue(clines(z))
                        .WriteEndElement()
                    Next z
                    .WriteEndElement()
                    .WriteEndElement()
                    .WriteEndElement()
                    .WriteEndDocument()
                    .Close()
                End With
            End If
                        Next
                    End If
                Next
            End If
            With xtwcurrent
                .WriteStartElement("Recipe")
                .WriteStartAttribute("Name")
                .WriteValue(RName.Text)
                .WriteEndAttribute()
                .WriteStartElement("Ingredients")
                Dim x As Integer = 0
                For x = 0 To Ingredients.Items.Count - 1
                    .WriteStartElement("Item")
                    .WriteValue(Ingredients.Items.Item(x))
                    .WriteEndElement()
                Next x
                .WriteEndElement()
                .WriteStartElement("Directions")
                Dim lines() As String = Directions.Lines
                For y As Integer = 0 To lines.GetUpperBound(0)
                    .WriteStartElement("Step")
                    .WriteValue(lines(y))
                    .WriteEndElement()
                Next y
                .WriteEndElement()
                .WriteStartElement("Comments")
                Dim comlines() As String = Comments.Lines
                For z As Integer = 0 To comlines.GetUpperBound(0)
                    .WriteStartElement("Step")
                    .WriteValue(comlines(z))
                    .WriteEndElement()
                Next z
                .WriteEndElement()
                .WriteEndDocument()
                newdoc.Save("C:\recipe\myrecipe.xml")
                .Close()
            End With
    Else
            Dim newdoc As Xml.XmlDataDocument
            Dim olddoc As New Xml.XmlDocument
            Dim xtwcurrent As Xml.XmlTextWriter
            xtwcurrent = New Xml.XmlTextWriter("C:\recipe\myrecipe.xml", System.Text.Encoding.UTF8)
            Dim rnodes As Xml.XmlNodeList = olddoc.SelectSingleNode("Recipes").ChildNodes
            Dim rnode As Xml.XmlNode
            With xtwcurrent
                .Formatting = Xml.Formatting.Indented
                .WriteStartDocument()
                .WriteDocType("Recipe", Nothing, Nothing, Nothing)
                .WriteStartElement("Recipes")
            End With
            For Each rnode In rnodes
                If rnode.Name = "Recipe" Then
                    newdoc.CreateNode(Xml.XmlNodeType.Element, Nothing, rnode.Name, Nothing)
                    xtwcurrent.WriteStartElement("Recipe")
                    xtwcurrent.WriteStartAttribute("Name")
                    xtwcurrent.WriteValue(rnode.Attributes(0).Value)
                    xtwcurrent.WriteEndAttribute()
                    Dim rchild As Xml.XmlNode
                    Dim rstuff As Xml.XmlNodeList = rnode.ChildNodes
                    For Each rchild In rstuff
                        If rchild.Name = "Ingredients" Then
                            Dim x As Integer = 0
                            With xtwcurrent
                                .WriteStartElement("Ingredients")
                                Dim ingchild As Xml.XmlNode
                                Dim ingchildren As Xml.XmlNodeList = rchild.ChildNodes
                                For Each ingchild In ingchildren
                                    .WriteStartElement("Item")
                                    .WriteValue(ingchild.InnerText)
                                    .WriteEndElement()
                                Next
                                .WriteEndElement()
                            End With
                        ElseIf rchild.Name = "Directions" Then
                            With xtwcurrent
                                .WriteStartElement("Directions")
                                Dim child As Xml.XmlNode
                                Dim rgchild As Xml.XmlNodeList = rchild.ChildNodes
                                For Each child In rgchild
                                    .WriteStartElement("Step")
                                    .WriteValue(child.InnerText)
                                    .WriteEndElement()
                                Next
                                .WriteEndElement()
                            End With
                        ElseIf rchild.Name = "Comments" Then
                            With xtwcurrent
                                Dim clines As Integer = rnode.ChildNodes.Count
                                .WriteStartElement("Comments")
                                Dim comchild As Xml.XmlNode
                                Dim comchildren As Xml.XmlNodeList = rchild.ChildNodes
                                For Each comchild In comchildren
                                    .WriteStartElement("Step")
                                    .WriteValue(comchild.InnerText)
                                    .WriteEndElement()
                                Next
                                .WriteEndElement()
                                .WriteStartElement("Recipe")
                                .WriteStartAttribute("Name")
                                .WriteValue(RName.Text)
                                .WriteEndAttribute()
                                .WriteStartElement("Ingredients")
                                Dim x As Integer = 0
                                For x = 0 To Ingredients.Items.Count - 1
                                    .WriteStartElement("Item")
                                    .WriteValue(Ingredients.Items.Item(x))
                                    .WriteEndElement()
                                Next x
                                .WriteEndElement()
                                .WriteStartElement("Directions")
                                Dim lines() As String = Directions.Lines
                                For y As Integer = 0 To lines.GetUpperBound(0)
                                    .WriteStartElement("Step")
                                    .WriteValue(lines(y))
                                    .WriteEndElement()
                                Next y
                                .WriteEndElement()
                                .WriteStartElement("Comments")
                                Dim comlines() As String = Comments.Lines
                                For z As Integer = 0 To comlines.GetUpperBound(0)
                                    .WriteStartElement("Step")
                                    .WriteValue(comlines(z))
                                    .WriteEndElement()
                                Next z
                                .WriteEndElement()
                                .WriteEndDocument()
                                'newdoc.Save("C:\recipe\myrecipe.xml")
                                .Close()

                            End With
                        End If

        End Sub

    Friday, June 2, 2006 2:14 PM

All replies

  • hi,

    why don't you use just xmldocument it will make it easier for you , you can try something like this



    Dim doc As XmlDocument New XmlDocument

        
        
    Private Sub Form1_Load(ByVal sender As ObjectByVal As EventArgs)
            doc.Load(
    "XMLFile1.xml")
        
    End Sub
        
        Private Sub 
    button1_Click(ByVal sender As ObjectByVal As EventArgs)
            
    'parent node
            
    Dim cat As XmlElement doc.CreateElement("Category")
            cat.InnerText 
    textBox1.Text
            cat.SetAttribute(
    "name", textBox2.Text)


            
    'child node
            
    Dim subCat As XmlElement doc.CreateElement("SubCategory")
            subCat.InnerText 
    textBox3.Text
            subCat.SetAttribute(
    "address", textBox4.Text)


            
    'Add the child node to its parent
            
    cat.AppendChild(subCat)


            
    'add the parent node to the root node in the document
            
    doc.DocumentElement.AppendChild(cat)

            
    'let the document save its content
            
    doc.Save("XMLFile1.xml")
        
    End Sub

     

    Friday, June 2, 2006 4:11 PM
  • I tried your example, and it didn't save anything.  It didn't give me any errors, but it didn't save to the file I told it to.
    Friday, June 2, 2006 6:38 PM
  • Actually, it wasn't doing anything because Button needs to be capitalized in the event name.  I got an error on this line when I ran it.

    'add the parent node to the root node in the document

    doc.DocumentElement.AppendChild(cat)

     

    The error I got was Object reference not set to an instance of an object.  If I look at the value of cat, alot of the values (like InnerXML) say this:

    {"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."}

    Most of the others, if they don't say that line, say Object reference not set to an instance of an object.  What's causing this?

     

    EDIT:

      I just fixed this.  Strange problem, but I put the Doc.Load line in the Button1_Click event instead of Form1_Load.

    Friday, June 2, 2006 6:44 PM
  • This still doesn't work for me.  It's giving me the same problem I had earlier when I tried this on my own.  If I add something to the XML and then try to add something else, it overwrites the first thing I added with the second.  Why does it do this?  Is there any way to have it keep making a new element called "Category" in this case with all of its children instead of overwriting the last one?
    Friday, June 2, 2006 6:49 PM
  • hi,

    xml is like text file , if you opened a file and edit then you have to save the entire file back,

    if you tried to add something without loading the file you will lose the previous data, textfile has append which can add to the end of the file , but i don't know anything to do the same in xml file except loading the entire file , edit it , save it back to the file

    would you post your exact code , and highlight where is the problem occur plz

    hope this helps

    Monday, June 19, 2006 6:44 PM
  • sorry i went back to this code and tried it again, the funny thing it didn't work normaly , its only work normaly if you have a break point during debugging very strange but i don't know what's wrong

    best regards

    Monday, June 19, 2006 7:37 PM