2009-06-12 Bill Holmes <billholmes54@gmail.com>
[mono.git] / mcs / class / System.XML / Test / System.Xml / XmlElementTests.cs
1 //
2 // XmlElementTests
3 //
4 // Authors:
5 //   Jason Diamond (jason@injektilo.org)
6 //   Martin Willemoes Hansen (mwh@sysrq.dk)
7 //
8 // (C) 2002 Jason Diamond  http://injektilo.org/
9 // (C) 2003 Martin Willemoes Hansen 
10 //
11
12 using System;
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         [TestFixture]
22         public class XmlElementTests  : Assertion
23         {
24                 private XmlDocument document;
25
26                 [SetUp]
27                 public void GetReady ()
28                 {
29                         document = new XmlDocument ();
30                 }
31
32                 private void AssertElement (XmlElement element, string prefix,
33                                             string localName, string namespaceURI,
34                                             int attributesCount)
35                 {
36                         AssertEquals (prefix != String.Empty ? prefix + ":" + localName : localName, element.Name);
37                         AssertEquals (prefix, element.Prefix);
38                         AssertEquals (localName, element.LocalName);
39                         AssertEquals (namespaceURI, element.NamespaceURI);
40                         //AssertEquals (attributesCount, element.Attributes.Count);
41                 }
42
43                 // for NodeInserted Event
44                 private bool Inserted = false;
45                 private void OnNodeInserted (object o, XmlNodeChangedEventArgs e)
46                 {
47                         Inserted = true;
48                 }
49
50                 // for NodeChanged Event
51                 private bool Changed = false;
52                 private void OnNodeChanged (object o, XmlNodeChangedEventArgs e)
53                 {
54                         Changed = true;
55                 }
56
57                 // for NodeRemoved Event
58                 private bool Removed = false;
59                 private void OnNodeRemoved (object o, XmlNodeChangedEventArgs e)
60                 {
61                         Removed = true;
62                 }
63
64                 [Test]
65                 public void CloneNode ()
66                 {
67                         XmlElement element = document.CreateElement ("foo");
68                         XmlElement child = document.CreateElement ("bar");
69                         XmlElement grandson = document.CreateElement ("baz");
70
71                         element.SetAttribute ("attr1", "val1");
72                         element.SetAttribute ("attr2", "val2");
73                         element.AppendChild (child);
74                         child.SetAttribute ("attr3", "val3");
75                         child.AppendChild (grandson);
76                         
77                         document.AppendChild (element);
78                         XmlNode deep = element.CloneNode (true);
79                         // AssertEquals ("These should be the same", deep.OuterXml, element.OuterXml); 
80                         AssertNull ("This is not null", deep.ParentNode);
81                         Assert ("Copies, not pointers", !Object.ReferenceEquals (element,deep));
82
83                         XmlNode shallow = element.CloneNode (false);
84                         AssertNull ("This is not null", shallow.ParentNode);
85                         Assert ("Copies, not pointers", !Object.ReferenceEquals (element,shallow));
86                         AssertEquals ("Shallow clones shalt have no children!", false, shallow.HasChildNodes);
87                 }
88
89                 [Test]
90                 public void ConstructionAndDefaultAttributes ()
91                 {
92                         string dtd = "<!DOCTYPE root [<!ELEMENT root EMPTY><!ATTLIST root foo CDATA 'def'>]>";
93                         string xml = dtd + "<root />";
94 //                      XmlValidatingReader xvr = new XmlValidatingReader (new XmlTextReader (xml, XmlNodeType.Document, null));
95                         XmlDocument doc = new XmlDocument ();
96                         doc.LoadXml (xml);
97                         Console.WriteLine (doc.DocumentElement.Attributes.Count);
98                         Console.WriteLine (doc.CreateElement ("root").Attributes.Count);
99                         Console.WriteLine (doc.CreateElement ("root2").Attributes.Count);
100                 }
101
102                 [Test]
103                 public void CreateElement1 ()
104                 {
105                         XmlElement element = document.CreateElement ("name");
106                         AssertElement (element, String.Empty, "name", String.Empty, 0);
107                 }
108
109                 [Test]
110                 public void CreateElement1WithPrefix ()
111                 {
112                         XmlElement element = document.CreateElement ("prefix:localName");
113                         AssertElement (element, "prefix", "localName", String.Empty, 0);
114                 }
115
116                 [Test]
117                 public void CreateElement2 ()
118                 {
119                         XmlElement element = document.CreateElement ("qualifiedName", "namespaceURI");
120                         AssertElement (element, String.Empty, "qualifiedName",
121                                        "namespaceURI", 0);
122                 }
123
124                 [Test]
125                 public void CreateElement2WithPrefix ()
126                 {
127                         XmlElement element = document.CreateElement ("prefix:localName", "namespaceURI");
128                         AssertElement (element, "prefix", "localName", "namespaceURI", 0);
129                 }
130
131                 [Test]
132                 public void CreateElement3 ()
133                 {
134                         XmlElement element = document.CreateElement ("prefix", "localName", "namespaceURI");
135                         AssertElement (element, "prefix", "localName", "namespaceURI", 0);
136                 }
137
138                 [Test]
139                 public void CreateElement3WithNullNamespace ()
140                 {
141                         // bug #26855, NamespaceURI should NEVER be null.
142                         XmlElement element = document.CreateElement (null, "localName", null);
143                         AssertElement (element, String.Empty, "localName", String.Empty, 0);
144                 }
145
146                 [Test]
147                 public void InnerAndOuterXml ()
148                 {
149                         XmlElement element;
150                         XmlText text;
151                         XmlComment comment;
152                         
153                         element = document.CreateElement ("foo");
154                         AssertEquals (String.Empty, element.InnerXml);
155                         AssertEquals ("<foo />", element.OuterXml);
156
157                         text = document.CreateTextNode ("bar");
158                         element.AppendChild (text);
159                         AssertEquals ("bar", element.InnerXml);
160                         AssertEquals ("<foo>bar</foo>", element.OuterXml);
161
162                         element.SetAttribute ("baz", "quux");
163                         AssertEquals ("bar", element.InnerXml);
164                         AssertEquals ("<foo baz=\"quux\">bar</foo>", element.OuterXml);
165
166                         comment = document.CreateComment ("squonk");
167                         element.AppendChild (comment);
168                         AssertEquals ("bar<!--squonk-->", element.InnerXml);
169                         AssertEquals ("<foo baz=\"quux\">bar<!--squonk--></foo>", element.OuterXml);
170
171                         element.RemoveAll();
172                         element.AppendChild(document.CreateElement("hoge"));
173                         AssertEquals ("<hoge />", element.InnerXml);
174                 }
175
176                 [Test]
177                 public void SetGetAttribute ()
178                 {
179                         XmlElement element = document.CreateElement ("foo");
180                         element.SetAttribute ("attr1", "val1");
181                         element.SetAttribute ("attr2", "val2");
182                         AssertEquals ("val1", element.GetAttribute ("attr1"));
183                         AssertEquals ("val2", element.GetAttribute ("attr2"));
184                 }
185
186                 [Test]
187                 public void GetElementsByTagNameNoNameSpace ()
188                 {
189                         string xml = @"<library><book><title>XML Fun</title><author>John Doe</author>
190                                 <price>34.95</price></book><book><title>Bear and the Dragon</title>
191                                 <author>Tom Clancy</author><price>6.95</price></book><book>
192                                 <title>Bourne Identity</title><author>Robert Ludlum</author>
193                                 <price>9.95</price></book><Fluffer><Nutter><book>
194                                 <title>Bourne Ultimatum</title><author>Robert Ludlum</author>
195                                 <price>9.95</price></book></Nutter></Fluffer></library>";
196
197                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml));
198                         document = new XmlDocument ();
199                         document.Load (memoryStream);
200                         XmlNodeList libraryList = document.GetElementsByTagName ("library");
201                         XmlNode xmlNode = libraryList.Item (0);
202                         XmlElement xmlElement = xmlNode as XmlElement;
203                         XmlNodeList bookList = xmlElement.GetElementsByTagName ("book");
204                         AssertEquals ("GetElementsByTagName (string) returned incorrect count.", 4, bookList.Count);
205                 }
206
207                 [Test]
208                 public void GetElementsByTagNameUsingNameSpace ()
209                 {
210                         StringBuilder xml = new StringBuilder ();
211                         xml.Append ("<?xml version=\"1.0\" ?><library xmlns:North=\"http://www.foo.com\" ");
212                         xml.Append ("xmlns:South=\"http://www.goo.com\"><North:book type=\"non-fiction\"> ");
213                         xml.Append ("<North:title type=\"intro\">XML Fun</North:title> " );
214                         xml.Append ("<North:author>John Doe</North:author> " );
215                         xml.Append ("<North:price>34.95</North:price></North:book> " );
216                         xml.Append ("<South:book type=\"fiction\"> " );
217                         xml.Append ("<South:title>Bear and the Dragon</South:title> " );
218                         xml.Append ("<South:author>Tom Clancy</South:author> " );
219                         xml.Append ("<South:price>6.95</South:price></South:book> " );
220                         xml.Append ("<South:book type=\"fiction\"><South:title>Bourne Identity</South:title> " );
221                         xml.Append ("<South:author>Robert Ludlum</South:author> " );
222                         xml.Append ("<South:price>9.95</South:price></South:book></library>");
223
224                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml.ToString ()));
225                         document = new XmlDocument ();
226                         document.Load (memoryStream);
227                         XmlNodeList libraryList = document.GetElementsByTagName ("library");
228                         XmlNode xmlNode = libraryList.Item (0);
229                         XmlElement xmlElement = xmlNode as XmlElement;
230                         XmlNodeList bookList = xmlElement.GetElementsByTagName ("book", "http://www.foo.com");
231                         AssertEquals ("GetElementsByTagName (string, uri) returned incorrect count.", 1, bookList.Count);
232                 }
233
234                 [Test]
235                 public void GetElementsByTagNameNs2 ()
236                 {
237                         document.LoadXml (@"<root>
238                         <x:a xmlns:x='urn:foo' id='a'>
239                         <y:a xmlns:y='urn:foo' id='b'/>
240                         <x:a id='c' />
241                         <z id='d' />
242                         text node
243                         <?a processing instruction ?>
244                         <x:w id='e'/>
245                         </x:a>
246                         </root>");
247                         // id='b' has different prefix. Should not caught by (name),
248                         // while should caught by (name, ns).
249                         XmlNodeList nl = document.DocumentElement.GetElementsByTagName ("x:a");
250                         AssertEquals (2, nl.Count);
251                         AssertEquals ("a", nl [0].Attributes ["id"].Value);
252                         AssertEquals ("c", nl [1].Attributes ["id"].Value);
253
254                         nl = document.DocumentElement.GetElementsByTagName ("a", "urn:foo");
255                         AssertEquals (3, nl.Count);
256                         AssertEquals ("a", nl [0].Attributes ["id"].Value);
257                         AssertEquals ("b", nl [1].Attributes ["id"].Value);
258                         AssertEquals ("c", nl [2].Attributes ["id"].Value);
259
260                         // name wildcard
261                         nl = document.DocumentElement.GetElementsByTagName ("*");
262                         AssertEquals (5, nl.Count);
263                         AssertEquals ("a", nl [0].Attributes ["id"].Value);
264                         AssertEquals ("b", nl [1].Attributes ["id"].Value);
265                         AssertEquals ("c", nl [2].Attributes ["id"].Value);
266                         AssertEquals ("d", nl [3].Attributes ["id"].Value);
267                         AssertEquals ("e", nl [4].Attributes ["id"].Value);
268
269                         // wildcard - local and ns
270                         nl = document.DocumentElement.GetElementsByTagName ("*", "*");
271                         AssertEquals (5, nl.Count);
272                         AssertEquals ("a", nl [0].Attributes ["id"].Value);
273                         AssertEquals ("b", nl [1].Attributes ["id"].Value);
274                         AssertEquals ("c", nl [2].Attributes ["id"].Value);
275                         AssertEquals ("d", nl [3].Attributes ["id"].Value);
276                         AssertEquals ("e", nl [4].Attributes ["id"].Value);
277
278                         // namespace wildcard - namespace
279                         nl = document.DocumentElement.GetElementsByTagName ("*", "urn:foo");
280                         AssertEquals (4, nl.Count);
281                         AssertEquals ("a", nl [0].Attributes ["id"].Value);
282                         AssertEquals ("b", nl [1].Attributes ["id"].Value);
283                         AssertEquals ("c", nl [2].Attributes ["id"].Value);
284                         AssertEquals ("e", nl [3].Attributes ["id"].Value);
285
286                         // namespace wildcard - local only. I dare say, such usage is not XML-ish!
287                         nl = document.DocumentElement.GetElementsByTagName ("a", "*");
288                         AssertEquals (3, nl.Count);
289                         AssertEquals ("a", nl [0].Attributes ["id"].Value);
290                         AssertEquals ("b", nl [1].Attributes ["id"].Value);
291                         AssertEquals ("c", nl [2].Attributes ["id"].Value);
292                 }
293
294                 [Test]
295                 public void OuterXmlWithNamespace ()
296                 {
297                         XmlElement element = document.CreateElement ("foo", "bar", "#foo");
298                         AssertEquals ("<foo:bar xmlns:foo=\"#foo\" />", element.OuterXml);
299                 }               
300
301                 [Test]
302                 public void RemoveAllAttributes ()
303                 {
304                         StringBuilder xml = new StringBuilder ();
305                         xml.Append ("<?xml version=\"1.0\" ?><library><book type=\"non-fiction\" price=\"34.95\"> ");
306                         xml.Append ("<title type=\"intro\">XML Fun</title> " );
307                         xml.Append ("<author>John Doe</author></book></library>");
308
309                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml.ToString ()));
310                         document = new XmlDocument ();
311                         document.Load (memoryStream);
312                         XmlNodeList bookList = document.GetElementsByTagName ("book");
313                         XmlNode xmlNode = bookList.Item (0);
314                         XmlElement xmlElement = xmlNode as XmlElement;
315                         xmlElement.RemoveAllAttributes ();
316                         AssertEquals ("attributes not properly removed.", false, xmlElement.HasAttribute ("type"));
317                 }
318
319                 [Test]
320 #if NET_2_0
321                 [Ignore ("This test is very implementation dependent and thus .NET 2.0 does not pass. That's why I said http://primates.ximian.com/~atsushi/blog/archives/000416.html and http://svn.myrealbox.com/viewcvs/trunk/mono/web/xml-classes?rev=23598")]
322 #endif
323                 public void RemoveDoesNotRemoveDefaultAttributes ()
324                 {
325                         string dtd = "<!DOCTYPE root [<!ELEMENT root EMPTY><!ATTLIST root   foo CDATA 'def'   bar CDATA #IMPLIED>]>";
326                         string xml = dtd + "<root bar='baz' />";
327                         XmlValidatingReader xvr = new XmlValidatingReader (xml, XmlNodeType.Document, null);
328                         document.Load (xvr);
329                         // RemoveAll
330                         AssertNotNull (document.DocumentElement);
331                         AssertEquals ("attrCount #01", 2, document.DocumentElement.Attributes.Count);
332                         AssertEquals ("baz", document.DocumentElement.GetAttribute ("bar"));
333                         AssertEquals ("def", document.DocumentElement.GetAttribute ("foo"));
334                         AssertEquals (false, document.DocumentElement.GetAttributeNode ("foo").Specified);
335                         document.DocumentElement.RemoveAll ();
336                         AssertEquals ("attrCount #02", 1, document.DocumentElement.Attributes.Count);
337                         AssertEquals ("def", document.DocumentElement.GetAttribute ("foo"));
338                         AssertEquals (String.Empty, document.DocumentElement.GetAttribute ("bar"));
339
340                         // RemoveAllAttributes
341                         xvr = new XmlValidatingReader (xml, XmlNodeType.Document, null);
342                         document.Load (xvr);
343                         document.DocumentElement.RemoveAllAttributes ();
344                         AssertEquals ("attrCount #03", 1, document.DocumentElement.Attributes.Count);
345
346                         // RemoveAttribute(name)
347                         xvr = new XmlValidatingReader (xml, XmlNodeType.Document, null);
348                         document.Load (xvr);
349                         document.DocumentElement.RemoveAttribute ("foo");
350                         AssertEquals ("attrCount #04", 2, document.DocumentElement.Attributes.Count);
351
352                         // RemoveAttribute(name, ns)
353                         xvr = new XmlValidatingReader (xml, XmlNodeType.Document, null);
354                         document.Load (xvr);
355                         document.DocumentElement.RemoveAttribute ("foo", String.Empty);
356                         AssertEquals ("attrCount #05", 2, document.DocumentElement.Attributes.Count);
357
358                         // RemoveAttributeAt
359                         xvr = new XmlValidatingReader (xml, XmlNodeType.Document, null);
360                         document.Load (xvr);
361                         document.DocumentElement.RemoveAttributeAt (1);
362                         AssertEquals ("attrCount #06", 2, document.DocumentElement.Attributes.Count);
363
364                         // RemoveAttributeNode
365                         xvr = new XmlValidatingReader (xml, XmlNodeType.Document, null);
366                         document.Load (xvr);
367                         document.DocumentElement.RemoveAttributeNode (document.DocumentElement.Attributes [1]);
368                         AssertEquals ("attrCount #07", 2, document.DocumentElement.Attributes.Count);
369
370                         // RemoveAttributeNode(name, ns)
371                         xvr = new XmlValidatingReader (xml, XmlNodeType.Document, null);
372                         document.Load (xvr);
373                         document.DocumentElement.RemoveAttributeNode ("foo", String.Empty);
374                         AssertEquals ("attrCount #08", 2, document.DocumentElement.Attributes.Count);
375                 }
376
377                 [Test]
378                 public void SetAttributeNode ()
379                 {
380                         XmlDocument xmlDoc = new XmlDocument ();
381                         XmlElement xmlEl = xmlDoc.CreateElement ("TestElement");
382                         XmlAttribute xmlAttribute = xmlEl.SetAttributeNode ("attr1", "namespace1");
383                         XmlAttribute xmlAttribute2 = xmlEl.SetAttributeNode ("attr2", "namespace2");
384                         AssertEquals ("attribute name not properly created.", true, xmlAttribute.Name.Equals ("attr1"));
385                         AssertEquals ("attribute namespace not properly created.", true, xmlAttribute.NamespaceURI.Equals ("namespace1"));
386                 }
387
388                 [Test]
389                 [ExpectedException (typeof (XmlException))]
390                 public void SetAttributeNodeError ()
391                 {
392                         XmlDocument doc = new XmlDocument ();
393                         doc.LoadXml ("<root xmlns:x='urn:foo'/>");
394                         doc.DocumentElement.SetAttributeNode ("x:lang", "urn:foo");
395                 }
396
397                 [Test]
398                 public void SetAttributeXmlns ()
399                 {
400                         // should not affect Element node's xmlns
401                         XmlElement el = document.CreateElement ("root");
402                         el.SetAttribute ("xmlns", "urn:foo");
403                         AssertEquals (String.Empty, el.NamespaceURI);
404                 }
405
406                 [Test]
407                 public void InnerTextAndEvent ()
408                 {
409                         XmlDocument doc = new XmlDocument ();
410                         doc.LoadXml ("<root><child>text</child><child2><![CDATA[cdata]]></child2></root>");
411                         doc.NodeInserted += new XmlNodeChangedEventHandler (
412                                 OnNodeInserted);
413                         doc.NodeRemoved += new XmlNodeChangedEventHandler (
414                                 OnNodeRemoved);
415                         // If only one child of the element is Text node,
416                         // then no events are fired.
417                         doc.DocumentElement.FirstChild.InnerText = "no events fired.";
418                         AssertEquals ("NoInsertEventFired", false, Inserted);
419                         AssertEquals ("NoRemoveEventFired", false, Removed);
420                         AssertEquals ("SetInnerTextToSingleText", "no events fired.", doc.DocumentElement.FirstChild.InnerText);
421                         Inserted = false;
422                         Removed = false;
423
424                         // if only one child of the element is CDataSection,
425                         // then events are fired.
426                         doc.DocumentElement.LastChild.InnerText = "events are fired.";
427                         AssertEquals ("InsertedEventFired", true, Inserted);
428                         AssertEquals ("RemovedEventFired", true, Removed);
429                         AssertEquals ("SetInnerTextToCDataSection", "events are fired.", doc.DocumentElement.LastChild.InnerText);
430                 }
431
432                 [Test]
433                 public void InnerXmlSetter ()
434                 {
435                         XmlDocument doc = new XmlDocument ();
436                         doc.LoadXml ("<root/>");
437                         XmlElement el =  doc.DocumentElement;
438                         AssertNull ("#Simple", el.FirstChild);
439                         el.InnerXml = "<foo><bar att='baz'/></foo>";
440                         XmlElement child = el.FirstChild as XmlElement;
441                         AssertNotNull ("#Simple.Child", child);
442                         AssertEquals ("#Simple.Child.Name", "foo", child.LocalName);
443
444                         XmlElement grandchild = child.FirstChild as XmlElement;
445                         AssertNotNull ("#Simple.GrandChild", grandchild);
446                         AssertEquals ("#Simple.GrandChild.Name", "bar", grandchild.LocalName);
447                         AssertEquals ("#Simple.GrandChild.Attr", "baz", grandchild.GetAttribute ("att"));
448
449                         doc.LoadXml ("<root xmlns='NS0' xmlns:ns1='NS1'><foo/><ns1:bar/><ns2:bar xmlns:ns2='NS2' /></root>");
450                         el = doc.DocumentElement.FirstChild.NextSibling as XmlElement;  // ns1:bar
451                         AssertNull ("#Namespaced.Prepare", el.FirstChild);
452                         el.InnerXml = "<ns1:baz />";
453                         AssertNotNull ("#Namespaced.Child", el.FirstChild);
454                         AssertEquals ("#Namespaced.Child.Name", "baz", el.FirstChild.LocalName);
455                         AssertEquals ("#Namespaced.Child.NSURI", "NS1", el.FirstChild.NamespaceURI);    // important!
456
457                         el.InnerXml = "<hoge />";
458                         AssertEquals ("#Namespaced.VerifyPreviousCleared", "hoge", el.FirstChild.Name);
459                 }
460
461                 [Test]
462                 public void InnerXmlSetter2 ()
463                 {
464                         // See bug #63574
465                         XmlDocument doc = new XmlDocument ();
466                         doc.LoadXml (@"<type>QPair&lt;QString,int&gt;::
467 <ref refid='classQPair'>QPair</ref>
468 &lt;
469 <ref refid='classQString'>QString</ref>
470 ,int&gt;
471 </type>");
472                         XmlElement typeNode = doc.DocumentElement;
473                         typeNode.InnerText = "QPair<QString, int>";
474                         AssertEquals ("QPair<QString, int>", typeNode.InnerText);
475                 }
476
477                 [Test]
478                 public void IsEmpty ()
479                 {
480                         document.LoadXml ("<root><foo/><bar></bar></root>");
481                         Assertion.AssertEquals ("Empty", true, ((XmlElement) document.DocumentElement.FirstChild).IsEmpty);
482                         Assertion.AssertEquals ("Empty", false, ((XmlElement) document.DocumentElement.LastChild).IsEmpty);
483                 }
484
485                 [Test]
486                 public void RemoveAttribute ()
487                 {
488                         string xlinkURI = "http://www.w3.org/1999/XLink";
489                         XmlDocument doc = new XmlDocument ();
490                         doc.LoadXml ("<root a1='1' a2='2' xlink:href='urn:foo' xmlns:xlink='" + xlinkURI + "' />");
491
492                         XmlElement el =  doc.DocumentElement;
493                         el.RemoveAttribute ("a1");
494                         AssertNull ("RemoveAttribute", el.GetAttributeNode ("a1"));
495                         el.RemoveAttribute ("xlink:href");
496                         AssertNull ("RemoveAttribute", el.GetAttributeNode ("href", xlinkURI));
497                         el.RemoveAllAttributes ();
498                         AssertNull ("RemoveAllAttributes", el.GetAttributeNode ("a2"));
499                 }
500
501                 [Test]
502                 public void WriteToWithDefaultNamespace ()
503                 {
504                         XmlDocument doc = new XmlDocument ();
505                         doc.LoadXml ("<RetrievalElement URI=\"\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\" />");
506                         StringWriter sw = new StringWriter ();
507                         XmlTextWriter xtw = new XmlTextWriter (sw);
508                         doc.DocumentElement.WriteTo (xtw);
509                         AssertEquals ("<RetrievalElement URI=\"\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\" />", sw.ToString());
510                 }
511
512                 [Test]
513                 public void WriteToMakesNonsenseForDefaultNSChildren ()
514                 {
515                         XmlDocument d = new XmlDocument ();
516                         XmlElement x = d.CreateElement ("root");
517                         d.AppendChild (x);
518                         XmlElement a = d.CreateElement ("a");
519                         XmlElement b = d.CreateElement ("b");
520                         b.SetAttribute ("xmlns","probe");
521                         x.AppendChild (a);
522                         x.AppendChild (b);
523                         XmlElement b2 = d.CreateElement ("p2", "b2", "");
524                         b.AppendChild (b2);
525                         AssertEquals ("<root><a /><b xmlns=\"probe\"><b2 /></b></root>", d.OuterXml);
526                 }
527
528                 [Test]
529                 public void WriteToWithDeletedNamespacePrefix ()
530                 {
531                         XmlDocument doc = new XmlDocument ();
532                         doc.LoadXml ("<root xmlns:foo='urn:dummy'><foo foo:bar='baz' /></root>");
533                         doc.DocumentElement.RemoveAllAttributes ();
534
535                         Assert (doc.DocumentElement.FirstChild.OuterXml.IndexOf("xmlns:foo") > 0);
536                 }
537
538                 [Test]
539                 public void WriteToWithDifferentNamespaceAttributes ()
540                 {
541                         XmlDocument doc = new XmlDocument ();
542                         doc.LoadXml ("<root xmlns:foo='urn:dummy' xmlns:html='http://www.w3.org/1999/xhtml' html:style='font-size: 1em'></root>");
543                         Assert (doc.OuterXml.IndexOf ("xmlns:html=\"http://www.w3.org/1999/xhtml\"") > 0);
544                 }
545
546                 [Test]
547                 public void WriteToDefaultAttribute ()
548                 {
549                         // default attributes should be ignored.
550
551                         string dtd = "<!DOCTYPE root[<!ATTLIST root hoge CDATA 'hoge-def'><!ENTITY foo 'ent-foo'>]>";
552                         string xml = dtd + "<root>&foo;</root>";
553                         XmlValidatingReader xvr = new XmlValidatingReader (xml, XmlNodeType.Document,null);
554                         xvr.EntityHandling = EntityHandling.ExpandCharEntities;
555                         xvr.ValidationType = ValidationType.None;
556                         document.Load (xvr);
557                         StringWriter sw = new StringWriter ();
558                         XmlTextWriter xtw = new XmlTextWriter (sw);
559                         document.DocumentElement.WriteTo (xtw);
560                         AssertEquals ("<root>&foo;</root>", sw.ToString ());
561                 }
562
563                 [Test]
564 #if ONLY_1_1
565                 [ExpectedException (typeof (ArgumentNullException))]
566 #endif
567                 public void SetNullPrefix ()
568                 {
569                         XmlDocument doc = new XmlDocument ();
570                         doc.LoadXml ("<root/>");
571                         doc.DocumentElement.Prefix = null;
572
573 #if NET_2_0
574                         AssertEquals ("#1", string.Empty, doc.DocumentElement.Prefix);
575                         AssertClearPrefix ((string) null);
576 #endif
577                 }
578
579                 [Test]
580                 public void SetEmptyStringPrefix ()
581                 {
582                         XmlDocument doc = new XmlDocument ();
583                         doc.LoadXml ("<root />");
584                         doc.DocumentElement.Prefix = String.Empty;
585                         AssertEquals ("#1", string.Empty, doc.DocumentElement.Prefix);
586
587                         AssertClearPrefix (string.Empty);
588
589                 }
590
591                 private void AssertClearPrefix (string newPrefix)
592                 {
593                         XmlDocument doc = new XmlDocument ();
594                         doc.LoadXml ("<x:root xmlns:x=\"http://somenamespace.com\" />");
595                         AssertEquals ("#Clear1", "<x:root xmlns:x=\"http://somenamespace.com\" />",
596                                 doc.OuterXml);
597                         AssertEquals ("#Clear2", "<x:root xmlns:x=\"http://somenamespace.com\" />",
598                                 doc.DocumentElement.OuterXml);
599                         AssertEquals ("#Clear3", "x", doc.DocumentElement.Prefix);
600                         doc.DocumentElement.Prefix = newPrefix;
601                         AssertEquals ("#Clear4", "<root xmlns:x=\"http://somenamespace.com\" xmlns=\"http://somenamespace.com\" />",
602                                 doc.OuterXml);
603                         AssertEquals ("#Clear5", "<root xmlns:x=\"http://somenamespace.com\" xmlns=\"http://somenamespace.com\" />",
604                                 doc.DocumentElement.OuterXml);
605                         AssertEquals ("#Clear6", string.Empty, doc.DocumentElement.Prefix);
606                 }
607
608                 [Test]
609                 public void NullPrefix ()
610                 {
611                         new MyXmlElement ("foo", "urn:foo", new XmlDocument ());
612                 }
613
614                 [Test] // bug #380720
615                 public void SetAttributeWithIdentity ()
616                 {
617                         XmlDocument doc = new XmlDocument ();
618                         doc.LoadXml (@"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' []>
619 <html xmlns='http://www.w3.org/1999/xhtml'>
620 <head></head>
621 <body><div id='xxx'>XXX</div><div id='yyy'>YYY</div></body>
622 </html>");
623                         XmlElement xxx = (XmlElement) doc.GetElementsByTagName ("div") [0];
624                         XmlElement yyy = (XmlElement) doc.GetElementsByTagName ("div") [1];
625                         yyy.ParentNode.RemoveChild (yyy);
626                         yyy.SetAttribute ("id", "xxx");
627                 }
628
629                 [Test]
630                 public void SetAttributeExistingNoInsert () // bug #464394
631                 {
632                         XmlDocument doc = new XmlDocument ();
633                         bool changed = false;
634                         doc.LoadXml (@"<MyNode Key='ABC' ClientName='xxx' DateIssued='yyy' />");
635                         doc.NodeChanged += delegate {
636                                 changed = true;
637                         };
638                         doc.DocumentElement.SetAttribute ("Key", "");
639                         Assert (changed);
640                 }
641
642                 class MyXmlElement : XmlElement
643                 {
644                         public MyXmlElement (string localName, string ns, XmlDocument doc)
645                                 : base (null, localName, ns, doc)
646                         {
647                         }
648                 }
649         }
650 }