To create an XML element, you can directly type the XML code in
a document and then save the file with and .xml extension. As an alternative and as
we saw in our introduction, you can call the XmlDocument.LoadXml() method to
which you would pass the starting XML code, then save the file by calling the
XmlDocument.Save() method to which you would pass the name (and/or path) of
the file. This can be done as follows:

In some cases, you will want the user to provide you with the
necessary value(s) to create an element. Fortunately, the XmlDocument, the XmlNode,
and the XmlElement classes provide all the necessary properties and methods to add a new element.

Creating an Element

To assist you with programmatically creating a new element, the XmlDocument
class is equipped with a method named CreateElement that is overloaded with three
versions. One of the versions uses the following syntax:

Public Function CreateElement(ByVal name As String) As XmlElement

To create a new element, call this method and pass it the name of the element.
Here is an example:

In order to add the new element to the document, you must specify its position in the
tree: whether it would be the first or the last node, whether you want to
position it before or after a node of your choice, etc. For example, if you want to
add a new element to a document, the element would be considered a child of the
root, that is, a child of the XmlDocument.DocumentElement property.

To support the positions of existing nodes, the XmlNode class, which is the ancestor to all XML
nodes of the .NET Framework, provides various methods. One of these methods is named AppendChild. It is
used to add an element as the last child of its parent. The syntax of the XmlNode.AppendChild()
method is:

Public Overridable Function AppendChild(ByVal newChild As XmlNode) As XmlNode

When calling this method, pass the XmlNode object you
had previous created. After adding the node, if you want to keep it,
you should save the file. Here is an example:

In the previous code, we assumed that the primary XML file
had already been created. If the file cannot be found, the server would produce
an error. Therefore, in most cases, you should first check whether the file
exists. This can be done as follows:

The above code would create a new element only if the file exists
already. If there is no such a file, nothing would happen. If you want, after chcking
the existense of the file, if it doesn't exist, you can first create it, and then
add the new element to it. This can be done as follows:

Of course, you can check the existense of the file by its name or as a Stream-based object.

When creating a new element, one of your concerns is to specify
what node will own the new element. As we know already, you can get a list of nodes
that use a certain name by calling the XmlDocument.GetElementsByTagName()
method. You can also locate an element using its position (or index) in the
collection of nodes. You can then decide whether the new element will be a child of
that node. This can be done by simply calling the AppendChild() method on that
node. Here is an example:

or you can decide that the new node would be created on the same level
as the node, or on the same level as parent node, etc. Here is an example that adds a new element to a node gotten
from its index and XML element name:

We already know that the XmlNode.InnerXml property
includes a node, its markup, its child(ren) and their markup. This means that
you can create the child node(s) with its (their) markup(s) as a string and
assign that string to an XmlNode.InnerXml property:

If you want the element to
have a value, the XmlDocument class provides the CreateTextNode()
method. This method returns an XmlText value. The syntax of this method
is:

Public Overridable Function CreateTextNode(ByVal text As String) As XmlText

This method takes as argument the string that would
constitute the value of the element. Before calling it, you should have used the
XmlNode.AppendChild() method to create a node. Calling this method on the
LastChild node of the one that called the AppendChild() method would
specify the value of the new node. Here is an example:

Notice that the root, chemistry, has a repetitive
child named element. This element element has its own child named name.
Imagine that you want to add a new element node that has a child. To
do this, first create an empty element node as a child of the root
(we learned earlier how to do that). After creating the new child of the root, initialize the
grand child with the desired name (the name doesn't have to be one of the
existing names) and a value (which is optional if you don't want the new node to
have a value). Once the new node is ready, append it as the last child of the
root. If this new node has a value, append its XmlText object as the LastChild
of the LastChild of the root. Here is an example of how you would do this:

The combination of calls to XmlDocument.CreateElement()
and XmlDocument.CreateTextNode() allow you to create a new element that
has a value. As done above, you can keep using that combination to create a new
element and its child nodes. Here are examples:

As we have seen in previous sections, to add an element as the
last node of an element, create an XmlElement object and call the AppendChild()
method.

Inserting an Element Referencing a Sibling

Instead of simply adding a new node at the end of child
nodes, you may want the new node to precede an existing child node. To support this operation, the XmlNode
class provides the InsertBefore() method. Its syntax is:

Public Overridable Function InsertBefore(ByVal newChild As XmlNode,
ByVal refChild As XmlNode) As XmlNode

The first argument of this method is the new node that will
be added. The second argument is the sibling that will succeed the new node.

You can add a new node to position it after a known element. To support this, the XmlNode
class is equipped with a method named InsertAfter. Its syntax is:

Public Overridable Function InsertAfter(ByVal newChild As XmlNode,
ByVal refChild As XmlNode) As XmlNode

As a result, using one of these methods, you can add children of an
existing node after locating that node. Here is an example:

<%@ Page Language="VB" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Xml" %>
<!DOCTYPE html>
<html>
<head runat="server">
<script runat="server">
Private Sub btnCreateIntersectionClick(ByVal sender As Object, ByVal e As EventArgs)
Dim xeRoad As XmlElement
Dim xnRoad, xnChild As XmlNode
Dim xdRoads As New XmlDocument()
Dim xnlRoads, xnlChildren As XmlNodeList
Dim strRoadsFile = Server.MapPath("roads1.xml")
If File.Exists(strRoadsFile) Then
Using fsRoad As New FileStream(strRoadsFile, FileMode.Open, FileAccess.Read)
xdRoads.Load(strRoadsFile)
End Using
' Create a list of nodes whose name is Title
xnlRoads = xdRoads.GetElementsByTagName("road")
Using fsRoad As New FileStream(strRoadsFile, FileMode.Create, FileAccess.Write)
' Now you can check each node of the list
For Each xnRoad in xnlRoads
' Within a Road, create a list of its children
xnlChildren = xnRoad.ChildNodes
' Visit each child node
For Each xnChild in xnlChildren
' If the child node, the road name, is I-81
If xnChild.InnerText = "I-81" Then
' Create an element named intersection
xeRoad = xdRoads.CreateElement("intersection")
' Specify the text of the new element
xeRoad.InnerText = "I-77"
' Insert the new node below the selected one
xnRoad.InsertAfter(xeRoad, xnChild)
' Save the file
xdRoads.Save(fsRoad)
Exit Sub
End If
Next
Next
End Using
End If
End Sub
</script>
<title>Road System Database - New Intersecting Road</title>
</head>
<body>
<h3>Road System Database - New Intersecting Road</h3>
<form id="frmRoads" runat="server">
<asp:Button id="btnCreateIntersection" Text="Create Intersecting Road"
OnClick="btnCreateIntersectionClick" runat="server"></asp:Button>
</form>
</body>
</html>

<%@ Page Language="VB" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Xml" %>
<!DOCTYPE html>
<html>
<head runat="server">
<script runat="server">
Private Sub btnCreateIntersectionClick(ByVal sender As Object, ByVal e As EventArgs)
Dim xeRoad As XmlElement
Dim xnRoad, xnChild As XmlNode
Dim xdRoads As New XmlDocument()
Dim xnlRoads, xnlChildren As XmlNodeList
Dim strRoadsFile = Server.MapPath("roads1.xml")
If File.Exists(strRoadsFile) Then
Using fsRoad As New FileStream(strRoadsFile, FileMode.Open, FileAccess.Read)
xdRoads.Load(strRoadsFile)
End Using
' Create a list of nodes whose name is Title
xnlRoads = xdRoads.GetElementsByTagName("road")
Using fsRoad As New FileStream(strRoadsFile, FileMode.Create, FileAccess.Write)
' Now you can check each node of the list
For Each xnRoad in xnlRoads
' Within a Road, create a list of its children
xnlChildren = xnRoad.ChildNodes
' Visit each child node
For Each xnChild in xnlChildren
' If the child node, the road name, is I-81
If xnChild.InnerText = "I-81" Then
' Create an element named intersection
xeRoad = xdRoads.CreateElement("intersection")
' Specify the text of the new element
xeRoad.InnerText = "I-77"
' Insert the new node below the selected one
xnRoad.InsertAfter(xeRoad, xnChild.NextSibling.NextSibling.NextSibling)
' Save the file
xdRoads.Save(fsRoad)
Exit Sub
End If
Next
Next
End Using
End If
End Sub
</script>
<title>Road System Database - New Intersecting Road</title>
</head>
<body>
<h3>Road System Database - New Intersecting Road</h3>
<form id="frmRoads" runat="server">
<asp:Button id="btnCreateIntersection" Text="Create Intersecting Road"
OnClick="btnCreateIntersectionClick" runat="server"></asp:Button>
</form>
</body>
</html>

The .NET Framework implementation of XML provides various
options to change the aspect, the structure, and/or the value(s), of an element. For example, you can use the same
logic used in collection classes. This consists of locating a node and
simply changing its value(s), then saving the file. Here is an example:

On the other hand, the XmlNode class is equipped with
a method named ReplaceChild. Its syntax is:

Public Overridable Function ReplaceChild(ByVal newChild As XmlNode,
ByVal oldChild As XmlNode) As XmlNode

To use this method, you can first create a new XmlNode. Then locate
an existing element and get its reference. When you call this method, pass the new element as
the first argument and pass the existing element as the second argument.

Deleting Elements

Deleting an Element

If you have a node you don't want or don't need anymore in
a document, you can delete it. To let you delete a node, the XmlNode class provides
the RemoveChild() method. Its syntax is:

Public Overridable Function RemoveChild(ByVal oldChild As XmlNode) As XmlNode

This method takes as argument the node to delete. If the
node exists, it would be deleted and the method would return the node that was
deleted. If the node does not exist, nothing would happen. Here is an example:

<%@ Page Language="VB" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Xml" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Exercise</title>
</head>
<body>
<h3>Exercise</h3>
<%
Dim xnEmployee As XmlNode
Dim xdEmployees As New XmlDocument()
Dim xnlEmployees, xnlChildren As XmlNodeList
Dim strFileName = Server.MapPath("exercises/employees.xml")
If File.Exists(strFileName) Then
Using fsEmployee As New FileStream(strFileName, FileMode.Open, FileAccess.Read)
xdEmployees.Load(strFileName)
End Using
' Create a list of nodes whose name is Title
xnlEmployees = xdEmployees.GetElementsByTagName("employee")
Using fsEmployee As New FileStream(strFileName, FileMode.Create, FileAccess.Write)
' visit each Employee
For Each xnEmployee In xnlEmployees
' Within a Employee, get a list of its children
xnlChildren = xnEmployee.ChildNodes
' Visit each child node
For Each xnChild In xnlChildren
' If the child node is Bruce Beresford
If xnChild.InnerText = "831-419" Then
xnEmployee.RemoveChild(xnChild)
xdEmployees.Save(fsEmployee)
End If
Next
Next
End Using
End If
%>
</body>
</html>