[VB.NET] XML - Create and Merge Files. Edit, Add and Delete Nodes.
There have been some posts recently regarding creating, editing, deleting and adding to XML files. I couldn't find a post in the VB.NET CodeBank regarding XML, so I thought I'd use my basic XML skills and contribute this brief post. So here are some very basic ways of working with XML files. These snippets assume you know what XML is and that there is a System.Xml namespace available in the .NET Framework 2.0 designed to manipulate XML files. Reading through the documentation on the System.Xml namespace will greatly help!
These are the ways that, so far, I have found to work and to be the most simple. I am still learning the System.Xml namespace. If anyone would like to comment on better ways to do something, please let me know!
I'd be happy to update this post to help everybody.
Creating an XML File
Here we'll use the XmlWriter to create a new XML file. This part of working with XML files is fairly straightforward and easy. Here are the steps:
Create an XmlWriter
This class does just what it sounds like it does. It is a fast, forward-only way to write XML files.
Prepare the settings for the writer. In this case, only choosing to indent each element.
Write a declaration
In the basic form that we are using it, the declaration specifies which version of XML we are using and how it is encoded.
Write a comment
Write the root element
Each XML file can have only one root element. In our case it is the "People" element.
Write elements and attributes that contain information about our "Person."
Each person elements contain elements that describe that person in greater detail.
Each person contains an attribute called "ID" that will help us easier identify the person later.
VB.NET Code:
' Set up our XmlWriter settings.
Dim settings as new XmlWriterSettings()
settings.Indent = True
' Initialize the XmlWriter.
Dim XmlWrt As XmlWriter = XmlWriter.Create("C:\XmlTest.xml", settings)
With XmlWrt
' Write the Xml declaration.
.WriteStartDocument()
' Write a comment.
.WriteComment("Xml example.")
' Write the root element.
.WriteStartElement("People")
' Start our first person.
.WriteStartElement("Person")
' Give this person the attribute ID of 1.
.WriteAttributeString("ID", "1")
' The person nodes.
.WriteStartElement("Name")
.WriteString("Bob")
.WriteEndElement()
.WriteStartElement("Age")
.WriteString("28")
.WriteEndElement()
.WriteStartElement("Weight")
.WriteString("180")
.WriteEndElement()
' The end of this person.
.WriteEndElement()
' Next person.
.WriteStartElement("Person")
.WriteAttributeString("ID", "2")
.WriteStartElement("Name")
.WriteString("Julie")
.WriteEndElement()
.WriteStartElement("Age")
.WriteString("34")
.WriteEndElement()
.WriteStartElement("Weight")
.WriteString("125")
' The end of this person.
.WriteEndElement()
' The end of People.
.WriteEndElement()
' Close the XmlTextWriter.
.WriteEndDocument()
.Close()
End With
Edit an XML File
Now that we have an XML file, we can edit it. Bob has turned a year older so we need to change his age. With the XmlDocument class we can get this done.
Find Bob with his attribute ID of 1
It is very easy to find an individual person using their attribute called "ID" since we created this in our first step.
We are using the XPath to find the person with the correct ID.
The XPath is a language used to easily traverse through an XML files elements.
Change the nodes we want
Since we have located Bob's node we can edit any of his child nodes or details. In this case we will edit his second child node (index of 1): his age.
Save the document
Clearly this is an important point, but it seems to be missed quite often. Don't forget to save!
VB.NET Code:
' Load the XmlDocument.
Dim xd As New XmlDocument()
xd.Load("C:\XmlTest.xml")
' Find the node where the Person's attribute ID is 1 using its XPath.
Dim nod As XmlNode = xd.SelectSingleNode("/People/Person[@ID='1']")
Add to an XML File
There are certainly different approaches to appending elements to an XML file. This is the one that I found easiest to use; particularly when adding an entire Person in our case.
Create a string containing the information about the person that we want to add to our XML file
At the moment this is, of course, just a string. However, it does hold the information that we want to add to our XML file.
Though the XML will look nice if you view it in a browser no matter how it looks as a regular text file, for the sake of keeping it looking nice when viewed in Notepad, the string is formatted as such.
This is, again, just what it sounds like. This is a lightweight document fragment that is very useful for inserting nodes into an XML file.
Next we set the fragment's InnerXml to our string.
Append that fragment to our file
Now that we have the node setup we can append this to the end of our XmlDocument.
Notice that we get the XML file's root with the DocumentElement property. We don't want to append this outside of the root.
Save the document
Don't forget to save!
VB.NET Code:
' Create our string that holds our new Person information.
Dim cr as String = Environment.Newline
Dim newPerson As String = _
"<Person ID='3'>" & cr & _
" <Name>Tommy</Name>" & cr & _
" <Age>62</Age>" & cr & _
" <Weight>190</Weight>" & cr & _
" </Person>"
' Load the XmlDocument.
Dim xd As New XmlDocument()
xd.Load("C:\XmlTest.xml")
' Create a new XmlDocumentFragment for our document.
Dim docFrag As XmlDocumentFragment = xd.CreateDocumentFragment()
' The Xml for this fragment is our newPerson string.
docFrag.InnerXml = newPerson
' The root element of our file is found using
' the DocumentElement property of the XmlDocument.
Dim root As XmlNode = xd.DocumentElement
' Append our new Person to the root element.
root.AppendChild(docFrag)
' Save the Xml.
xd.Save("C:\XmlTest.xml")
Delete an XML Node
We don't need Bob in our list of People any longer so we can now delete him. You alrealdy found him when we edited him, so we just need to change the code so we delete him instead. Easy!
Load the XmlDocument once again
Find his node again by using the correct XPath
You've done this before so this is no problem!
Delete all of his information
We have Bob's node. We then get his parent to remove Bob's node and all details using the RemoveChild method.
Save the document
That's right. Don't forget to save!
VB.NET Code:
' Load the XmlDocument.
Dim xd As New XmlDocument()
xd.Load("C:\XmlTest.xml")
' Find Bob's node with the attribute ID of 1
' using the XPath again.
Dim nod As XmlNode = xd.SelectSingleNode("/People/Person[@ID='1']")
Well, that's it for now. There will be more to come on XML. I can't get enough!
I hope that these basics have helped you begin your journey into VB.NET and XML. You can also find a small application using these snippets attached. Good luck!
Last edited by nmadd; Jul 16th, 2007 at 03:22 PM.
Reason: Updated formatting & some code. Changed title.
Re: [VB.NET] XML - Create and Merge Files. Edit, Add and Delete Nodes.
Merge Two XML Files
Let's say that you have two XML files that you would like to combine into one. So how do you "merge" two XML files? Well, you can read from one and by using the ImportNode method, append to the other.
Setup and load the two XmlDocuments
Loop through all of the nodes in the "from" document
All of the nodes inside of the root that is.
Import each node to the "to" document
Append each node to the "to" document
Save!
VB.NET Code:
' The XmlDocument that we want to merge from.
Dim xdFrom As New XmlDocument()
xdFrom.Load("C:\XmlTest2.xml")
' The XMLDocument that we want to merge to.
Dim xdTo As New XmlDocument()
xdTo.Load("C:\XmlTest.xml")
' Loop through all of the nodes in the "from" document.
' We don't want to copy the root node in this instance.
For Each nod As XmlNode In xdFrom.DocumentElement.ChildNodes
' Import the node to our "to" document.
Dim tmpNod As XmlNode = xdTo.ImportNode(nod, True)
' Append this temporary node to the end of the "to" document
' but inside the root element.
xdTo.DocumentElement.AppendChild(tmpNod)
Next nod
' Save the "to" document with it's newly appended nodes.
xdTo.Save("C:\XmlTest.xml")
That's it! Your original XML file now contains all the nodes from the "from" file as well. The attached file in post #1 has been updated.
Re: [VB.NET] XML - Create and Merge Files. Edit, Add and Delete Nodes.
Hiya, I read your post which was really helpful!!
I do have a problem I was wondering whether you could help me with?
I am trying to read the content.xml of an openoffice document and want to find out the xPath to a textbox in a frame within the document which contains the text "mytextbox1"....
Code:
'to unzip and read content.xml of an opendocument text file
Dim objTextDocument As New AODL.Document.TextDocuments.TextDocument
'load opendocument text file
objTextDocument.Load("C:\Users\Lynwen\Documents\textbox1.odt")
'access the textbox in content.xml
Dim nod As XmlNode = objTextDocument.XmlDoc.SelectSingleNode("
office:document-content/office:body/office:text/text:p/draw:frame/draw:text-box/text:p[@text='mytextbox']")
I have no idea how to find the xpath to the textbox... here is the xml file
Re: [VB.NET] XML - Create and Merge Files. Edit, Add and Delete Nodes.
Howdy,
The namespaces in your XML make it a little more difficult, but thanks to help from the .NET XML namespace, not much.
All you should need to do is add the appropriate namespace to your XmlDocument's SelectSingleNode method. There is on overload of this method that will accept a XmlNameSpaceManager.
VB.NET Code:
Dim xd As New XmlDocument()
xd.Load("c:\sample.xml")
Dim xNM As New XmlNamespaceManager(xd.NameTable)
' Add the text namespace to your manager and then include it in the method below.
Re: [VB.NET] XML - Create and Merge Files. Edit, Add and Delete Nodes.
Hi! Thanks, I'm beginning to get a better understanding now...
I do still have a problem however, this is my code so far
Code:
Dim xd As New XmlDocument
xd.Load("..\debug\aodlread\content.xml")
Dim xNM As New XmlNamespaceManager(xd.NameTable)
xNM.AddNamespace("draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0")
Dim nod As XmlNode = xd.SelectSingleNode("//draw:frame[@name='Frame1']", xNM)
If nod IsNot Nothing Then
MessageBox.Show("found")
Else
MessageBox.Show("not found")
End If
The location to the xml file is correct, and the name space for drawing should be too... I cant understand why it keeps saying not found, when it should find a frame called Frame1
So I took the namespace for draw, being: xmlns:draw="urnasis:names:tcpendocument:xmlns:drawing:1.0" for the namespace with prefix "draw". Then wanted to access the frame within the draw, hence //draw:frame then wanted to find Frame1 hence [@name='Frame1'], which according to the xml file should be okay? but I'm still getting nod=nothing
Re: [VB.NET] XML - Create and Merge Files. Edit, Add and Delete Nodes.
Problem solved, I was looking in the wrong place!!!
Here is my solution..
Code:
Dim objTextDocument As New AODL.Document.TextDocuments.TextDocument
Dim txtTitle As String = "new title inserted!"
Dim txtImage As String = "new image inserted!"
Dim txtBarcode As String = "new barcode inserted!"
Dim txtPrice As String = "new price inserted!"
Dim node As Xml.XmlNode
Dim xd As New Xml.XmlDocument
objTextDocument.Load("C:\Users\Lynwen\Documents\textbox1.odt")
xd.Load("..\debug\aodlread\content.xml")
Dim xNM As New XmlNamespaceManager(xd.NameTable)
xNM.AddNamespace("draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0")
Dim nodeList As XmlNodeList = xd.SelectNodes("//draw:frame", xNM)
If nodeList IsNot Nothing Then
For Each node In nodeList
MessageBox.Show(node.InnerText)
Select Case node.InnerText
Case "title"
node.InnerText = txtTitle
Case "image"
node.InnerText = txtImage
Case "barcode"
node.InnerText = txtBarcode
Case "price"
node.InnerText = txtPrice
End Select
Next
xd.Save("c:\Users\Lynwen\Documents\content.xml")
Else
MessageBox.Show("not found")
End If
I just need to find out how to save it as an open document text (.odt) now!!
Re: [VB.NET] XML - Create and Merge Files. Edit, Add and Delete Nodes.
Have you tried the ODFFormsGenerator example which comes with AODL, from there you can try and convert the C# code to VB or:
Below is my code which will save the contents of a textbox or richtextbox into an ODT file, however it does require a SaveFileDialog (the txtbox or rchtxtbox is called txtOutput):
Code:
SaveFileDialog1.Title = "Save a Word Document"
SaveFileDialog1.DefaultExt = "sfu"
SaveFileDialog1.Filter = "Spoof Factory ULTIMATE Documents (Beta)|*.sfu|OpenDocument Text Files(*.odt)|*.odt"
If SaveFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
textDocument.[New]()
Dim p1 As Paragraph = New Paragraph(textDocument)
'Displays the text enetered into the txtOutput control in OpenOffice.org
p1.TextContent.Add(New SimpleText(textDocument, txtOutput.Text))
Dim p2 As Paragraph = New Paragraph(textDocument)
Dim fMain As ODFForm = textDocument.AddNewForm("mainform")
Dim frame As ODFFrame = New ODFFrame(fMain, p2.Content, "frame", "5mm", "5mm", "9cm", "5cm")
frame.Label = "Form"
frame.AnchorType = AnchorType.Paragraph
Dim ft_addinfo As ODFFixedText = New ODFFixedText(fMain, p2.Content, "ft_addinfo", "45mm", "10mm", "45mm", "4mm")
ft_addinfo.Label = "Additional information"
Dim addinfo As ODFTextArea = New ODFTextArea(fMain, p2.Content, "addinfo", "45mm", "14mm", "45mm", "25mm")
addinfo.CurrentValue = txtOutput.Text
addinfo.AnchorType = AnchorType.Paragraph
addinfo.Properties.Add(New SingleFormProperty(textDocument, PropertyValueType.Boolean, "MultiLine", "true"))
textDocument.Content.Add(p1)
textDocument.Content.Add(p2)
textDocument.SaveTo(SaveFileDialog1.FileName)
lastOpenedFile = SaveFileDialog1.FileName
End If
End Sub
Re: [VB.NET] XML - Create and Merge Files. Edit, Add and Delete Nodes.
Hello! This is really a great example you have given but i am having problems with the add to xml thing.
Here's my code:
Code:
' Create our string that holds our new Movie Info
Dim cr As String = Environment.NewLine
Dim newMovie As String = _
"<Moviename xmlns=" + name + ">" & cr & _
" <Directory>" + dirname + "</Directory>" & cr & _
" <Bitrate>BitrateHere</Bitrate>" & cr & _
" </MovieName>"
' Load the XmlDocument.
Dim xd As New XmlDocument()
xd.Load("data.xml")
' Create a new XmlDocumentFragment for our document.
Dim docFrag As XmlDocumentFragment = xd.CreateDocumentFragment()
' The Xml for this fragment is our newPerson string.
docFrag.InnerXml = newMovie
' The root element of our file is found using
' the DocumentElement property of the XmlDocument.
Dim root As XmlNode = xd.DocumentElement
' Append our new Person to the root element.
root.AppendChild(docFrag)
' Save the Xml.
xd.Save("data.xml")
Where name and dirname is a movie name and a directory name that the user has chosen from a openfiledialog.
It hungs up at the docfrag.innerxml line throwing this:
'IntoTheBlue.mp4' is an unexpected token. The expected token is '"' or '''. Line 1, position 18.