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