1 
2 // System.Xml.XmlDocumentTests
3 //
4 // Authors:
5 //   Jason Diamond <jason@injektilo.org>
6 //   Kral Ferch <kral_ferch@hotmail.com>
7 //   Martin Willemoes Hansen <mwh@sysrq.dk>
8 //
9 // (C) 2002 Jason Diamond, Kral Ferch
10 // (C) 2003 Martin Willemoes Hansen
11 //
12 
13 using System;
14 using System.Collections;
15 using System.Xml;
16 using System.IO;
17 using System.Text;
18 
19 using NUnit.Framework;
20 
21 using InvalidNodeTypeArgException = System.ArgumentException;
22 
23 namespace MonoTests.System.Xml
24 {
25 	[TestFixture]
26 	public class XmlDocumentTests
27 	{
28 		private XmlDocument document;
29 		private ArrayList eventStrings = new ArrayList();
30 
31 		// These Event* methods support the TestEventNode* Tests in this file.
32 		// Most of them are event handlers for the XmlNodeChangedEventHandler
33 		// delegate.
EventStringAdd(string eventName, XmlNodeChangedEventArgs e)34 		private void EventStringAdd(string eventName, XmlNodeChangedEventArgs e)
35 		{
36 			string oldParent = (e.OldParent != null) ? e.OldParent.Name : "<none>";
37 			string newParent = (e.NewParent != null) ? e.NewParent.Name : "<none>";
38 			eventStrings.Add (String.Format ("{0}, {1}, {2}, {3}, {4}", eventName, e.Action.ToString (), e.Node.OuterXml, oldParent, newParent));
39 		}
40 
EventNodeChanged(Object sender, XmlNodeChangedEventArgs e)41 		private void EventNodeChanged(Object sender, XmlNodeChangedEventArgs e)
42 		{
43 			EventStringAdd ("NodeChanged", e);
44 		}
45 
EventNodeChanging(Object sender, XmlNodeChangedEventArgs e)46 		private void EventNodeChanging (Object sender, XmlNodeChangedEventArgs e)
47 		{
48 			EventStringAdd ("NodeChanging", e);
49 		}
50 
EventNodeChangingException(Object sender, XmlNodeChangedEventArgs e)51 		private void EventNodeChangingException (Object sender, XmlNodeChangedEventArgs e)
52 		{
53 			throw new Exception ("don't change the value.");
54 		}
55 
EventNodeInserted(Object sender, XmlNodeChangedEventArgs e)56 		private void EventNodeInserted(Object sender, XmlNodeChangedEventArgs e)
57 		{
58 			EventStringAdd ("NodeInserted", e);
59 		}
60 
EventNodeInserting(Object sender, XmlNodeChangedEventArgs e)61 		private void EventNodeInserting(Object sender, XmlNodeChangedEventArgs e)
62 		{
63 			EventStringAdd ("NodeInserting", e);
64 		}
65 
EventNodeInsertingException(Object sender, XmlNodeChangedEventArgs e)66 		private void EventNodeInsertingException(Object sender, XmlNodeChangedEventArgs e)
67 		{
68 			throw new Exception ("don't insert the element.");
69 		}
70 
EventNodeRemoved(Object sender, XmlNodeChangedEventArgs e)71 		private void EventNodeRemoved(Object sender, XmlNodeChangedEventArgs e)
72 		{
73 			EventStringAdd ("NodeRemoved", e);
74 		}
75 
EventNodeRemoving(Object sender, XmlNodeChangedEventArgs e)76 		private void EventNodeRemoving(Object sender, XmlNodeChangedEventArgs e)
77 		{
78 			EventStringAdd ("NodeRemoving", e);
79 		}
80 
EventNodeRemovingException(Object sender, XmlNodeChangedEventArgs e)81 		private void EventNodeRemovingException(Object sender, XmlNodeChangedEventArgs e)
82 		{
83 			throw new Exception ("don't remove the element.");
84 		}
85 
86 		[SetUp]
GetReady()87 		public void GetReady ()
88 		{
89 			document = new XmlDocument ();
90 			document.PreserveWhitespace = true;
91 		}
92 
93 		[Test]
CreateNodeNodeTypeNameEmptyParams()94 		public void CreateNodeNodeTypeNameEmptyParams ()
95 		{
96 			try {
97 				document.CreateNode (null, null, null);
98 				Assert.Fail ("Expected an ArgumentException to be thrown.");
99 			} catch (ArgumentException) {}
100 
101 			try {
102 				document.CreateNode ("attribute", null, null);
103 				Assert.Fail ("Expected a NullReferenceException to be thrown.");
104 			} catch (NullReferenceException) {}
105 
106 			try {
107 				document.CreateNode ("attribute", "", null);
108 				Assert.Fail ("Expected an ArgumentException to be thrown.");
109 			} catch (ArgumentException) {}
110 
111 			try {
112 				document.CreateNode ("element", null, null);
113 				Assert.Fail ("Expected a NullReferenceException to be thrown.");
114 			} catch (NullReferenceException) {}
115 
116 			try {
117 				document.CreateNode ("element", "", null);
118 				Assert.Fail ("Expected an ArgumentException to be thrown.");
119 			} catch (ArgumentException) {}
120 
121 			try {
122 				document.CreateNode ("entityreference", null, null);
123 				Assert.Fail ("Expected a NullReferenceException to be thrown.");
124 			} catch (NullReferenceException) {}
125 		}
126 
127 		[Test]
CreateNodeInvalidXmlNodeType()128 		public void CreateNodeInvalidXmlNodeType ()
129 		{
130 			XmlNode node;
131 
132 			try {
133 				node = document.CreateNode (XmlNodeType.EndElement, null, null);
134 				Assert.Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
135 			} catch (InvalidNodeTypeArgException) {}
136 
137 			try {
138 				node = document.CreateNode (XmlNodeType.EndEntity, null, null);
139 				Assert.Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
140 			} catch (InvalidNodeTypeArgException) {}
141 
142 			try {
143 				node = document.CreateNode (XmlNodeType.Entity, null, null);
144 				Assert.Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
145 			} catch (InvalidNodeTypeArgException) {}
146 
147 			try {
148 				node = document.CreateNode (XmlNodeType.None, null, null);
149 				Assert.Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
150 			} catch (InvalidNodeTypeArgException) {}
151 
152 			try {
153 				node = document.CreateNode (XmlNodeType.Notation, null, null);
154 				Assert.Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
155 			} catch (InvalidNodeTypeArgException) {}
156 
157 			// TODO:  undocumented allowable type.
158 			node = document.CreateNode (XmlNodeType.XmlDeclaration, null, null);
159 			Assert.AreEqual (XmlNodeType.XmlDeclaration, node.NodeType);
160 		}
161 
162 		[Test]
CreateNodeWhichParamIsUsed()163 		public void CreateNodeWhichParamIsUsed ()
164 		{
165 			XmlNode node;
166 
167 			// No constructor params for Document, DocumentFragment.
168 
169 			node = document.CreateNode (XmlNodeType.CDATA, "a", "b", "c");
170 			Assert.AreEqual (String.Empty, ((XmlCDataSection)node).Value);
171 
172 			node = document.CreateNode (XmlNodeType.Comment, "a", "b", "c");
173 			Assert.AreEqual (String.Empty, ((XmlComment)node).Value);
174 
175 			node = document.CreateNode (XmlNodeType.DocumentType, "a", "b", "c");
176 			Assert.IsNull (((XmlDocumentType)node).Value);
177 
178 // TODO: add this back in to test when it's implemented.
179 //			node = document.CreateNode (XmlNodeType.EntityReference, "a", "b", "c");
180 //			Assert.IsNull (((XmlEntityReference)node).Value);
181 
182 // TODO: add this back in to test when it's implemented.
183 //			node = document.CreateNode (XmlNodeType.ProcessingInstruction, "a", "b", "c");
184 //			Assert.AreEqual (String.Empty, ((XmlProcessingInstruction)node).Value);
185 
186 			node = document.CreateNode (XmlNodeType.SignificantWhitespace, "a", "b", "c");
187 			Assert.AreEqual (String.Empty, ((XmlSignificantWhitespace)node).Value);
188 
189 			node = document.CreateNode (XmlNodeType.Text, "a", "b", "c");
190 			Assert.AreEqual (String.Empty, ((XmlText)node).Value);
191 
192 			node = document.CreateNode (XmlNodeType.Whitespace, "a", "b", "c");
193 			Assert.AreEqual (String.Empty, ((XmlWhitespace)node).Value);
194 
195 			node = document.CreateNode (XmlNodeType.XmlDeclaration, "a", "b", "c");
196 			Assert.AreEqual ("version=\"1.0\"", ((XmlDeclaration)node).Value);
197 		}
198 
199 		[Test]
200 		[Category ("NotDotNet")] // enbug in 2.0
CreateNodeNodeTypeName()201 		public void CreateNodeNodeTypeName ()
202 		{
203 			XmlNode node;
204 
205 			try {
206 				node = document.CreateNode ("foo", null, null);
207 				Assert.Fail ("Expected an ArgumentException to be thrown.");
208 			} catch (ArgumentException) {}
209 
210 			// .NET 2.0 fails here.
211 			node = document.CreateNode("attribute", "foo", null);
212 			Assert.AreEqual (XmlNodeType.Attribute, node.NodeType);
213 
214 			node = document.CreateNode("cdatasection", null, null);
215 			Assert.AreEqual (XmlNodeType.CDATA, node.NodeType);
216 
217 			node = document.CreateNode("comment", null, null);
218 			Assert.AreEqual (XmlNodeType.Comment, node.NodeType);
219 
220 			node = document.CreateNode("document", null, null);
221 			Assert.AreEqual (XmlNodeType.Document, node.NodeType);
222 			// TODO: test which constructor this ended up calling,
223 			// i.e. reuse underlying NameTable or not?
224 
225 			node = document.CreateNode("documentfragment", null, null);
226 			Assert.AreEqual (XmlNodeType.DocumentFragment, node.NodeType);
227 
228 			try {
229 				node = document.CreateNode("documenttype", null, null);
230 				Assert.Fail ("Expected an ArgumentNullException to be thrown.");
231 			} catch (ArgumentNullException) {}
232 
233 			node = document.CreateNode("element", "foo", null);
234 			Assert.AreEqual (XmlNodeType.Element, node.NodeType);
235 
236 // TODO: add this back in to test when it's implemented.
237 // ---> It is implemented, but it is LAMESPEC that allows null entity reference name.
238 //			node = document.CreateNode("entityreference", "foo", null);
239 //			Assert.AreEqual (XmlNodeType.EntityReference, node.NodeType);
240 
241 // LAMESPEC: null PI name is silly.
242 //			node = document.CreateNode("processinginstruction", null, null);
243 //			Assert.AreEqual (XmlNodeType.ProcessingInstruction, node.NodeType);
244 
245 			node = document.CreateNode("significantwhitespace", null, null);
246 			Assert.AreEqual (XmlNodeType.SignificantWhitespace, node.NodeType);
247 
248 			node = document.CreateNode("text", null, null);
249 			Assert.AreEqual (XmlNodeType.Text, node.NodeType);
250 
251 			node = document.CreateNode("whitespace", null, null);
252 			Assert.AreEqual (XmlNodeType.Whitespace, node.NodeType);
253 		}
254 
255 		[Test]
DocumentElement()256 		public void DocumentElement ()
257 		{
258 			Assert.IsNull (document.DocumentElement);
259 			XmlElement element = document.CreateElement ("foo", "bar", "http://foo/");
260 			Assert.IsNotNull (element);
261 
262 			Assert.AreEqual ("foo", element.Prefix);
263 			Assert.AreEqual ("bar", element.LocalName);
264 			Assert.AreEqual ("http://foo/", element.NamespaceURI);
265 
266 			Assert.AreEqual ("foo:bar", element.Name);
267 
268 			Assert.AreSame (element, document.AppendChild (element));
269 
270 			Assert.AreSame (element, document.DocumentElement);
271 		}
272 
273 		[Test]
DocumentEmpty()274 		public void DocumentEmpty()
275 		{
276 			Assert.AreEqual ("", document.OuterXml, "Incorrect output for empty document.");
277 		}
278 
279 		[Test]
EventNodeChanged()280 		public void EventNodeChanged()
281 		{
282 			XmlElement element;
283 			XmlComment comment;
284 
285 			document.NodeChanged += new XmlNodeChangedEventHandler (this.EventNodeChanged);
286 
287 			// Node that is part of the document.
288 			document.AppendChild (document.CreateElement ("foo"));
289 			comment = document.CreateComment ("bar");
290 			document.DocumentElement.AppendChild (comment);
291 			Assert.AreEqual ("<!--bar-->", document.DocumentElement.InnerXml);
292 			comment.Value = "baz";
293 			Assert.IsTrue (eventStrings.Contains ("NodeChanged, Change, <!--baz-->, foo, foo"));
294 			Assert.AreEqual ("<!--baz-->", document.DocumentElement.InnerXml);
295 
296 			// Node that isn't part of the document but created by the document.
297 			element = document.CreateElement ("foo");
298 			comment = document.CreateComment ("bar");
299 			element.AppendChild (comment);
300 			Assert.AreEqual ("<!--bar-->", element.InnerXml);
301 			comment.Value = "baz";
302 			Assert.IsTrue (eventStrings.Contains ("NodeChanged, Change, <!--baz-->, foo, foo"));
303 			Assert.AreEqual ("<!--baz-->", element.InnerXml);
304 
305 /*
306  TODO:  Insert this when XmlNode.InnerText() and XmlNode.InnerXml() have been implemented.
307 
308 			// Node that is part of the document.
309 			element = document.CreateElement ("foo");
310 			element.InnerText = "bar";
311 			document.AppendChild(element);
312 			element.InnerText = "baz";
313 			Assert.IsTrue (eventStrings.Contains("NodeChanged, Change, baz, foo, foo"));
314 
315 			// Node that isn't part of the document but created by the document.
316 			element = document.CreateElement("qux");
317 			element.InnerText = "quux";
318 			element.InnerText = "quuux";
319 			Assert.IsTrue (eventStrings.Contains("NodeChanged, Change, quuux, qux, qux"));
320 */
321 		}
322 
323 		[Test]
EventNodeChanging()324 		public void EventNodeChanging()
325 		{
326 			XmlElement element;
327 			XmlComment comment;
328 
329 			document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChanging);
330 
331 			// Node that is part of the document.
332 			document.AppendChild (document.CreateElement ("foo"));
333 			comment = document.CreateComment ("bar");
334 			document.DocumentElement.AppendChild (comment);
335 			Assert.AreEqual ("<!--bar-->", document.DocumentElement.InnerXml);
336 			comment.Value = "baz";
337 			Assert.IsTrue (eventStrings.Contains ("NodeChanging, Change, <!--bar-->, foo, foo"));
338 			Assert.AreEqual ("<!--baz-->", document.DocumentElement.InnerXml);
339 
340 			// Node that isn't part of the document but created by the document.
341 			element = document.CreateElement ("foo");
342 			comment = document.CreateComment ("bar");
343 			element.AppendChild (comment);
344 			Assert.AreEqual ("<!--bar-->", element.InnerXml);
345 			comment.Value = "baz";
346 			Assert.IsTrue (eventStrings.Contains ("NodeChanging, Change, <!--bar-->, foo, foo"));
347 			Assert.AreEqual ("<!--baz-->", element.InnerXml);
348 
349 			// If an exception is thrown the Document returns to original state.
350 			document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChangingException);
351 			element = document.CreateElement("foo");
352 			comment = document.CreateComment ("bar");
353 			element.AppendChild (comment);
354 			Assert.AreEqual ("<!--bar-->", element.InnerXml);
355 			try
356 			{
357 				comment.Value = "baz";
358 				Assert.Fail ("Expected an exception to be thrown by the NodeChanging event handler method EventNodeChangingException().");
359 			} catch (Exception) {}
360 			Assert.AreEqual ("<!--bar-->", element.InnerXml);
361 
362 			// Yes it's a bit anal but this tests whether the node changing event exception fires before the
363 			// ArgumentOutOfRangeException.  Turns out it does so that means our implementation needs to raise
364 			// the node changing event before doing any work.
365 			try
366 			{
367 				comment.ReplaceData(-1, 0, "qux");
368 				Assert.Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
369 			}
370 			catch (Exception) {}
371 
372 			/*
373  TODO:  Insert this when XmlNode.InnerText() and XmlNode.InnerXml() have been implemented.
374 
375 			// Node that is part of the document.
376 			element = document.CreateElement ("foo");
377 			element.InnerText = "bar";
378 			document.AppendChild(element);
379 			element.InnerText = "baz";
380 			Assert.IsTrue (eventStrings.Contains("NodeChanging, Change, bar, foo, foo"));
381 
382 			// Node that isn't part of the document but created by the document.
383 			element = document.CreateElement("foo");
384 			element.InnerText = "bar";
385 			element.InnerText = "baz";
386 			Assert.IsTrue (eventStrings.Contains("NodeChanging, Change, bar, foo, foo"));
387 
388 			// If an exception is thrown the Document returns to original state.
389 			document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChangingException);
390 			element = document.CreateElement("foo");
391 			element.InnerText = "bar";
392 			try {
393 				element.InnerText = "baz";
394 				Assert.Fail ("Expected an exception to be thrown by the NodeChanging event handler method EventNodeChangingException().");
395 			} catch (Exception) {}
396 			Assert.AreEqual ("bar", element.InnerText);
397 */
398 		}
399 
400 		[Test]
EventNodeInserted()401 		public void EventNodeInserted()
402 		{
403 			XmlElement element;
404 
405 			document.NodeInserted += new XmlNodeChangedEventHandler (this.EventNodeInserted);
406 
407 			// Inserted 'foo' element to the document.
408 			element = document.CreateElement ("foo");
409 			document.AppendChild (element);
410 			Assert.IsTrue (eventStrings.Contains ("NodeInserted, Insert, <foo />, <none>, #document"));
411 
412 			// Append child on node in document
413 			element = document.CreateElement ("foo");
414 			document.DocumentElement.AppendChild (element);
415 			Assert.IsTrue (eventStrings.Contains ("NodeInserted, Insert, <foo />, <none>, foo"));
416 
417 			// Append child on node not in document but created by document
418 			element = document.CreateElement ("bar");
419 			element.AppendChild(document.CreateElement ("bar"));
420 			Assert.IsTrue (eventStrings.Contains("NodeInserted, Insert, <bar />, <none>, bar"));
421 		}
422 
423 		[Test]
EventNodeInserting()424 		public void EventNodeInserting()
425 		{
426 			XmlElement element;
427 
428 			document.NodeInserting += new XmlNodeChangedEventHandler (this.EventNodeInserting);
429 
430 			// Inserting 'foo' element to the document.
431 			element = document.CreateElement ("foo");
432 			document.AppendChild (element);
433 			Assert.IsTrue (eventStrings.Contains ("NodeInserting, Insert, <foo />, <none>, #document"));
434 
435 			// Append child on node in document
436 			element = document.CreateElement ("foo");
437 			document.DocumentElement.AppendChild (element);
438 			Assert.IsTrue (eventStrings.Contains ("NodeInserting, Insert, <foo />, <none>, foo"));
439 
440 			// Append child on node not in document but created by document
441 			element = document.CreateElement ("bar");
442 			Assert.AreEqual (0, element.ChildNodes.Count);
443 			element.AppendChild (document.CreateElement ("bar"));
444 			Assert.IsTrue (eventStrings.Contains ("NodeInserting, Insert, <bar />, <none>, bar"));
445 			Assert.AreEqual (1, element.ChildNodes.Count);
446 
447 			// If an exception is thrown the Document returns to original state.
448 			document.NodeInserting += new XmlNodeChangedEventHandler (this.EventNodeInsertingException);
449 			Assert.AreEqual (1, element.ChildNodes.Count);
450 			try
451 			{
452 				element.AppendChild (document.CreateElement("baz"));
453 				Assert.Fail ("Expected an exception to be thrown by the NodeInserting event handler method EventNodeInsertingException().");
454 			}
455 			catch (Exception) {}
456 			Assert.AreEqual (1, element.ChildNodes.Count);
457 		}
458 
459 		[Test]
EventNodeRemoved()460 		public void EventNodeRemoved()
461 		{
462 			XmlElement element;
463 			XmlElement element2;
464 
465 			document.NodeRemoved += new XmlNodeChangedEventHandler (this.EventNodeRemoved);
466 
467 			// Removed 'bar' element from 'foo' outside document.
468 			element = document.CreateElement ("foo");
469 			element2 = document.CreateElement ("bar");
470 			element.AppendChild (element2);
471 			Assert.AreEqual (1, element.ChildNodes.Count);
472 			element.RemoveChild (element2);
473 			Assert.IsTrue (eventStrings.Contains ("NodeRemoved, Remove, <bar />, foo, <none>"));
474 			Assert.AreEqual (0, element.ChildNodes.Count);
475 
476 /*
477  * TODO:  put this test back in when AttributeCollection.RemoveAll() is implemented.
478 
479 			// RemoveAll.
480 			element = document.CreateElement ("foo");
481 			element2 = document.CreateElement ("bar");
482 			element.AppendChild(element2);
483 			Assert.AreEqual (1, element.ChildNodes.Count);
484 			element.RemoveAll();
485 			Assert.IsTrue (eventStrings.Contains ("NodeRemoved, Remove, <bar />, foo, <none>"));
486 			Assert.AreEqual (0, element.ChildNodes.Count);
487 */
488 
489 			// Removed 'bar' element from 'foo' inside document.
490 			element = document.CreateElement ("foo");
491 			document.AppendChild (element);
492 			element = document.CreateElement ("bar");
493 			document.DocumentElement.AppendChild (element);
494 			Assert.AreEqual (1, document.DocumentElement.ChildNodes.Count);
495 			document.DocumentElement.RemoveChild (element);
496 			Assert.IsTrue (eventStrings.Contains ("NodeRemoved, Remove, <bar />, foo, <none>"));
497 			Assert.AreEqual (0, document.DocumentElement.ChildNodes.Count);
498 		}
499 
500 		[Test]
EventNodeRemoving()501 		public void EventNodeRemoving()
502 		{
503 			XmlElement element;
504 			XmlElement element2;
505 
506 			document.NodeRemoving += new XmlNodeChangedEventHandler (this.EventNodeRemoving);
507 
508 			// Removing 'bar' element from 'foo' outside document.
509 			element = document.CreateElement ("foo");
510 			element2 = document.CreateElement ("bar");
511 			element.AppendChild (element2);
512 			Assert.AreEqual (1, element.ChildNodes.Count);
513 			element.RemoveChild (element2);
514 			Assert.IsTrue (eventStrings.Contains ("NodeRemoving, Remove, <bar />, foo, <none>"));
515 			Assert.AreEqual (0, element.ChildNodes.Count);
516 
517 /*
518  * TODO:  put this test back in when AttributeCollection.RemoveAll() is implemented.
519 
520 			// RemoveAll.
521 			element = document.CreateElement ("foo");
522 			element2 = document.CreateElement ("bar");
523 			element.AppendChild(element2);
524 			Assert.AreEqual (1, element.ChildNodes.Count);
525 			element.RemoveAll();
526 			Assert.IsTrue (eventStrings.Contains ("NodeRemoving, Remove, <bar />, foo, <none>"));
527 			Assert.AreEqual (0, element.ChildNodes.Count);
528 */
529 
530 			// Removing 'bar' element from 'foo' inside document.
531 			element = document.CreateElement ("foo");
532 			document.AppendChild (element);
533 			element = document.CreateElement ("bar");
534 			document.DocumentElement.AppendChild (element);
535 			Assert.AreEqual (1, document.DocumentElement.ChildNodes.Count);
536 			document.DocumentElement.RemoveChild (element);
537 			Assert.IsTrue (eventStrings.Contains ("NodeRemoving, Remove, <bar />, foo, <none>"));
538 			Assert.AreEqual (0, document.DocumentElement.ChildNodes.Count);
539 
540 			// If an exception is thrown the Document returns to original state.
541 			document.NodeRemoving += new XmlNodeChangedEventHandler (this.EventNodeRemovingException);
542 			element.AppendChild (element2);
543 			Assert.AreEqual (1, element.ChildNodes.Count);
544 			try
545 			{
546 				element.RemoveChild(element2);
547 				Assert.Fail ("Expected an exception to be thrown by the NodeRemoving event handler method EventNodeRemovingException().");
548 			}
549 			catch (Exception) {}
550 			Assert.AreEqual (1, element.ChildNodes.Count);
551 		}
552 
553 		[Test]
GetElementsByTagNameNoNameSpace()554 		public void GetElementsByTagNameNoNameSpace ()
555 		{
556 			string xml = @"<library><book><title>XML Fun</title><author>John Doe</author>
557 				<price>34.95</price></book><book><title>Bear and the Dragon</title>
558 				<author>Tom Clancy</author><price>6.95</price></book><book>
559 				<title>Bourne Identity</title><author>Robert Ludlum</author>
560 				<price>9.95</price></book><Fluffer><Nutter><book>
561 				<title>Bourne Ultimatum</title><author>Robert Ludlum</author>
562 				<price>9.95</price></book></Nutter></Fluffer></library>";
563 
564 			MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml));
565 			document = new XmlDocument ();
566 			document.Load (memoryStream);
567 			XmlNodeList bookList = document.GetElementsByTagName ("book");
568 			Assert.AreEqual (4, bookList.Count, "GetElementsByTagName (string) returned incorrect count.");
569 		}
570 
571 		[Test]
GetElementsByTagNameUsingNameSpace()572 		public void GetElementsByTagNameUsingNameSpace ()
573 		{
574 			StringBuilder xml = new StringBuilder ();
575 			xml.Append ("<?xml version=\"1.0\" ?><library xmlns:North=\"http://www.foo.com\" ");
576 			xml.Append ("xmlns:South=\"http://www.goo.com\"><North:book type=\"non-fiction\"> ");
577 			xml.Append ("<North:title type=\"intro\">XML Fun</North:title> " );
578 			xml.Append ("<North:author>John Doe</North:author> " );
579 			xml.Append ("<North:price>34.95</North:price></North:book> " );
580 			xml.Append ("<South:book type=\"fiction\"> " );
581 			xml.Append ("<South:title>Bear and the Dragon</South:title> " );
582 			xml.Append ("<South:author>Tom Clancy</South:author> " );
583                         xml.Append ("<South:price>6.95</South:price></South:book> " );
584 			xml.Append ("<South:book type=\"fiction\"><South:title>Bourne Identity</South:title> " );
585 			xml.Append ("<South:author>Robert Ludlum</South:author> " );
586 			xml.Append ("<South:price>9.95</South:price></South:book></library>");
587 
588 			MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml.ToString ()));
589 			document = new XmlDocument ();
590 			document.Load (memoryStream);
591 			XmlNodeList bookList = document.GetElementsByTagName ("book", "http://www.goo.com");
592 			Assert.AreEqual (2, bookList.Count, "GetElementsByTagName (string, uri) returned incorrect count.");
593 		}
594 
595 		[Test]
GetElementsByTagNameNs2()596 		public void GetElementsByTagNameNs2 ()
597 		{
598 			document.LoadXml (@"<root>
599 			<x:a xmlns:x='urn:foo' id='a'>
600 			<y:a xmlns:y='urn:foo' id='b'/>
601 			<x:a id='c' />
602 			<z id='d' />
603 			text node
604 			<?a processing instruction ?>
605 			<x:w id='e'/>
606 			</x:a>
607 			</root>");
608 			// id='b' has different prefix. Should not caught by (name),
609 			// while should caught by (name, ns).
610 			XmlNodeList nl = document.GetElementsByTagName ("x:a");
611 			Assert.AreEqual (2, nl.Count);
612 			Assert.AreEqual ("a", nl [0].Attributes ["id"].Value);
613 			Assert.AreEqual ("c", nl [1].Attributes ["id"].Value);
614 
615 			nl = document.GetElementsByTagName ("a", "urn:foo");
616 			Assert.AreEqual (3, nl.Count);
617 			Assert.AreEqual ("a", nl [0].Attributes ["id"].Value);
618 			Assert.AreEqual ("b", nl [1].Attributes ["id"].Value);
619 			Assert.AreEqual ("c", nl [2].Attributes ["id"].Value);
620 
621 			// name wildcard
622 			nl = document.GetElementsByTagName ("*");
623 			Assert.AreEqual (6, nl.Count);
624 			Assert.AreEqual ("root", nl [0].Name);
625 			Assert.AreEqual ("a", nl [1].Attributes ["id"].Value);
626 			Assert.AreEqual ("b", nl [2].Attributes ["id"].Value);
627 			Assert.AreEqual ("c", nl [3].Attributes ["id"].Value);
628 			Assert.AreEqual ("d", nl [4].Attributes ["id"].Value);
629 			Assert.AreEqual ("e", nl [5].Attributes ["id"].Value);
630 
631 			// wildcard - local and ns
632 			nl = document.GetElementsByTagName ("*", "*");
633 			Assert.AreEqual (6, nl.Count);
634 			Assert.AreEqual ("root", nl [0].Name);
635 			Assert.AreEqual ("a", nl [1].Attributes ["id"].Value);
636 			Assert.AreEqual ("b", nl [2].Attributes ["id"].Value);
637 			Assert.AreEqual ("c", nl [3].Attributes ["id"].Value);
638 			Assert.AreEqual ("d", nl [4].Attributes ["id"].Value);
639 			Assert.AreEqual ("e", nl [5].Attributes ["id"].Value);
640 
641 			// namespace wildcard - namespace
642 			nl = document.GetElementsByTagName ("*", "urn:foo");
643 			Assert.AreEqual (4, nl.Count);
644 			Assert.AreEqual ("a", nl [0].Attributes ["id"].Value);
645 			Assert.AreEqual ("b", nl [1].Attributes ["id"].Value);
646 			Assert.AreEqual ("c", nl [2].Attributes ["id"].Value);
647 			Assert.AreEqual ("e", nl [3].Attributes ["id"].Value);
648 
649 			// namespace wildcard - local only. I dare say, such usage is not XML-ish!
650 			nl = document.GetElementsByTagName ("a", "*");
651 			Assert.AreEqual (3, nl.Count);
652 			Assert.AreEqual ("a", nl [0].Attributes ["id"].Value);
653 			Assert.AreEqual ("b", nl [1].Attributes ["id"].Value);
654 			Assert.AreEqual ("c", nl [2].Attributes ["id"].Value);
655 		}
656 
657 		[Test]
Implementation()658 		public void Implementation ()
659 		{
660 			Assert.IsNotNull (new XmlDocument ().Implementation);
661 		}
662 
663 		[Test]
InnerAndOuterXml()664 		public void InnerAndOuterXml ()
665 		{
666 			Assert.AreEqual (String.Empty, document.InnerXml);
667 			Assert.AreEqual (document.InnerXml, document.OuterXml);
668 
669 			XmlDeclaration declaration = document.CreateXmlDeclaration ("1.0", null, null);
670 			document.AppendChild (declaration);
671 			Assert.AreEqual ("<?xml version=\"1.0\"?>", document.InnerXml);
672 			Assert.AreEqual (document.InnerXml, document.OuterXml);
673 
674 			XmlElement element = document.CreateElement ("foo");
675 			document.AppendChild (element);
676 			Assert.AreEqual ("<?xml version=\"1.0\"?><foo />", document.InnerXml);
677 			Assert.AreEqual (document.InnerXml, document.OuterXml);
678 
679 			XmlComment comment = document.CreateComment ("bar");
680 			document.DocumentElement.AppendChild (comment);
681 			Assert.AreEqual ("<?xml version=\"1.0\"?><foo><!--bar--></foo>", document.InnerXml);
682 			Assert.AreEqual (document.InnerXml, document.OuterXml);
683 
684 			XmlText text = document.CreateTextNode ("baz");
685 			document.DocumentElement.AppendChild (text);
686 			Assert.AreEqual ("<?xml version=\"1.0\"?><foo><!--bar-->baz</foo>", document.InnerXml);
687 			Assert.AreEqual (document.InnerXml, document.OuterXml);
688 
689 			element = document.CreateElement ("quux");
690 			element.SetAttribute ("quuux", "squonk");
691 			document.DocumentElement.AppendChild (element);
692 			Assert.AreEqual ("<?xml version=\"1.0\"?><foo><!--bar-->baz<quux quuux=\"squonk\" /></foo>", document.InnerXml);
693 			Assert.AreEqual (document.InnerXml, document.OuterXml);
694 		}
695 
696 		[Test]
LoadWithSystemIOStream()697 		public void LoadWithSystemIOStream ()
698 		{
699 			string xml = @"<library><book><title>XML Fun</title><author>John Doe</author>
700 				<price>34.95</price></book><book><title>Bear and the Dragon</title>
701 				<author>Tom Clancy</author><price>6.95</price></book><book>
702 				<title>Bourne Identity</title><author>Robert Ludlum</author>
703 				<price>9.95</price></book><Fluffer><Nutter><book>
704 				<title>Bourne Ultimatum</title><author>Robert Ludlum</author>
705 				<price>9.95</price></book></Nutter></Fluffer></library>";
706 
707 			MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml));
708 			document = new XmlDocument ();
709 			document.Load (memoryStream);
710 			Assert.AreEqual (true, document.HasChildNodes, "Not Loaded From IOStream");
711 		}
712 
713 		[Test]
LoadXmlReaderNamespacesFalse()714 		public void LoadXmlReaderNamespacesFalse ()
715 		{
716 			XmlTextReader xtr = new XmlTextReader (
717 				"<root xmlns='urn:foo' />", XmlNodeType.Document, null);
718 			xtr.Namespaces = false;
719 			document.Load (xtr); // Don't complain about xmlns attribute with its namespaceURI == String.Empty.
720 		}
721 
722 		[Test]
LoadXmlCDATA()723 		public void LoadXmlCDATA ()
724 		{
725 			document.LoadXml ("<foo><![CDATA[bar]]></foo>");
726 			Assert.IsTrue (document.DocumentElement.FirstChild.NodeType == XmlNodeType.CDATA);
727 			Assert.AreEqual ("bar", document.DocumentElement.FirstChild.Value);
728 		}
729 
730 		[Test]
LoadXMLComment()731 		public void LoadXMLComment()
732 		{
733 // XmlTextReader needs to throw this exception
734 //			try {
735 //				document.LoadXml("<!--foo-->");
736 //				Assert.Fail ("XmlException should have been thrown.");
737 //			}
738 //			catch (XmlException e) {
739 //				Assert.AreEqual ("The root element is missing.", e.Message, "Exception message doesn't match.");
740 //			}
741 
742 			document.LoadXml ("<foo><!--Comment--></foo>");
743 			Assert.IsTrue (document.DocumentElement.FirstChild.NodeType == XmlNodeType.Comment);
744 			Assert.AreEqual ("Comment", document.DocumentElement.FirstChild.Value);
745 
746 			document.LoadXml (@"<foo><!--bar--></foo>");
747 			Assert.AreEqual ("bar", ((XmlComment)document.FirstChild.FirstChild).Data, "Incorrect target.");
748 		}
749 
750 		[Test]
LoadXmlElementSingle()751 		public void LoadXmlElementSingle ()
752 		{
753 			Assert.IsNull (document.DocumentElement);
754 			document.LoadXml ("<foo/>");
755 
756 			Assert.IsNotNull (document.DocumentElement);
757 			Assert.AreSame (document.FirstChild, document.DocumentElement);
758 
759 			Assert.AreEqual (String.Empty, document.DocumentElement.Prefix);
760 			Assert.AreEqual ("foo", document.DocumentElement.LocalName);
761 			Assert.AreEqual (String.Empty, document.DocumentElement.NamespaceURI);
762 			Assert.AreEqual ("foo", document.DocumentElement.Name);
763 		}
764 
765 		[Test]
LoadXmlElementWithAttributes()766 		public void LoadXmlElementWithAttributes ()
767 		{
768 			Assert.IsNull (document.DocumentElement);
769 			document.LoadXml ("<foo bar='baz' quux='quuux' hoge='hello &amp; world' />");
770 
771 			XmlElement documentElement = document.DocumentElement;
772 
773 			Assert.AreEqual ("baz", documentElement.GetAttribute ("bar"));
774 			Assert.AreEqual ("quuux", documentElement.GetAttribute ("quux"));
775 			Assert.AreEqual ("hello & world", documentElement.GetAttribute ("hoge"));
776 			Assert.AreEqual ("hello & world", documentElement.Attributes ["hoge"].Value);
777 			Assert.AreEqual (1, documentElement.GetAttributeNode ("hoge").ChildNodes.Count);
778 		}
779 
780 		[Test]
LoadXmlElementWithChildElement()781 		public void LoadXmlElementWithChildElement ()
782 		{
783 			document.LoadXml ("<foo><bar/></foo>");
784 			Assert.IsTrue (document.ChildNodes.Count == 1);
785 			Assert.IsTrue (document.FirstChild.ChildNodes.Count == 1);
786 			Assert.AreEqual ("foo", document.DocumentElement.LocalName);
787 			Assert.AreEqual ("bar", document.DocumentElement.FirstChild.LocalName);
788 		}
789 
790 		[Test]
LoadXmlElementWithTextNode()791 		public void LoadXmlElementWithTextNode ()
792 		{
793 			document.LoadXml ("<foo>bar</foo>");
794 			Assert.IsTrue (document.DocumentElement.FirstChild.NodeType == XmlNodeType.Text);
795 			Assert.AreEqual ("bar", document.DocumentElement.FirstChild.Value);
796 		}
797 
798 		[Test]
LoadXmlExceptionClearsDocument()799 		public void LoadXmlExceptionClearsDocument ()
800 		{
801 			document.LoadXml ("<foo/>");
802 			Assert.IsTrue (document.FirstChild != null);
803 
804 			try {
805 				document.LoadXml ("<123/>");
806 				Assert.Fail ("An XmlException should have been thrown.");
807 			} catch (XmlException) {}
808 
809 			Assert.IsTrue (document.FirstChild == null);
810 		}
811 
812 		[Test]
LoadXmlProcessingInstruction()813 		public void LoadXmlProcessingInstruction ()
814 		{
815 			document.LoadXml (@"<?foo bar='baaz' quux='quuux'?><quuuux></quuuux>");
816 			Assert.AreEqual ("foo", ((XmlProcessingInstruction)document.FirstChild).Target, "Incorrect target.");
817 			Assert.AreEqual ("bar='baaz' quux='quuux'", ((XmlProcessingInstruction)document.FirstChild).Data, "Incorrect data.");
818 		}
819 
820 		[Test]
OuterXml()821 		public void OuterXml ()
822 		{
823 			string xml;
824 
825 			xml = "<root><![CDATA[foo]]></root>";
826 			document.LoadXml (xml);
827 			Assert.AreEqual (xml, document.OuterXml, "XmlDocument with cdata OuterXml is incorrect.");
828 
829 			xml = "<root><!--foo--></root>";
830 			document.LoadXml (xml);
831 			Assert.AreEqual (xml, document.OuterXml, "XmlDocument with comment OuterXml is incorrect.");
832 
833 			xml = "<root><?foo bar?></root>";
834 			document.LoadXml (xml);
835 			Assert.AreEqual (xml, document.OuterXml, "XmlDocument with processing instruction OuterXml is incorrect.");
836 		}
837 
838 		[Test]
ParentNodes()839 		public void ParentNodes ()
840 		{
841 			document.LoadXml ("<foo><bar><baz/></bar></foo>");
842 			XmlNode node = document.FirstChild.FirstChild.FirstChild;
843 			Assert.AreEqual ("baz", node.LocalName, "Wrong child found.");
844 			Assert.AreEqual ("bar", node.ParentNode.LocalName, "Wrong parent.");
845 			Assert.AreEqual ("foo", node.ParentNode.ParentNode.LocalName, "Wrong parent.");
846 			Assert.AreEqual ("#document", node.ParentNode.ParentNode.ParentNode.LocalName, "Wrong parent.");
847 			Assert.IsNull (node.ParentNode.ParentNode.ParentNode.ParentNode, "Expected parent to be null.");
848 		}
849 
850 		[Test]
RemovedElementNextSibling()851 		public void RemovedElementNextSibling ()
852 		{
853 			XmlNode node;
854 			XmlNode nextSibling;
855 
856 			document.LoadXml ("<foo><child1/><child2/></foo>");
857 			node = document.DocumentElement.FirstChild;
858 			document.DocumentElement.RemoveChild (node);
859 			nextSibling = node.NextSibling;
860 			Assert.IsNull (nextSibling, "Expected removed node's next sibling to be null.");
861 		}
862 
863 		// ImportNode
864 		[Test]
ImportNode()865 		public void ImportNode ()
866 		{
867 			XmlNode n;
868 
869 			string xlinkURI = "http://www.w3.org/1999/XLink";
870 			string xml1 = "<?xml version='1.0' encoding='utf-8' ?><foo xmlns:xlink='" + xlinkURI + "'><bar a1='v1' xlink:href='#foo'><baz><![CDATA[cdata section.\n\titem 1\n\titem 2\n]]>From here, simple text node.</baz></bar></foo>";
871 			document.LoadXml(xml1);
872 			XmlDocument newDoc = new XmlDocument();
873 			newDoc.LoadXml("<hoge><fuga /></hoge>");
874 			XmlElement bar = document.DocumentElement.FirstChild as XmlElement;
875 
876 			// Attribute
877 			n = newDoc.ImportNode(bar.GetAttributeNode("href", xlinkURI), true);
878 			Assert.AreEqual ("href", n.LocalName, "#ImportNode.Attr.NS.LocalName");
879 			Assert.AreEqual (xlinkURI, n.NamespaceURI, "#ImportNode.Attr.NS.NSURI");
880 			Assert.AreEqual ("#foo", n.Value, "#ImportNode.Attr.NS.Value");
881 
882 			// CDATA
883 			n = newDoc.ImportNode(bar.FirstChild.FirstChild, true);
884 			Assert.AreEqual ("cdata section.\n\titem 1\n\titem 2\n", n.Value, "#ImportNode.CDATA");
885 
886 			// Element
887 			XmlElement e = newDoc.ImportNode(bar, true) as XmlElement;
888 			Assert.AreEqual ("bar", e.Name, "#ImportNode.Element.Name");
889 			Assert.AreEqual ("#foo", e.GetAttribute("href", xlinkURI), "#ImportNode.Element.Attr");
890 			Assert.AreEqual ("baz", e.FirstChild.Name, "#ImportNode.Element.deep");
891 
892 			// Entity Reference:
893 			//   [2002/10/14] CreateEntityReference was not implemented.
894 //			document.LoadXml("<!DOCTYPE test PUBLIC 'dummy' [<!ENTITY FOOENT 'foo'>]><root>&FOOENT;</root>");
895 //			n = newDoc.ImportNode(document.DocumentElement.FirstChild);
896 //			Assert.AreEqual ("FOOENT", n.Name, "#ImportNode.EntityReference");
897 //			Assert.AreEqual ("foo_", n.Value, "#ImportNode.EntityReference");
898 
899 			// Processing Instruction
900 			document.LoadXml("<foo><?xml-stylesheet href='foo.xsl' ?></foo>");
901 			XmlProcessingInstruction pi = (XmlProcessingInstruction)newDoc.ImportNode(document.DocumentElement.FirstChild, false);
902 			Assert.AreEqual ("xml-stylesheet", pi.Name, "#ImportNode.ProcessingInstruction.Name");
903 			Assert.AreEqual ("href='foo.xsl'", pi.Data.Trim(), "#ImportNode.ProcessingInstruction.Data");
904 
905 			// Text
906 			document.LoadXml(xml1);
907 			n = newDoc.ImportNode((XmlText)bar.FirstChild.ChildNodes[1], true);
908 			Assert.AreEqual ("From here, simple text node.", n.Value, "#ImportNode.Text");
909 
910 			// XmlDeclaration
911 			document.LoadXml(xml1);
912 			XmlDeclaration decl = (XmlDeclaration)newDoc.ImportNode(document.FirstChild, false);
913 			Assert.AreEqual (XmlNodeType.XmlDeclaration, decl.NodeType, "#ImportNode.XmlDeclaration.Type");
914 			Assert.AreEqual ("utf-8", decl.Encoding, "#ImportNode.XmlDeclaration.Encoding");
915 		}
916 
917 		[Test]
NameTable()918 		public void NameTable()
919 		{
920 			XmlDocument doc = new XmlDocument();
921 			Assert.IsNotNull (doc.NameTable);
922 		}
923 
924 		[Test]
SingleEmptyRootDocument()925 		public void SingleEmptyRootDocument()
926 		{
927 			XmlDocument doc = new XmlDocument();
928 			doc.LoadXml("<root />");
929 			Assert.IsNotNull (doc.DocumentElement);
930 		}
931 
932 		[Test]
DocumentWithDoctypeDecl()933 		public void DocumentWithDoctypeDecl ()
934 		{
935 			XmlDocument doc = new XmlDocument ();
936 			// In fact it is invalid, but it doesn't fail with MS.NET 1.0.
937 			doc.LoadXml ("<!DOCTYPE test><root />");
938 			Assert.IsNotNull (doc.DocumentType);
939 #if NetworkEnabled
940 			try
941 			{
942 				doc.LoadXml ("<!DOCTYPE test SYSTEM 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><root />");
943 			} catch (XmlException) {
944 				Assert.Fail ("#DoctypeDecl.System");
945 			}
946 			try {
947 				doc.LoadXml ("<!DOCTYPE test PUBLIC '-//test' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><root />");
948 			} catch (XmlException) {
949 				Assert.Fail ("#DoctypeDecl.Public");
950 			}
951 #endif
952 			// Should this be commented out?
953 			doc.LoadXml ("<!DOCTYPE test [<!ELEMENT foo EMPTY>]><test><foo/></test>");
954 		}
955 
956 		[Test]
CloneNode()957 		public void CloneNode ()
958 		{
959 			XmlDocument doc = new XmlDocument ();
960 			doc.LoadXml ("<foo><bar /><baz hoge='fuga'>TEST Text</baz></foo>");
961 			XmlDocument doc2 = (XmlDocument)doc.CloneNode (false);
962 			Assert.AreEqual (0, doc2.ChildNodes.Count, "ShallowCopy");
963 			doc2 = (XmlDocument)doc.CloneNode (true);
964 			Assert.AreEqual ("foo", doc2.DocumentElement.Name, "DeepCopy");
965 		}
966 
967 		[Test]
OuterXmlWithDefaultXmlns()968 		public void OuterXmlWithDefaultXmlns ()
969 		{
970 			XmlDocument doc = new XmlDocument ();
971 			doc.LoadXml ("<iq type=\"get\" id=\"ATECLIENT_1\"><query xmlns=\"jabber:iq:auth\"><username></username></query></iq>");
972 			Assert.AreEqual ("<iq type=\"get\" id=\"ATECLIENT_1\"><query xmlns=\"jabber:iq:auth\"><username></username></query></iq>", doc.OuterXml);
973 		}
974 
975 		[Test]
PreserveWhitespace()976 		public void PreserveWhitespace ()
977 		{
978 			string input =
979 				"<?xml version=\"1.0\" encoding=\"utf-8\" ?><!-- --> <foo/>";
980 
981 			XmlDocument dom = new XmlDocument ();
982 			XmlTextReader reader = new XmlTextReader (new StringReader (input));
983 			dom.Load (reader);
984 
985 			Assert.AreEqual (XmlNodeType.Element, dom.FirstChild.NextSibling.NextSibling.NodeType);
986 		}
987 
988 		[Test]
PreserveWhitespace2()989 		public void PreserveWhitespace2 ()
990 		{
991 			XmlDocument doc = new XmlDocument ();
992 			Assert.IsTrue (!doc.PreserveWhitespace);
993 			doc.PreserveWhitespace = true;
994 			XmlDocument d2 = doc.Clone () as XmlDocument;
995 			Assert.IsTrue (!d2.PreserveWhitespace); // i.e. not cloned
996 			d2.AppendChild (d2.CreateElement ("root"));
997 			d2.DocumentElement.AppendChild (d2.CreateWhitespace ("   "));
998 			StringWriter sw = new StringWriter ();
999 			d2.WriteTo (new XmlTextWriter (sw));
1000 			Assert.AreEqual ("<root>   </root>", sw.ToString ());
1001 		}
1002 
1003 		[Test]
CreateAttribute()1004 		public void CreateAttribute ()
1005 		{
1006 			XmlDocument dom = new XmlDocument ();
1007 
1008 			// Check that null prefix and namespace are allowed and
1009 			// equivalent to ""
1010 			XmlAttribute attr = dom.CreateAttribute (null, "FOO", null);
1011 			Assert.AreEqual (attr.Prefix, "");
1012 			Assert.AreEqual (attr.NamespaceURI, "");
1013 		}
1014 
1015 		[Test]
DocumentTypeNodes()1016 		public void DocumentTypeNodes ()
1017 		{
1018 			string entities = "<!ENTITY foo 'foo-ent'>";
1019 			string dtd = "<!DOCTYPE root [<!ELEMENT root (#PCDATA)*> " + entities + "]>";
1020 			string xml = dtd + "<root>&foo;</root>";
1021 			XmlValidatingReader xvr = new XmlValidatingReader (xml, XmlNodeType.Document, null);
1022 			document.Load (xvr);
1023 			Assert.IsNotNull (document.DocumentType);
1024 			Assert.AreEqual (1, document.DocumentType.Entities.Count);
1025 
1026 			XmlEntity foo = document.DocumentType.Entities.GetNamedItem ("foo") as XmlEntity;
1027 			Assert.IsNotNull (foo);
1028 			Assert.IsNotNull (document.DocumentType.Entities.GetNamedItem ("foo", ""));
1029 			Assert.AreEqual ("foo", foo.Name);
1030 			Assert.IsNull (foo.Value);
1031 			Assert.AreEqual ("foo-ent", foo.InnerText);
1032 		}
1033 
1034 		[Test]
DTDEntityAttributeHandling()1035 		public void DTDEntityAttributeHandling ()
1036 		{
1037 			string dtd = "<!DOCTYPE root[<!ATTLIST root hoge CDATA 'hoge-def'><!ENTITY foo 'ent-foo'>]>";
1038 			string xml = dtd + "<root>&foo;</root>";
1039 			XmlValidatingReader xvr = new XmlValidatingReader (xml, XmlNodeType.Document,null);
1040 			xvr.EntityHandling = EntityHandling.ExpandCharEntities;
1041 			xvr.ValidationType = ValidationType.None;
1042 			document.Load (xvr);
1043 			// Don't include default attributes here.
1044 			Assert.AreEqual (xml, document.OuterXml);
1045 			Assert.AreEqual ("hoge-def", document.DocumentElement.GetAttribute ("hoge"));
1046 		}
1047 
1048 //		[Test]  Comment out in the meantime.
1049 //		public void LoadExternalUri ()
1050 //		{
1051 //			// set any URL of well-formed XML.
1052 //			document.Load ("http://www.go-mono.com/index.rss");
1053 //		}
1054 
1055 //		[Test] comment out in the meantime.
1056 //		public void LoadDocumentWithIgnoreSection ()
1057 //		{
1058 //			// set any URL of well-formed XML.
1059 //			document.Load ("xmlfiles/test.xml");
1060 //		}
1061 
1062 		[Test]
1063 		[ExpectedException (typeof (XmlException))]
LoadThrowsUndeclaredEntity()1064 		public void LoadThrowsUndeclaredEntity ()
1065 		{
1066 			string ent1 = "<!ENTITY ent 'entity string'>";
1067 			string ent2 = "<!ENTITY ent2 '<foo/><foo/>'>]>";
1068 			string dtd = "<!DOCTYPE root[<!ELEMENT root (#PCDATA|foo)*>" + ent1 + ent2;
1069 			string xml = dtd + "<root>&ent3;&ent2;</root>";
1070 			XmlTextReader xtr = new XmlTextReader (xml, XmlNodeType.Document, null);
1071 			document.Load (xtr);
1072 			xtr.Close ();
1073 		}
1074 
1075 		[Test]
CreateEntityReferencesWithoutDTD()1076 		public void CreateEntityReferencesWithoutDTD ()
1077 		{
1078 			document.RemoveAll ();
1079 			document.AppendChild (document.CreateElement ("root"));
1080 			document.DocumentElement.AppendChild (document.CreateEntityReference ("foo"));
1081 		}
1082 
1083 		[Test]
LoadEntityReference()1084 		public void LoadEntityReference ()
1085 		{
1086 			string xml = "<!DOCTYPE root [<!ELEMENT root (#PCDATA)*><!ENTITY ent 'val'>]><root attr='a &ent; string'>&ent;</root>";
1087 			XmlTextReader xtr = new XmlTextReader (xml, XmlNodeType.Document, null);
1088 			XmlDocument doc = new XmlDocument ();
1089 			doc.Load (xtr);
1090 			Assert.AreEqual (XmlNodeType.EntityReference, doc.DocumentElement.FirstChild.NodeType, "#text node");
1091 			Assert.AreEqual (XmlNodeType.EntityReference, doc.DocumentElement.Attributes [0].ChildNodes [1].NodeType, "#attribute");
1092 		}
1093 
1094 		[Test]
ReadNodeEmptyContent()1095 		public void ReadNodeEmptyContent ()
1096 		{
1097 			XmlTextReader xr = new XmlTextReader ("", XmlNodeType.Element, null);
1098 			xr.Read ();
1099 			Console.WriteLine (xr.NodeType);
1100 			XmlNode n = document.ReadNode (xr);
1101 			Assert.IsNull (n);
1102 		}
1103 
1104 		[Test]
ReadNodeWhitespace()1105 		public void ReadNodeWhitespace ()
1106 		{
1107 			XmlTextReader xr = new XmlTextReader ("  ", XmlNodeType.Element, null);
1108 			xr.Read ();
1109 			Console.WriteLine (xr.NodeType);
1110 			document.PreserveWhitespace = false; // Note this line.
1111 			XmlNode n = document.ReadNode (xr);
1112 			Assert.IsNotNull (n);
1113 			Assert.AreEqual (XmlNodeType.Whitespace, n.NodeType);
1114 		}
1115 
1116 		[Test]
SavePreserveWhitespace()1117 		public void SavePreserveWhitespace ()
1118 		{
1119 			string xml = "<root>  <element>text\n</element></root>";
1120 			XmlDocument doc = new XmlDocument ();
1121 			doc.PreserveWhitespace = true;
1122 			doc.LoadXml (xml);
1123 			StringWriter sw = new StringWriter ();
1124 			doc.Save (sw);
1125 			Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>" + xml, sw.ToString ());
1126 
1127 			doc.PreserveWhitespace = false;
1128 			sw = new StringWriter ();
1129 			doc.Save (sw);
1130 			string NEL = Environment.NewLine;
1131 			Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>"
1132 				+ NEL + "<root>  <element>text"
1133 				+ "\n</element></root>",
1134 				sw.ToString ());
1135 		}
1136 
1137 		[Test]
ReadNodeEntityReferenceFillsChildren()1138 		public void ReadNodeEntityReferenceFillsChildren ()
1139 		{
1140 			string dtd = "<!DOCTYPE root [<!ELEMENT root (#PCDATA)*><!ENTITY ent 'val'>]>";
1141 
1142 			string xml = dtd + "<root attr='a &ent; string'>&ent;</root>";
1143 			XmlValidatingReader reader = new XmlValidatingReader (
1144 				xml, XmlNodeType.Document, null);
1145 
1146 			reader.EntityHandling = EntityHandling.ExpandCharEntities;
1147 			reader.ValidationType = ValidationType.None;
1148 
1149 			//skip the doctype delcaration
1150 			reader.Read ();
1151 			reader.Read ();
1152 
1153 			XmlDocument doc = new XmlDocument ();
1154 			doc.Load (reader);
1155 
1156 			Assert.AreEqual (1,
1157 				doc.DocumentElement.FirstChild.ChildNodes.Count);
1158 		}
1159 
1160 		[Test]
LoadTreatsFixedAttributesAsIfItExisted()1161 		public void LoadTreatsFixedAttributesAsIfItExisted ()
1162 		{
1163 			string xml = @"<!DOCTYPE foo [<!ELEMENT foo EMPTY><!ATTLIST foo xmlns CDATA #FIXED 'urn:foo'>]><foo />";
1164 			XmlDocument doc = new XmlDocument ();
1165 			doc.Load (new StringReader (xml));
1166 			Assert.AreEqual ("urn:foo", doc.DocumentElement.NamespaceURI);
1167 		}
1168 
1169 		[Test]
Bug79468()1170 		public void Bug79468 () // XmlNameEntryCache bug
1171 		{
1172 			string xml = "<?xml version='1.0' encoding='UTF-8'?>"
1173 				+ "<ns0:DebtAmountRequest xmlns:ns0='http://whatever'>"
1174 				+ "  <Signature xmlns='http://www.w3.org/2000/09/xmldsig#' />"
1175 				+ "</ns0:DebtAmountRequest>";
1176 			XmlDocument doc = new XmlDocument ();
1177 			doc.LoadXml (xml);
1178 			XmlNodeList nodeList = doc.GetElementsByTagName ("Signature");
1179 		}
1180 
1181 		class MyXmlDocument : XmlDocument
1182 		{
CreateAttribute(string p, string l, string n)1183 			public override XmlAttribute CreateAttribute (string p, string l, string n)
1184 			{
1185 				return base.CreateAttribute (p, "hijacked", n);
1186 			}
1187 		}
1188 
1189 		[Test]
UseOverridenCreateAttribute()1190 		public void UseOverridenCreateAttribute ()
1191 		{
1192 			XmlDocument doc = new MyXmlDocument ();
1193 			doc.LoadXml ("<root a='sane' />");
1194 			Assert.IsNotNull (doc.DocumentElement.GetAttributeNode ("hijacked"));
1195 			Assert.IsNull (doc.DocumentElement.GetAttributeNode ("a"));
1196 		}
1197 
1198 		[Test]
LoadFromMiddleOfDocument()1199 		public void LoadFromMiddleOfDocument ()
1200 		{
1201 			// bug #598953
1202 			string xml = @"<?xml version='1.0' encoding='utf-8' ?>
1203 <Racal>
1204   <Ports>
1205     <ConsolePort value='9998' />
1206   </Ports>
1207 </Racal>";
1208 			var r = new XmlTextReader (new StringReader (xml));
1209 			r.WhitespaceHandling = WhitespaceHandling.All;
1210 			r.MoveToContent ();
1211 			r.Read ();
1212 			var doc = new XmlDocument ();
1213 			doc.Load (r);
1214 			Assert.AreEqual (XmlNodeType.EndElement, r.NodeType, "#1");
1215 		}
1216 	}
1217 }
1218