9
XML Data Document
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main()
{
XmlDocument d = new XmlDocument();
XmlTextReader r = new XmlTextReader("books.xml");
r.WhitespaceHandling = WhitespaceHandling.None;
//r.MoveToContent();
d.Load(r);
d.Save(Console.Out);
}
}
books.xml
<?xml version='1.0'?>
<!-- This file represents a fragment of a book store inventory database -->
<bookstore>
<book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
Output
<?xml version="1.0"?>
<!-- This file represents a fragment of a book store inventory database -->
<bookstore>
..
The XmlDocument class represents
an XML document. The W3C has two standards, one called the Document Object
Model DOM Level 1, and the other called the Core DOM Level 2. The XmlDocument
class implements these standards. This class is derived from an abstract class
called XmlNode.
The XML Document is loaded into
memory as a tree structure, thereby facilitating the navigation within and the
editing of the document. The representation of the document in memory is known
as a DOM.
The XML file books.xml
represents a bookstore , which stores a large number of books. This file shall
not be displayed in future since it is pretty lengthy. This file is utilised by
most of the XML samples supplied by Microsoft.
The tag 'books' represents a
book, and has attributes such as, type of book, genre, the year of publication
or publication date etc; and finally, a unique number, ISBN, assigned to the
book. Each book has a title as well as an author. The attribute author contains
a few tags that disclose details such as, the first name and the last name of
the author. The price of the book is the last element. It is not imperative for
these elements of a book to be present in a specific order, i.e. price can come
before the title, and so on.
The object r of type
XmlTextReader class represents the XML file books.xml. As always, the
WhiteSpaceHandling is set to None. D is an object that looks like XmlDocument.
The Load function of this class can handle four overloads. One of the overloads
that the function can take is an XmlReader. As we are supplying an
XmlTextReader to this function, it eventually scales down to an XmlReader.
The Load function is responsible
for loading the XML file into the XmlDocument object. If the property
PreserveWhitespace is set to True, then and only then, are the Whitespace nodes
created. In this case, since we have set Whitespaces to None in the XML file,
no white space nodes can ever be created, regardless of property
PreserveWhitespace being set to True. The Load function cannot change the
Whitespace Handling present in the reader. The Load method does not perform any
validations. In case validations are imperative, the XmlValidatingReader class
must be utilised in place of the plain Jane XmlTextReader class. The same
argument holds good when entities have to be resolved.
The Save function writes the XML
document associated with the XmlDocument, either to disk or to the console. We
have displayed only a section of the document, since the entire books.xml shall
occupy space needlessly. We acquire the entire file because the ReadState is
set to Initial. This is so because the state has not been changed yet. Let us
now position the reader and see what happens.
We remove the comment marks
associated with MoveToContent, thereby, making it available. As a consequence,
both, the XmlDeclaration and the content are skipped, and the reader is
positioned at the first node 'Bookstore'. The output is as displayed below:
Output
<bookstore>
<book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
…
</bookstore>
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main()
{
XmlDocument d = new XmlDocument();
XmlTextReader r = new XmlTextReader("books.xml");
r.WhitespaceHandling = WhitespaceHandling.None;
r.MoveToContent();
r.Read();
r.Skip();
r.Skip();
d.Load(r);
d.Save(Console.Out);
}
}
Output
<book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
The Read function takes the
liberty to position itself at the book tag, the first Skip function skips over
the first book, and the second skip function skips over the second book. The
Load function of the XmlDocument now loads the node from the reader's current
position, i.e. from the third book onwards. Thus, the XmlDocument contains the
third book, which is about Philosophy, and not the other two books. The skip
function skips over nodes that are at the same level.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main()
{
XmlDocument d = new XmlDocument();
d.LoadXml("<aa bb='hi'> bad </aa>");
d.Save("d.xml");
}
}
d.xml
<aa bb="hi"> bad </aa>
There are different ways of associating
XML with an XmlDocument object. The XmlDocument class has a function called
LoadXml that converts a string representing XML into an XmlDocument object. The
Save function writes the contents to a file on disk named d.xml.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main()
{
XmlDocument d = new XmlDocument();
d.CreateElement("vijay");
d.Save("d.xml");
}
}
Output
Unhandled Exception: System.Xml.XmlException: This an invalid XML document. The document does not have a root element.
The CreateElement function, as
the name suggests, creates an element with the name passed as a parameter. We
encounter an impediment when we attempt to write it to disk. An exception is
thrown, since we have not added the element to the XmlDocument. Had we used the
Save overload that writes to Console.Out, no exceptions would have been thrown,
but neither would any output have been displayed on the screen.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main() {
XmlDocument d = new XmlDocument();
XmlElement e;
e = d.CreateElement("vijay");
d.AppendChild(e);
d.Save("d.xml");
}
}
d.xml
<vijay />
The CreateElement function
returns an XmlElement object, which is stored in e. This object is then passed
on to the AppendChild function, which creates a child node. Thus, when we write
the XmlDocument to disk, d.xml will display a single tag of 'vijay'.
We shall now examine a series of
programs, which shall create each and every type of node and shall write them
all to disk.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main()
{
XmlDocument d = new XmlDocument();
XmlElement e;
e = d.CreateElement("vijay");
XmlAttribute a = d.CreateAttribute("a1");
e.SetAttributeNode(a);
e.SetAttribute("a1", "howdy");
d.AppendChild(e);
d.Save("d.xml");
}
}
d.xml
<vijay a1="howdy" />
CreateElement creates an element
called 'vijay'. Thereafter, a function called CreateAttribute creates an
attribute called a1. This function returns an XmlAttribute object that is
associated with the element e, using the function SetAttributeNode, off the
XmlElement class. If we comment the line e.SetAttribute("a1",
"howdy"); we shall see the file
d.xml containing the following:
d.xml
<vijay a1="" />
The attribute gets created, but
it is devoid of any value at this stage. It is the SetAttribute function from
the XmlElement class that will assign the value to the attribute. Hence, it
accepts two parameters.
The first parameter is a1, which
is the name of the attribute, and the second parameter 'howdy' is the value of
the attribute.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main()
{
XmlDocument d = new XmlDocument();
XmlElement e;
e = d.CreateElement("vijay");
d.AppendChild(e);
XmlCDataSection c;
c = d.CreateCDataSection("sonal mukhi");
d.AppendChild(c);
d.Save("d.xml");
}
}
Output
Unhandled Exception: System.InvalidOperationException: The specified node cannot be inserted as the valid child of this node, because the specified node is the wrong type.
We first create an element
'vijay' by using the CreateElement function. Thereafter, using the Append Child
function, we add the element to the XmlDocument. No errors are generated upto
this point.
Now, we wish to add a CDATA
section to the file. To achieve this, the CreateCDataSection is used with a
string parameter 'sonal mukhi', which returns an XmlCDataSection object.
Employing the familiar AppendChild function, the section is added to the file.
Since an XML document cannot
have a CDATA section by itself, the above exception is generated.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main()
{
XmlDocument d = new XmlDocument();
XmlElement e;
e = d.CreateElement("vijay");
d.AppendChild(e);
XmlCDataSection c;
c = d.CreateCDataSection("sonal mukhi");
XmlElement r = d.DocumentElement;
r.AppendChild(c);
d.Save("d.xml");
}
}
d.xml
<vijay><![CDATA[sonal mukhi]]></vijay>
The error now disappears, as the
AppendChild function is called from the XmlElement class, and not from the
XmlDocument class.
The DocumentElement property
represents the root or the first element of theXMLdocument. The CDATA section
now gets added to the element 'vijay', since the root element is 'vijay'.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main() {
XmlDocument d = new XmlDocument();
d.LoadXml("<vijay> hi </vijay>");
XmlCDataSection c;
c = d.CreateCDataSection("sonal mukhi");
XmlElement r = d.DocumentElement;
r.AppendChild(c);
d.Save("d.xml");
}
}
d.xml
<vijay> hi <![CDATA[sonal mukhi]]></vijay>
An alternative approach would be
to use the trustworthy LoadXml function, in lieu of CreateElement. Any of the
two approaches may be employed to add a root node, thereby, displaying the
d.xml file. As we have been harping repeatedly, there are many ways to skin a
cat.
a.cs
using System.Xml;
public class Sample
{
public static void Main()
{
XmlDocument d = new XmlDocument();
d.LoadXml("<!DOCTYPE book > <book /> ");
XmlDocumentType t;
t = d.DocumentType;
System.Console.WriteLine(t.OuterXml);
System.Console.WriteLine(t.Name);
}
}
Output
<!DOCTYPE book[]>
book
This program demonstrates our
ability to access a specific node while processing an XML file.
The DocumentType property
returns an XmlDocumentType t, which represents the singular DOCTYPE node present
in an XML file. This object t has a large number of properties that facilitate
access to all the details regarding the node. In the program, only two
properties are displayed:
• The first property OuterXml represents the entire node as a string. Since no external DTD file is present, by default, the internal DTD, which does not have any contents, is displayed.
• The second property Name presents the name of the root node.
a.cs
using System;
using System.Xml;
public class Sample
{
public static void Main()
{
XmlDocument d = new XmlDocument();
d.LoadXml("<book> <title>None</title> <author>Me</author> </book>");
XmlNode r = d.FirstChild;
XmlNode n = r.FirstChild;
Console.WriteLine(r);
Console.WriteLine(n.OuterXml);
Console.WriteLine(r.OuterXml);
}
}
Output
System.Xml.XmlElement
<title>None</title>
<book><title>None</title><author>Me</author></book>
The FirstChild property of the
XmlDocument class or XmlNode class retrieves the first child of the current
node in the document i.e. XmlElement. The
value is stored in both r and n. It can be displayed using the WriteLine
function. The OuterXml property contains the tags, including the child nodes.
The FirstChild property of r is
an XmlNode, whose OuterXml is the first child node or tag title within the tag
'book'. If no child node exists, the value is null.
a.cs
using System;
using System.Xml;
public class Sample
{
public static void Main()
{
XmlDocument d = new XmlDocument();
d.LoadXml("<book> <title>None</title> <author>Me</author> </book>");
XmlNode r = d.LastChild;
XmlNode n = r.LastChild;
Console.WriteLine(r);
Console.WriteLine(n.OuterXml);
Console.WriteLine(r.OuterXml);
}
}
Output
System.Xml.XmlElement
<author>Me</author>
<book><title>None</title><author>Me</author></book>
Comparable to the FirstChild
property is the LastChild property, which merely returns the last child in the
node. Therefore, as the 'author' tag is the last tag, the LastChild property
returns a reference to 'Me'. Since title is the only tag in the file, the use
of FirstChild or LastChild achieves the same outcome, in this case.
a.cs
using System;
using System.Xml;
public class Sample
{
public static void Main()
{
XmlDocument d = new XmlDocument();
d.LoadXml("<aa><book> hi<title>None</title> </book> </aa>");
XmlDocument de = (XmlDocument) d.CloneNode(true);
Console.WriteLine(de.ChildNodes.Count);
for (int i=0; i<de.ChildNodes.Count; i++)
Console.WriteLine(de.ChildNodes[i].OuterXml);
Console.WriteLine(de.Name + de.OuterXml);
Console.WriteLine("Shallow");
XmlDocument sh = (XmlDocument) d.CloneNode(false);
Console.WriteLine(sh.ChildNodes.Count);
for (int i=0; i<sh.ChildNodes.Count; i++)
Console.WriteLine(sh.ChildNodes[i].InnerXml);
Console.WriteLine(sh.Name + sh.OuterXml);
}
}
Output
1
<aa><book> hi<title>None</title></book></aa>
#document<aa><book> hi<title>None</title></book></aa>
Shallow
0
#document
We start with an XML fragment
that has a root node aa, which has a child node of book, containing another child
node called title. The CloneNode function in XmlDocument takes a boolean
parameter, where True refers to cloning the nodes within the node aa, which
includes the nodes 'book' and 'title'. It behaves akin to a copy constructor
for nodes.
The cloned node does not have a
parent. Therefore, when we exploit the property ParentNode to ascertain the
value of the parent node, it returns a value of null. The ParentNode property
returns a handle to the Parent node of the node.
The return value of the CloneNode
function is an XmlNode class. As the XmlDocument derives from XmlNode, the
'cast' operator is used. The XmlNode class has a property called ChildNodes,
which returns an XmlNodeList object that refers to all the child nodes. This
object is of a Collection data type. The Count property in the collection can
be used to render a count of the number of entities present in the clone.
The Name property returns the
qualified name of #document and the OuterXml property provides the entire
element. This function at variance with the LocalName function, which returns
the name of an attribute, #cdata-section for the CDATA section, and so on.
Thus, with the help of this function, we can identify the different names for
different node types.
The CloneNode function is called
again, but with a value of false. Thus, a shallow node with no ChildNodes is
returned. This is confirmed using the count property, which shows a count of
zero. This proves that only the node has been cloned and not the content.
Using a 'for' statement, we
iterate through all the child nodes, and display the OuterXml property using
the indexer. The value returned is the content of the node, which includes text
such as 'hi'. If you read about the CloneNode function in the documentation, it
would apprise you of the impending eventuality, if an attempt is made to clone
nodes of different types.
a.cs
using System;
using System.IO;
using System.Xml;
public class Sample
{
public static void Main()
{
XmlDocument d = new XmlDocument();
d.LoadXml("<!DOCTYPE book [<!ENTITY bb 'vijay'>]> <book> <misc /> </book>");
XmlEntityReference e = d.CreateEntityReference("bb");
Console.WriteLine(e.ChildNodes.Count);
d.DocumentElement.LastChild.AppendChild(e);
Console.WriteLine(e.FirstChild.InnerText + ". " + e.ChildNodes.Count + " " + e.Name);
d.Save(Console.Out);
XmlEntityReference e1 = d.CreateEntityReference("bbb");
Console.WriteLine(e1.ChildNodes.Count);
d.DocumentElement.LastChild.AppendChild(e1);
Console.WriteLine(e1.FirstChild.InnerText + ". " + e1.ChildNodes.Count + " " + e1.Name);
d.Save(Console.Out);
}
}
Output
0
vijay. 1 bb
<!DOCTYPE book[<!ENTITY bb 'vijay'>]>
<book>
<misc>&bb;</misc>
</book>0
. 1 bbb
<!DOCTYPE book[<!ENTITY bb 'vijay'>]>
<book>
<misc>&bb;&bbb;</misc>
</book>
The LoadXml function has a
DOCTYPE declaration, and an entity reference called bb having a value of
'vijay'. Now, using the function CreateEntityReference, we create an entity
reference called bb. This function returns an XmlEntityReference object, which
is a class derived from XmlLinkedNode, which, in turn, is derived from XmlNode.
The number of child nodes is zero at this stage, because the node has not yet
been expanded.
The function AppendChild is then
used to append the child to the node, returned by the LastChild property.
Since the node has been appended
to the document, its parent node is set and the entity reference bb is expanded
to 'vijay'. Thus, the file has a child node that contains 'vijay', the entity
reference text. The InnerText property of the FirstChild gives the replacement
text. The Count of the child nodes is one, since we have added one entity, and
the Name property of the Entity Reference is the name bb, which we have
created.
Finally, the Save function,
which prints out the XML fragment, displays the entity reference bb, starting
with an ampersand symbol & and ending with a semi-colon, with the LastChild
node named misc.
We now add another entity
reference bbb, but lay it aside, undefined. The rules, which applied earlier to
the entity reference, are also relevant now. The only significant difference is
that the InnerText property does not have any value when the reference node is
expanded. Thus, the child is an empty text node. The entity refs of bb and bbb
are placed one after the other.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main() {
XmlDocument d = new XmlDocument();
d.LoadXml("<book></book>");
XmlNode n=d.CreateNode("element", "vijay", "");
n.InnerText = "hi";
XmlElement r = d.DocumentElement;
r.AppendChild(n);
//d.LastChild.AppendChild(n);
//d.AppendChild(n);
Console.WriteLine(d.OuterXml);
d.Save(Console.Out);
}
}
Output
<book><vijay>hi</vijay></book>
<book>
<vijay>hi</vijay>
</book>
The XML fragment shows the root
tag as 'book' because of the LoadXml function. The CreateNode function creates
a new node or element called 'vijay'. This function returns an object of type
XmlNode and accepts the following parameters:
The first parameter decides on the
type of node. Exactly 10 types of nodes can be created with this function:
element, attribute, text, cdatasection, entityreference, processinginstruction,
comment, document, documenttype and documentfragmnet. This parameter is case
sensitive.
The second parameter is the name
of the new node. If there is a colon in the name, it is parsed into a prefix
and a LocalName.
The third parameter refers to
the namespace URI. The InnerText property is another mechanism for adding
content between tags. The tag 'vijay' now embodies the word 'hi'. This node in
memory is added to the XML fragment with the help of the AppendChild function,
which is called off the XmlElement, returned by the DocumentElement property.
Calling AppendChild off the
XmlDocument class, throws an exception, since a DocumentElement node already
exists within the document. If we uncomment the line d.AppendChild(n), it will
result in the following exception:
Output
Unhandled Exception: System.InvalidOperationException: This document already has a DocumentElement node.
If we uncomment the line
d.LastChild.AppendChild(n), it would be similar to first gaining a handle to
the last child and then adding the node. In this case, whether the node is the
first child or the last child, it does not make any difference at all. The
documentation for the CreateNode function, offers a table that very distinctly
specifies as to which nodes can be placed within other nodes.
a.cs
using System;
using System.Xml;
public class zzz {
public static void Main()
{
XmlDocument d = new XmlDocument();
d.Load("b.xml");
XmlImplementation i;
i = d.Implementation;
XmlDocument d1 = i.CreateDocument();
d.Save(Console.Out);
d1.Save(Console.Out);
}
}
b.xml
<?xml version="1.0"?>
<!DOCTYPE vijay>
<vijay />
Output
<?xml version="1.0"?>
<!DOCTYPE vijay[]>
<vijay />
Every XmlDocument has an
XmlImplementation object associated with it, which can be accessed using the
Implementation property. XmlDocument objects created from the same
XmlImplementation, share the same name table. Thus, it is permissible to
compare attribute and element names as objects, instead of strings.
We create an empty XmlDocument d
by using the constructor as before, and thereafter, use the Load function to
associate anXMLfile named b.xml with the XmlDocument. Earlier we had used the
Reader object.
To create an XmlDocument object
that shares the same XmlNameTable, we use the function CreateDocument from the
XmlImplementation object. Then, the Save function is used to write out both the
XmlDocument objects to the Console. The first XmlDocument object d, displays a
replica of the file b.xml, while the second one is empty because we have not
associated any XML content with it.
Thus, the CreateDocument
function creates an empty XML document, but it does not copy any content to it.
It ensures that the names are shared, and not duplicated.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz
{
public static void Main()
{
XmlTextReader r = new XmlTextReader ("books.xml");
r.WhitespaceHandling = WhitespaceHandling.None;
XmlDocument d = new XmlDocument();
d.Load (r);
XmlNode n;
n = d.DocumentElement;
Console.WriteLine(n.Name + "<" + n.Value + ">");
n = n.FirstChild;
Console.WriteLine(n.Name + "<" + n.Value + ">");
while (n != null)
{
XmlNamedNodeMap m = n.Attributes;
foreach (XmlNode a in m)
Console.Write(" " + a.Name + "<" + a.Value + "> ");
n = n.NextSibling;
Console.WriteLine();
}
}
}
Output
bookstore<>
book<>
genre<autobiography> publicationdate<1981> ISBN<1-861003-11-0>
genre<novel> publicationdate<1967> ISBN<0-201-63361-2>
genre<philosophy> publicationdate<1991> ISBN<1-861001-57-6>
First, we start by loading the
XML file books.xml, and then, positioning the DocumentElement at the root tag
bookstore. Then, using the FirstChild property, we make the first child node
'book' as the active node and display it. As we have no clue about the number
of child book nodes that are present in the file, we use a while loop that
repeats itself until the XmlNode object n returns a null.
The Attributes property returns
an XmlNamedNodeMap object that represents a collection of nodes. These nodes
can be represented by a name or an index. So, using the foreach loop, we fetch
one attribute at a time in an XmlNode object and display the Name and the Value
contained in it. The <> signs are used as a talisman.
Once this is accomplished, we
move to the next book at the same level. Tags at the same level are called
siblings. The property NextSibling moves to the next book or tag at the same level,
thereby, displaying one book tag after another.
a.cs
using System;
using System.Xml;
public class Sample
{
public static void Main()
{
XmlTextReader r = new XmlTextReader ("books.xml");
r.WhitespaceHandling = WhitespaceHandling.None;
XmlDocument d = new XmlDocument();
d.Load (r);
XmlNode n = d.DocumentElement;
Console.WriteLine(n.Name);
XmlNode b = n.LastChild;
Console.WriteLine(b.Name);
Console.WriteLine(b.OuterXml + "\n");
b = n.LastChild.PreviousSibling;
Console.WriteLine(b.OuterXml);
}
}
Output
bookstore
book
<book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6"><title>The Gorgias</title><author><name>Plato </name></author><price>9.99</price></book>
In the previous example, we
first displayed the root node bookstore, followed by the LastChild and not the
FirstChild node. Both are expected to return the same name, since the first and
last child tags refer to the same node book. The XML associated with this node
was displayed using the OuterXml function, which displayed the last book, which
deals with Philosophy. You may recollect that the OuterXml function displays
the child tags also.
In this example, we proceed
backwards. Hence, we use the PreviousSibling function to display the second
last book. Thus, we can either proceed in the forward direction, like we did in
the last example, or in the backward direction, as shown in the current
example.
a.cs
using System;
using System.IO;
using System.Xml;
public class Sample
{
public static void Main()
{
XmlDocument d = new XmlDocument();
d.LoadXml("<book> hi </book>");
XmlComment c;
c = d.CreateComment("Comment 1");
XmlElement r = d.DocumentElement;
d.InsertBefore(c, r);
d.Save(Console.Out);
Console.WriteLine("\n---");
XmlComment c1;
c1 = d.CreateComment("Comment 2");
d.InsertAfter(c1, r);
d.Save(Console.Out);
}
}
Output
<!--Comment 1-->
<book> hi </book>
---
<!--Comment 1-->
<book> hi </book>
<!--Comment 2-->
LoadXml creates a node called book,
which encompasses 'hi'. Thereafter, a Comment object is created by calling the
CreateComment function. The function merely requires the string to be displayed
as a comment. The extra comment characters are placed by the function in the
XML file.
The next dilemma is with regard
to the position of the comment i.e. should the comment be placed before or
after the node book. The InsertBefore function inserts the required node. It
takes two parameters, i.e. a comment, followed by the node before which the
comment is to be inserted. As we want it to be inserted before the book node,
we use the handle returned by DocumentElement property, which contains the
handle to the book node. The Save function then displays the comment before the
book node.
The InsertAfter function inserts
the comment node after the reference node, which has been passed as the second
parameter. Thus, the second comment comes after the book node.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz {
public static void Main()
{
XmlDocument d = new XmlDocument();
d.LoadXml("<?xml version='1.0' ?><book> <title>Vijay</title> </book>");
XmlNode n = d.DocumentElement;
n.RemoveChild(n.FirstChild);
d.Save(Console.Out);
d.RemoveAll();
Console.WriteLine("\n=========");
d.Save(Console.Out);
}
}
Output
<?xml version="1.0"?>
<book>
</book>
=========
The XML fragment that is loaded
using the LoadXml function has an XML Declaration, which is a tag book,
containing an element of title enclosing 'Vijay'.
The DocumentElement property
returns a handle to the node book, which is stored in n. Then, the RemoveChild
function of node n is called with a single parameter, which is the node title,
since the FirstChild returns this value. This function removes the child from
the tag.
Saving to the Console displays
the remaining XML fragment. Thus, we can see the XML declaration and the tag
book, but without any content, since the tag title has been removed.
The next function that is
implemented is, RemoveAll from the XmlDocument class. On displaying the XML
file, we witness no output since the RemoveAll function erases everything from
the Document.
a.cs
using System;
using System.IO;
using System.Xml;
public class zzz {
public static void Main()
{
XmlNode n;
XmlDocument d = new XmlDocument();
d.LoadXml("<zz xml:space=\"preserve\"><aa>Vijay</aa><bb>Mukhi</bb></zz>");
Console.WriteLine(d.DocumentElement.InnerText);
n=d.DocumentElement;
XmlSignificantWhitespace s=d.CreateSignificantWhitespace(" ");
d.Save(Console.Out);
Console.WriteLine();
n.InsertAfter(s, n.FirstChild);
Console.WriteLine(d.DocumentElement.InnerText);
d.Save(Console.Out);
}
}
Output
VijayMukhi
<zz xml:space="preserve">
<aa>Vijay</aa>
<bb>Mukhi</bb>
</zz>
Vijay Mukhi
<zz xml:space="preserve">
<aa>Vijay</aa> <bb>Mukhi</bb></zz>
The DocumentElement property
returns a handle to the zz tag, whereas, the InnerText property in the
DocumentElement, refers to the Text present within the tags aa and bb. Thus, we
see 'VijayMukhi' displayed without any spaces displayed between the two words.
We also create significant
whitespace, using the function CreateSignificantWhitespace, after initializing
the node n to tag zz. This function accepts only one string parameter, which
could be any one of the following four:  and
	. It does not augment
theXMLfragment. Finally, we write the XML fragment using the Save function. The
attribute space=preserve is visible. This attribute is optional.
Using the InsertAfter function,
we add significant whitespace after the FirstChild node. Thus, we see
significant space between the nodes aa and bb. The InnerText also displays the
spaces between the words 'Vijay' and ' Mukhi'.
Output
VijayMukhi
<zz xml:space="preserve">
<aa>Vijay</aa>
<bb>Mukhi</bb>
</zz>
VijayMukhi
<zz xml:space="preserve"> <aa>Vijay</aa><bb>Mukhi</bb></zz>
The above output is obtained on
adding the significant space before the first child, using the InsertBefore
function, in lieu of the InsertAfter function. The spaces are inserted before
the FirstChild aa, i.e. before the text 'Vijay' and not after.
a.cs
using System;
using System.Collections;
using System.Xml;
public class zzz
{
public static void Main()
{
XmlDocument d = new XmlDocument();
d.Load("books.xml");
XmlNode n = d.DocumentElement;
IEnumerator i = n.GetEnumerator();
XmlNode b;
while (i.MoveNext())
{
b = (XmlNode)i.Current;
Console.WriteLine(b.OuterXml);
}
}
}
Output
<book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0"><title>The Autobiography of Benjamin Franklin</title><author><first-name>Benjamin</first-name><last-name> Franklin</last-name></author><price>8.99</price></book>
<book genre="novel" publicationdate="1967" ISBN="0-201-63361-2"><title>The Confidence Man</title><author><first-name> Herman</first-name><last-name>Melville</last-name></author> <price>11.99</price></book><book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6"><title>The
Gorgias</title><author><name>Plato</name></author><price> 9.99</price></book>
The last example in the series,
displays various parts of an XML file in a different manner.
Every XML node object has a
function called GetEnumerator, which returns an IEnumerator interface object.
This interface has a MoveNext function that moves from one node to the next. In
our program, we move from one book to another, since the XmlNode is on a tag
book.
The Current property accesses
the current book node, since it happens to be the first one. Then, we use the OuterXml
property to display the entire contents of this node.
The MoveNext function then activates the next node. If no more nodes exist, it returns False, or else it returns True. In this manner, we can iterate through all the nodes. The foreach instruction has a similar functionality. Whenever we want to navigate through a collection, the IEnumerator interface is used. This is the conventional way of moving sequentially through a list of objects or a collection in C#.