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