Added implementation of namepsace qualified GetElementsByTagName courtesy of
[mono.git] / mcs / class / System.XML / Test / XmlDocumentTests.cs
1 //
2 // System.Xml.XmlDocumentTests
3 //
4 // Authors:
5 //   Jason Diamond <jason@injektilo.org>
6 //   Kral Ferch <kral_ferch@hotmail.com>
7 //
8 // (C) 2002 Jason Diamond, Kral Ferch
9 //
10
11 using System;
12 using System.Collections;
13 using System.Xml;
14 using System.IO;
15 using System.Text;
16
17 using NUnit.Framework;
18
19 namespace MonoTests.System.Xml
20 {
21         public class XmlDocumentTests : TestCase
22         {
23                 public XmlDocumentTests () : base ("MonoTests.System.Xml.XmlDocumentTests testsuite") {}
24                 public XmlDocumentTests (string name) : base (name) {}
25
26                 private XmlDocument document;
27                 private ArrayList eventStrings = new ArrayList();
28
29                 // These Event* methods support the TestEventNode* Tests in this file.
30                 // Most of them are event handlers for the XmlNodeChangedEventHandler
31                 // delegate.
32                 private void EventStringAdd(string eventName, XmlNodeChangedEventArgs e)
33                 {
34                         string oldParent = (e.OldParent != null) ? e.OldParent.Name : "<none>";
35                         string newParent = (e.NewParent != null) ? e.NewParent.Name : "<none>";
36                         eventStrings.Add (String.Format ("{0}, {1}, {2}, {3}, {4}", eventName, e.Action.ToString (), e.Node.OuterXml, oldParent, newParent));
37                 }
38
39                 private void EventNodeChanged(Object sender, XmlNodeChangedEventArgs e)
40                 {
41                         EventStringAdd ("NodeChanged", e);
42                 }
43
44                 private void EventNodeChanging (Object sender, XmlNodeChangedEventArgs e)
45                 {
46                         EventStringAdd ("NodeChanging", e);
47                 }
48
49                 private void EventNodeChangingException (Object sender, XmlNodeChangedEventArgs e)
50                 {
51                         throw new Exception ("don't change the value.");
52                 }
53
54                 private void EventNodeInserted(Object sender, XmlNodeChangedEventArgs e)
55                 {
56                         EventStringAdd ("NodeInserted", e);
57                 }
58
59                 private void EventNodeInserting(Object sender, XmlNodeChangedEventArgs e)
60                 {
61                         EventStringAdd ("NodeInserting", e);
62                 }
63
64                 private void EventNodeInsertingException(Object sender, XmlNodeChangedEventArgs e)
65                 {
66                         throw new Exception ("don't insert the element.");
67                 }
68
69                 private void EventNodeRemoved(Object sender, XmlNodeChangedEventArgs e)
70                 {
71                         EventStringAdd ("NodeRemoved", e);
72                 }
73
74                 private void EventNodeRemoving(Object sender, XmlNodeChangedEventArgs e)
75                 {
76                         EventStringAdd ("NodeRemoving", e);
77                 }
78
79                 private void EventNodeRemovingException(Object sender, XmlNodeChangedEventArgs e)
80                 {
81                         throw new Exception ("don't remove the element.");
82                 }
83
84                 protected override void SetUp ()
85                 {
86                         document = new XmlDocument ();
87                 }
88
89                 public void TestCreateNodeNodeTypeNameEmptyParams ()
90                 {
91                         XmlNode node;
92
93                         try {
94                                 node = document.CreateNode (null, null, null);
95                                 Fail ("Expected an ArgumentException to be thrown.");
96                         } catch (ArgumentException) {}
97
98                         try {
99                                 node = document.CreateNode ("attribute", null, null);
100                                 Fail ("Expected a NullReferenceException to be thrown.");
101                         } catch (NullReferenceException) {}
102
103                         try {
104                                 node = document.CreateNode ("attribute", "", null);
105                                 Fail ("Expected an ArgumentException to be thrown.");
106                         } catch (ArgumentException) {}
107
108                         try {
109                                 node = document.CreateNode ("element", null, null);
110                                 Fail ("Expected a NullReferenceException to be thrown.");
111                         } catch (NullReferenceException) {}
112
113                         try {
114                                 node = document.CreateNode ("element", "", null);
115                                 Fail ("Expected an ArgumentException to be thrown.");
116                         } catch (ArgumentException) {}
117
118                         try {
119                                 node = document.CreateNode ("entityreference", null, null);
120                                 Fail ("Expected a NullReferenceException to be thrown.");
121                         } catch (NullReferenceException) {}
122                 }
123
124                 public void TestCreateNodeInvalidXmlNodeType ()
125                 {
126                         XmlNode node;
127
128                         try {
129                                 node = document.CreateNode (XmlNodeType.EndElement, null, null);
130                                 Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
131                         } catch (ArgumentOutOfRangeException) {}
132
133                         try {
134                                 node = document.CreateNode (XmlNodeType.EndEntity, null, null);
135                                 Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
136                         } catch (ArgumentOutOfRangeException) {}
137
138                         try {
139                                 node = document.CreateNode (XmlNodeType.Entity, null, null);
140                                 Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
141                         } catch (ArgumentOutOfRangeException) {}
142
143                         try {
144                                 node = document.CreateNode (XmlNodeType.None, null, null);
145                                 Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
146                         } catch (ArgumentOutOfRangeException) {}
147
148                         try {
149                                 node = document.CreateNode (XmlNodeType.Notation, null, null);
150                                 Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
151                         } catch (ArgumentOutOfRangeException) {}
152
153                         // TODO:  undocumented allowable type.
154                         node = document.CreateNode (XmlNodeType.XmlDeclaration, null, null);
155                         AssertEquals (XmlNodeType.XmlDeclaration, node.NodeType);
156                 }
157
158                 public void TestCreateNodeWhichParamIsUsed ()
159                 {
160                         XmlNode node;
161
162                         // No constructor params for Document, DocumentFragment.
163
164                         node = document.CreateNode (XmlNodeType.CDATA, "a", "b", "c");
165                         AssertEquals (String.Empty, ((XmlCDataSection)node).Value);
166
167                         node = document.CreateNode (XmlNodeType.Comment, "a", "b", "c");
168                         AssertEquals (String.Empty, ((XmlComment)node).Value);
169
170                         node = document.CreateNode (XmlNodeType.DocumentType, "a", "b", "c");
171                         AssertNull (((XmlDocumentType)node).Value);
172
173 // TODO: add this back in to test when it's implemented.
174 //                      node = document.CreateNode (XmlNodeType.EntityReference, "a", "b", "c");
175 //                      AssertNull (((XmlEntityReference)node).Value);
176
177                         node = document.CreateNode (XmlNodeType.ProcessingInstruction, "a", "b", "c");
178                         AssertEquals (String.Empty, ((XmlProcessingInstruction)node).Value);
179
180                         node = document.CreateNode (XmlNodeType.SignificantWhitespace, "a", "b", "c");
181                         AssertEquals (String.Empty, ((XmlSignificantWhitespace)node).Value);
182
183                         node = document.CreateNode (XmlNodeType.Text, "a", "b", "c");
184                         AssertEquals (String.Empty, ((XmlText)node).Value);
185
186                         node = document.CreateNode (XmlNodeType.Whitespace, "a", "b", "c");
187                         AssertEquals (String.Empty, ((XmlWhitespace)node).Value);
188
189                         node = document.CreateNode (XmlNodeType.XmlDeclaration, "a", "b", "c");
190                         AssertEquals ("version=\"1.0\"", ((XmlDeclaration)node).Value);
191                 }
192
193                 public void TestCreateNodeNodeTypeName ()
194                 {
195                         XmlNode node;
196
197                         try {
198                                 node = document.CreateNode ("foo", null, null);
199                                 Fail ("Expected an ArgumentException to be thrown.");
200                         } catch (ArgumentException) {}
201
202                         node = document.CreateNode("attribute", "foo", null);
203                         AssertEquals (XmlNodeType.Attribute, node.NodeType);
204
205                         node = document.CreateNode("cdatasection", null, null);
206                         AssertEquals (XmlNodeType.CDATA, node.NodeType);
207
208                         node = document.CreateNode("comment", null, null);
209                         AssertEquals (XmlNodeType.Comment, node.NodeType);
210
211                         node = document.CreateNode("document", null, null);
212                         AssertEquals (XmlNodeType.Document, node.NodeType);
213                         // TODO: test which constructor this ended up calling,
214                         // i.e. reuse underlying NameTable or not?
215
216 // TODO: add this back in to test when it's implemented.
217 //                      node = document.CreateNode("documentfragment", null, null);
218 //                      AssertEquals (XmlNodeType.DocumentFragment, node.NodeType);
219
220                         node = document.CreateNode("documenttype", null, null);
221                         AssertEquals (XmlNodeType.DocumentType, node.NodeType);
222
223                         node = document.CreateNode("element", "foo", null);
224                         AssertEquals (XmlNodeType.Element, node.NodeType);
225
226 // TODO: add this back in to test when it's implemented.
227 //                      node = document.CreateNode("entityreference", "foo", null);
228 //                      AssertEquals (XmlNodeType.EntityReference, node.NodeType);
229
230                         node = document.CreateNode("processinginstruction", null, null);
231                         AssertEquals (XmlNodeType.ProcessingInstruction, node.NodeType);
232
233                         node = document.CreateNode("significantwhitespace", null, null);
234                         AssertEquals (XmlNodeType.SignificantWhitespace, node.NodeType);
235
236                         node = document.CreateNode("text", null, null);
237                         AssertEquals (XmlNodeType.Text, node.NodeType);
238
239                         node = document.CreateNode("whitespace", null, null);
240                         AssertEquals (XmlNodeType.Whitespace, node.NodeType);
241                 }
242
243                 public void TestDocumentElement ()
244                 {
245                         AssertNull (document.DocumentElement);
246                         XmlElement element = document.CreateElement ("foo", "bar", "http://foo/");
247                         AssertNotNull (element);
248
249                         AssertEquals ("foo", element.Prefix);
250                         AssertEquals ("bar", element.LocalName);
251                         AssertEquals ("http://foo/", element.NamespaceURI);
252
253                         AssertEquals ("foo:bar", element.Name);
254
255                         AssertSame (element, document.AppendChild (element));
256
257                         AssertSame (element, document.DocumentElement);
258                 }
259
260                 public void TestDocumentEmpty()
261                 {
262                         AssertEquals ("Incorrect output for empty document.", "", document.OuterXml);
263                 }
264
265                 public void TestEventNodeChanged()
266                 {
267                         XmlElement element;
268                         XmlComment comment;
269
270                         document.NodeChanged += new XmlNodeChangedEventHandler (this.EventNodeChanged);
271
272                         // Node that is part of the document.
273                         document.AppendChild (document.CreateElement ("foo"));
274                         comment = document.CreateComment ("bar");
275                         document.DocumentElement.AppendChild (comment);
276                         AssertEquals ("<!--bar-->", document.DocumentElement.InnerXml);
277                         comment.Value = "baz";
278                         Assert (eventStrings.Contains ("NodeChanged, Change, <!--baz-->, foo, foo"));
279                         AssertEquals ("<!--baz-->", document.DocumentElement.InnerXml);
280
281                         // Node that isn't part of the document but created by the document.
282                         element = document.CreateElement ("foo");
283                         comment = document.CreateComment ("bar");
284                         element.AppendChild (comment);
285                         AssertEquals ("<!--bar-->", element.InnerXml);
286                         comment.Value = "baz";
287                         Assert (eventStrings.Contains ("NodeChanged, Change, <!--baz-->, foo, foo"));
288                         AssertEquals ("<!--baz-->", element.InnerXml);
289
290 /*
291  TODO:  Insert this when XmlNode.InnerText() and XmlNode.InnerXml() have been implemented.
292  
293                         // Node that is part of the document.
294                         element = document.CreateElement ("foo");
295                         element.InnerText = "bar";
296                         document.AppendChild(element);
297                         element.InnerText = "baz";
298                         Assert(eventStrings.Contains("NodeChanged, Change, baz, foo, foo"));
299                         
300                         // Node that isn't part of the document but created by the document.
301                         element = document.CreateElement("qux");
302                         element.InnerText = "quux";
303                         element.InnerText = "quuux";
304                         Assert(eventStrings.Contains("NodeChanged, Change, quuux, qux, qux"));
305 */
306                 }
307
308                 public void TestEventNodeChanging()
309                 {
310                         XmlElement element;
311                         XmlComment comment;
312
313                         document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChanging);
314
315                         // Node that is part of the document.
316                         document.AppendChild (document.CreateElement ("foo"));
317                         comment = document.CreateComment ("bar");
318                         document.DocumentElement.AppendChild (comment);
319                         AssertEquals ("<!--bar-->", document.DocumentElement.InnerXml);
320                         comment.Value = "baz";
321                         Assert (eventStrings.Contains ("NodeChanging, Change, <!--bar-->, foo, foo"));
322                         AssertEquals ("<!--baz-->", document.DocumentElement.InnerXml);
323
324                         // Node that isn't part of the document but created by the document.
325                         element = document.CreateElement ("foo");
326                         comment = document.CreateComment ("bar");
327                         element.AppendChild (comment);
328                         AssertEquals ("<!--bar-->", element.InnerXml);
329                         comment.Value = "baz";
330                         Assert (eventStrings.Contains ("NodeChanging, Change, <!--bar-->, foo, foo"));
331                         AssertEquals ("<!--baz-->", element.InnerXml);
332
333                         // If an exception is thrown the Document returns to original state.
334                         document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChangingException);
335                         element = document.CreateElement("foo");
336                         comment = document.CreateComment ("bar");
337                         element.AppendChild (comment);
338                         AssertEquals ("<!--bar-->", element.InnerXml);
339                         try 
340                         {
341                                 comment.Value = "baz";
342                                 Fail("Expected an exception to be thrown by the NodeChanging event handler method EventNodeChangingException().");
343                         } catch (Exception) {}
344                         AssertEquals ("<!--bar-->", element.InnerXml);
345
346                         // Yes it's a bit anal but this tests whether the node changing event exception fires before the
347                         // ArgumentOutOfRangeException.  Turns out it does so that means our implementation needs to raise
348                         // the node changing event before doing any work.
349                         try 
350                         {
351                                 comment.ReplaceData(-1, 0, "qux");
352                                 Fail("Expected an ArgumentOutOfRangeException to be thrown.");
353                         } 
354                         catch (Exception) {}
355
356                         /*
357  TODO:  Insert this when XmlNode.InnerText() and XmlNode.InnerXml() have been implemented.
358  
359                         // Node that is part of the document.
360                         element = document.CreateElement ("foo");
361                         element.InnerText = "bar";
362                         document.AppendChild(element);
363                         element.InnerText = "baz";
364                         Assert(eventStrings.Contains("NodeChanging, Change, bar, foo, foo"));
365
366                         // Node that isn't part of the document but created by the document.
367                         element = document.CreateElement("foo");
368                         element.InnerText = "bar";
369                         element.InnerText = "baz";
370                         Assert(eventStrings.Contains("NodeChanging, Change, bar, foo, foo"));
371
372                         // If an exception is thrown the Document returns to original state.
373                         document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChangingException);
374                         element = document.CreateElement("foo");
375                         element.InnerText = "bar";
376                         try {
377                                 element.InnerText = "baz";
378                                 Fail("Expected an exception to be thrown by the NodeChanging event handler method EventNodeChangingException().");
379                         } catch (Exception) {}
380                         AssertEquals("bar", element.InnerText);
381 */
382                 }
383
384                 public void TestEventNodeInserted()
385                 {
386                         XmlElement element;
387
388                         document.NodeInserted += new XmlNodeChangedEventHandler (this.EventNodeInserted);
389
390                         // Inserted 'foo' element to the document.
391                         element = document.CreateElement ("foo");
392                         document.AppendChild (element);
393                         Assert (eventStrings.Contains ("NodeInserted, Insert, <foo />, <none>, #document"));
394
395                         // Append child on node in document
396                         element = document.CreateElement ("foo");
397                         document.DocumentElement.AppendChild (element);
398                         Assert (eventStrings.Contains ("NodeInserted, Insert, <foo />, <none>, foo"));
399
400                         // Append child on node not in document but created by document
401                         element = document.CreateElement ("bar");
402                         element.AppendChild(document.CreateElement ("bar"));
403                         Assert(eventStrings.Contains("NodeInserted, Insert, <bar />, <none>, bar"));
404                 }
405
406                 public void TestEventNodeInserting()
407                 {
408                         XmlElement element;
409
410                         document.NodeInserting += new XmlNodeChangedEventHandler (this.EventNodeInserting);
411
412                         // Inserting 'foo' element to the document.
413                         element = document.CreateElement ("foo");
414                         document.AppendChild (element);
415                         Assert (eventStrings.Contains ("NodeInserting, Insert, <foo />, <none>, #document"));
416
417                         // Append child on node in document
418                         element = document.CreateElement ("foo");
419                         document.DocumentElement.AppendChild (element);
420                         Assert(eventStrings.Contains ("NodeInserting, Insert, <foo />, <none>, foo"));
421
422                         // Append child on node not in document but created by document
423                         element = document.CreateElement ("bar");
424                         AssertEquals (0, element.ChildNodes.Count);
425                         element.AppendChild (document.CreateElement ("bar"));
426                         Assert (eventStrings.Contains ("NodeInserting, Insert, <bar />, <none>, bar"));
427                         AssertEquals (1, element.ChildNodes.Count);
428
429                         // If an exception is thrown the Document returns to original state.
430                         document.NodeInserting += new XmlNodeChangedEventHandler (this.EventNodeInsertingException);
431                         AssertEquals (1, element.ChildNodes.Count);
432                         try 
433                         {
434                                 element.AppendChild (document.CreateElement("baz"));
435                                 Fail ("Expected an exception to be thrown by the NodeInserting event handler method EventNodeInsertingException().");
436                         } 
437                         catch (Exception) {}
438                         AssertEquals (1, element.ChildNodes.Count);
439                 }
440
441                 public void TestEventNodeRemoved()
442                 {
443                         XmlElement element;
444                         XmlElement element2;
445
446                         document.NodeRemoved += new XmlNodeChangedEventHandler (this.EventNodeRemoved);
447
448                         // Removed 'bar' element from 'foo' outside document.
449                         element = document.CreateElement ("foo");
450                         element2 = document.CreateElement ("bar");
451                         element.AppendChild (element2);
452                         AssertEquals (1, element.ChildNodes.Count);
453                         element.RemoveChild (element2);
454                         Assert (eventStrings.Contains ("NodeRemoved, Remove, <bar />, foo, <none>"));
455                         AssertEquals (0, element.ChildNodes.Count);
456
457 /*
458  * TODO:  put this test back in when AttributeCollection.RemoveAll() is implemented.
459
460                         // RemoveAll.
461                         element = document.CreateElement ("foo");
462                         element2 = document.CreateElement ("bar");
463                         element.AppendChild(element2);
464                         AssertEquals(1, element.ChildNodes.Count);
465                         element.RemoveAll();
466                         Assert (eventStrings.Contains ("NodeRemoved, Remove, <bar />, foo, <none>"));
467                         AssertEquals(0, element.ChildNodes.Count);
468 */
469
470                         // Removed 'bar' element from 'foo' inside document.
471                         element = document.CreateElement ("foo");
472                         document.AppendChild (element);
473                         element = document.CreateElement ("bar");
474                         document.DocumentElement.AppendChild (element);
475                         AssertEquals (1, document.DocumentElement.ChildNodes.Count);
476                         document.DocumentElement.RemoveChild (element);
477                         Assert (eventStrings.Contains ("NodeRemoved, Remove, <bar />, foo, <none>"));
478                         AssertEquals (0, document.DocumentElement.ChildNodes.Count);
479                 }
480         
481                 public void TestEventNodeRemoving()
482                 {
483                         XmlElement element;
484                         XmlElement element2;
485
486                         document.NodeRemoving += new XmlNodeChangedEventHandler (this.EventNodeRemoving);
487
488                         // Removing 'bar' element from 'foo' outside document.
489                         element = document.CreateElement ("foo");
490                         element2 = document.CreateElement ("bar");
491                         element.AppendChild (element2);
492                         AssertEquals (1, element.ChildNodes.Count);
493                         element.RemoveChild (element2);
494                         Assert (eventStrings.Contains ("NodeRemoving, Remove, <bar />, foo, <none>"));
495                         AssertEquals (0, element.ChildNodes.Count);
496
497 /*
498  * TODO:  put this test back in when AttributeCollection.RemoveAll() is implemented.
499
500                         // RemoveAll.
501                         element = document.CreateElement ("foo");
502                         element2 = document.CreateElement ("bar");
503                         element.AppendChild(element2);
504                         AssertEquals(1, element.ChildNodes.Count);
505                         element.RemoveAll();
506                         Assert (eventStrings.Contains ("NodeRemoving, Remove, <bar />, foo, <none>"));
507                         AssertEquals(0, element.ChildNodes.Count);
508 */
509
510                         // Removing 'bar' element from 'foo' inside document.
511                         element = document.CreateElement ("foo");
512                         document.AppendChild (element);
513                         element = document.CreateElement ("bar");
514                         document.DocumentElement.AppendChild (element);
515                         AssertEquals (1, document.DocumentElement.ChildNodes.Count);
516                         document.DocumentElement.RemoveChild (element);
517                         Assert (eventStrings.Contains ("NodeRemoving, Remove, <bar />, foo, <none>"));
518                         AssertEquals (0, document.DocumentElement.ChildNodes.Count);
519
520                         // If an exception is thrown the Document returns to original state.
521                         document.NodeRemoving += new XmlNodeChangedEventHandler (this.EventNodeRemovingException);
522                         element.AppendChild (element2);
523                         AssertEquals (1, element.ChildNodes.Count);
524                         try 
525                         {
526                                 element.RemoveChild(element2);
527                                 Fail ("Expected an exception to be thrown by the NodeRemoving event handler method EventNodeRemovingException().");
528                         } 
529                         catch (Exception) {}
530                         AssertEquals (1, element.ChildNodes.Count);
531                 }
532
533                 public void TestGetElementsByTagNameNoNameSpace ()
534                 {
535                         string xml = @"<library><book><title>XML Fun</title><author>John Doe</author>
536                                 <price>34.95</price></book><book><title>Bear and the Dragon</title>
537                                 <author>Tom Clancy</author><price>6.95</price></book><book>
538                                 <title>Bourne Identity</title><author>Robert Ludlum</author>
539                                 <price>9.95</price></book><Fluffer><Nutter><book>
540                                 <title>Bourne Ultimatum</title><author>Robert Ludlum</author>
541                                 <price>9.95</price></book></Nutter></Fluffer></library>";
542
543                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml));
544                         document = new XmlDocument ();
545                         document.Load (memoryStream);
546                         XmlNodeList bookList = document.GetElementsByTagName ("book");
547                         AssertEquals ("GetElementsByTagName (string) returned incorrect count.", 4, bookList.Count);
548                 }
549
550                 public void TestGetElementsByTagNameUsingNameSpace ()
551                 {
552                         StringBuilder xml = new StringBuilder ();
553                         xml.Append ("<?xml version=\"1.0\" ?><library xmlns:North=\"http://www.foo.com\"");
554                         xml.Append ("xmlns:South=\"http://www.goo.com\"><North:book type=\"non-fiction\"> ");
555                         xml.Append ("<North:title type=\"intro\">XML Fun</North:title> " );
556                         xml.Append ("<North:author>John Doe</North:author> " );
557                         xml.Append ("<North:price>34.95</North:price></North:book> " );
558                         xml.Append ("<South:book type=\"fiction\"> " );
559                         xml.Append ("<South:title>Bear and the Dragon</South:title> " );
560                         xml.Append ("<South:author>Tom Clancy</South:author> " );
561                         xml.Append ("<South:price>6.95</South:price></South:book> " );
562                         xml.Append ("<South:book type=\"fiction\"><South:title>Bourne Identity</South:title> " );
563                         xml.Append ("<South:author>Robert Ludlum</South:author> " );
564                         xml.Append ("<South:price>9.95</South:price></South:book></library>");
565
566                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml.ToString ()));
567                         document = new XmlDocument ();
568                         document.Load (memoryStream);
569                         XmlNodeList bookList = document.GetElementsByTagName ("book", "http://www.goo.com");
570                         AssertEquals ("GetElementsByTagName (string, uri) returned incorrect count.", 2, bookList.Count);
571                 }
572
573         
574                 public void TestInnerAndOuterXml ()
575                 {
576                         AssertEquals (String.Empty, document.InnerXml);
577                         AssertEquals (document.InnerXml, document.OuterXml);
578
579                         XmlDeclaration declaration = document.CreateXmlDeclaration ("1.0", null, null);
580                         document.AppendChild (declaration);
581                         AssertEquals ("<?xml version=\"1.0\"?>", document.InnerXml);
582                         AssertEquals (document.InnerXml, document.OuterXml);
583
584                         XmlElement element = document.CreateElement ("foo");
585                         document.AppendChild (element);
586                         AssertEquals ("<?xml version=\"1.0\"?><foo />", document.InnerXml);
587                         AssertEquals (document.InnerXml, document.OuterXml);
588
589                         XmlComment comment = document.CreateComment ("bar");
590                         document.DocumentElement.AppendChild (comment);
591                         AssertEquals ("<?xml version=\"1.0\"?><foo><!--bar--></foo>", document.InnerXml);
592                         AssertEquals (document.InnerXml, document.OuterXml);
593
594                         XmlText text = document.CreateTextNode ("baz");
595                         document.DocumentElement.AppendChild (text);
596                         AssertEquals ("<?xml version=\"1.0\"?><foo><!--bar-->baz</foo>", document.InnerXml);
597                         AssertEquals (document.InnerXml, document.OuterXml);
598
599                         element = document.CreateElement ("quux");
600                         element.SetAttribute ("quuux", "squonk");
601                         document.DocumentElement.AppendChild (element);
602                         AssertEquals ("<?xml version=\"1.0\"?><foo><!--bar-->baz<quux quuux=\"squonk\" /></foo>", document.InnerXml);
603                         AssertEquals (document.InnerXml, document.OuterXml);
604                 }
605
606                 public void TestLoadWithSystemIOStream ()
607                 {                       
608                         string xml = @"<library><book><title>XML Fun</title><author>John Doe</author>
609                                 <price>34.95</price></book><book><title>Bear and the Dragon</title>
610                                 <author>Tom Clancy</author><price>6.95</price></book><book>
611                                 <title>Bourne Identity</title><author>Robert Ludlum</author>
612                                 <price>9.95</price></book><Fluffer><Nutter><book>
613                                 <title>Bourne Ultimatum</title><author>Robert Ludlum</author>
614                                 <price>9.95</price></book></Nutter></Fluffer></library>";
615
616                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml));
617                         document = new XmlDocument ();
618                         document.Load (memoryStream);
619                         AssertEquals ("Not Loaded From IOStream", true, document.HasChildNodes);
620                 }
621
622                 public void TestLoadXmlCDATA ()
623                 {
624                         document.LoadXml ("<foo><![CDATA[bar]]></foo>");
625                         Assert (document.DocumentElement.FirstChild.NodeType == XmlNodeType.CDATA);
626                         AssertEquals ("bar", document.DocumentElement.FirstChild.Value);
627                 }
628
629                 public void TestLoadXMLComment()
630                 {
631 // XmlTextReader needs to throw this exception
632 //                      try {
633 //                              document.LoadXml("<!--foo-->");
634 //                              Fail("XmlException should have been thrown.");
635 //                      }
636 //                      catch (XmlException e) {
637 //                              AssertEquals("Exception message doesn't match.", "The root element is missing.", e.Message);
638 //                      }
639
640                         document.LoadXml ("<foo><!--Comment--></foo>");
641                         Assert (document.DocumentElement.FirstChild.NodeType == XmlNodeType.Comment);
642                         AssertEquals ("Comment", document.DocumentElement.FirstChild.Value);
643
644                         document.LoadXml (@"<foo><!--bar--></foo>");
645                         AssertEquals ("Incorrect target.", "bar", ((XmlComment)document.FirstChild.FirstChild).Data);
646                 }
647
648                 public void TestLoadXmlElementSingle ()
649                 {
650                         AssertNull (document.DocumentElement);
651                         document.LoadXml ("<foo/>");
652
653                         AssertNotNull (document.DocumentElement);
654                         AssertSame (document.FirstChild, document.DocumentElement);
655
656                         AssertEquals (String.Empty, document.DocumentElement.Prefix);
657                         AssertEquals ("foo", document.DocumentElement.LocalName);
658                         AssertEquals (String.Empty, document.DocumentElement.NamespaceURI);
659                         AssertEquals ("foo", document.DocumentElement.Name);
660                 }
661
662                 public void TestLoadXmlElementWithAttributes ()
663                 {
664                         AssertNull (document.DocumentElement);
665                         document.LoadXml ("<foo bar='baz' quux='quuux'/>");
666
667                         XmlElement documentElement = document.DocumentElement;
668
669                         AssertEquals ("baz", documentElement.GetAttribute ("bar"));
670                         AssertEquals ("quuux", documentElement.GetAttribute ("quux"));
671                 }
672                 public void TestLoadXmlElementWithChildElement ()
673                 {
674                         document.LoadXml ("<foo><bar/></foo>");
675                         Assert (document.ChildNodes.Count == 1);
676                         Assert (document.FirstChild.ChildNodes.Count == 1);
677                         AssertEquals ("foo", document.DocumentElement.LocalName);
678                         AssertEquals ("bar", document.DocumentElement.FirstChild.LocalName);
679                 }
680
681                 public void TestLoadXmlElementWithTextNode ()
682                 {
683                         document.LoadXml ("<foo>bar</foo>");
684                         Assert (document.DocumentElement.FirstChild.NodeType == XmlNodeType.Text);
685                         AssertEquals ("bar", document.DocumentElement.FirstChild.Value);
686                 }
687
688                 public void TestLoadXmlExceptionClearsDocument ()
689                 {
690                         document.LoadXml ("<foo/>");
691                         Assert (document.FirstChild != null);
692                         
693                         try {
694                                 document.LoadXml ("<123/>");
695                                 Fail ("An XmlException should have been thrown.");
696                         } catch (XmlException) {}
697
698                         Assert (document.FirstChild == null);
699                 }
700
701                 public void TestLoadXmlProcessingInstruction ()
702                 {
703                         document.LoadXml (@"<?foo bar='baaz' quux='quuux'?><quuuux></quuuux>");
704                         AssertEquals ("Incorrect target.", "foo", ((XmlProcessingInstruction)document.FirstChild).Target);
705                         AssertEquals ("Incorrect data.", "bar='baaz' quux='quuux'", ((XmlProcessingInstruction)document.FirstChild).Data);
706                 }
707
708                 public void TestOuterXml ()
709                 {
710                         string xml;
711                         
712                         xml = "<root><![CDATA[foo]]></root>";
713                         document.LoadXml (xml);
714                         AssertEquals("XmlDocument with cdata OuterXml is incorrect.", xml, document.OuterXml);
715
716                         xml = "<root><!--foo--></root>";
717                         document.LoadXml (xml);
718                         AssertEquals("XmlDocument with comment OuterXml is incorrect.", xml, document.OuterXml);
719
720                         xml = "<root><?foo bar?></root>";
721                         document.LoadXml (xml);
722                         AssertEquals("XmlDocument with processing instruction OuterXml is incorrect.", xml, document.OuterXml);
723                 }
724
725                 public void TestParentNodes ()
726                 {
727                         document.LoadXml ("<foo><bar><baz/></bar></foo>");
728                         XmlNode node = document.FirstChild.FirstChild.FirstChild;
729                         AssertEquals ("Wrong child found.", "baz", node.LocalName);
730                         AssertEquals ("Wrong parent.", "bar", node.ParentNode.LocalName);
731                         AssertEquals ("Wrong parent.", "foo", node.ParentNode.ParentNode.LocalName);
732                         AssertEquals ("Wrong parent.", "#document", node.ParentNode.ParentNode.ParentNode.LocalName);
733                         AssertNull ("Expected parent to be null.", node.ParentNode.ParentNode.ParentNode.ParentNode);
734                 }
735
736                 public void TestRemovedElementNextSibling ()
737                 {
738                         XmlNode node;
739                         XmlNode nextSibling;
740
741                         document.LoadXml ("<foo><child1/><child2/></foo>");
742                         node = document.DocumentElement.FirstChild;
743                         document.DocumentElement.RemoveChild (node);
744                         nextSibling = node.NextSibling;
745                         AssertNull ("Expected removed node's next sibling to be null.", nextSibling);
746                 }
747         }
748 }