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: &#20; &#10; &#13; and &#9.  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#.