2 // XmlSimpleDictionaryWriterTest.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
10 // Copied from System.XML/Test/System.Xml/XmlTextWriterTests.cs
13 // Kral Ferch <kral_ferch@hotmail.com>
14 // Martin Willemoes Hansen <mwh@sysrq.dk>
16 // (C) 2002 Kral Ferch
17 // (C) 2003 Martin Willemoes Hansen
21 // Permission is hereby granted, free of charge, to any person obtaining
22 // a copy of this software and associated documentation files (the
23 // "Software"), to deal in the Software without restriction, including
24 // without limitation the rights to use, copy, modify, merge, publish,
25 // distribute, sublicense, and/or sell copies of the Software, and to
26 // permit persons to whom the Software is furnished to do so, subject to
27 // the following conditions:
29 // The above copyright notice and this permission notice shall be
30 // included in all copies or substantial portions of the Software.
32 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
35 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
36 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
37 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
38 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45 using NUnit.Framework;
47 namespace MonoTests.System.Xml
50 public class XmlSimpleDictionaryWriterTest
53 public void WriteXmlnsAttribute ()
55 xw.WriteStartElement ("l1");
56 xw.WriteXmlAttribute ("lang", "ja");
57 xw.WriteXmlnsAttribute ("f", "urn:foo");
58 xw.WriteStartElement ("l2");
59 xw.WriteXmlnsAttribute ("", "");
60 xw.WriteEndElement ();
61 xw.WriteStartElement ("l2");
62 xw.WriteXmlnsAttribute ("", "urn:bar");
63 xw.WriteEndElement ();
64 xw.WriteEndElement ();
66 Assert.AreEqual ("<l1 xml:lang='ja' xmlns:f='urn:foo'><l2 xmlns='' /><l2 xmlns='urn:bar' /></l1>", Output);
70 public void WriteXmlnsAttributeNullPrefix ()
72 xw.WriteStartElement ("root", "urn:x");
73 xw.WriteXmlnsAttribute (null, "urn:foo");
74 xw.WriteEndElement ();
76 Assert.AreEqual ("<root xmlns:d1p1='urn:foo' xmlns='urn:x' />", Output);
79 #region Copied from XmlTextWriterTests.cs
82 XmlDictionaryWriter xw;
85 public void GetReady ()
87 sw = new StringWriter ();
88 XmlTextWriter xtw = new XmlTextWriter (sw);
90 xw = XmlDictionaryWriter.CreateDictionaryWriter (xtw);
95 get { return sw.ToString (); }
99 public void AttributeNamespacesNonNamespaceAttributeBefore ()
101 xw.WriteStartElement ("foo");
102 xw.WriteAttributeString("bar", "baz");
103 xw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
104 Assert.AreEqual ("<foo bar='baz' xmlns:abc='http://abc.def'", Output);
108 public void AttributeNamespacesNonNamespaceAttributeAfter ()
110 xw.WriteStartElement ("foo");
112 xw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
113 xw.WriteAttributeString("bar", "baz");
114 Assert.AreEqual ("<foo xmlns:abc='http://abc.def' bar='baz'", Output);
118 public void AttributeNamespacesThreeParamWithNullInNamespaceParam ()
120 xw.WriteAttributeString ("xmlns", null, "http://abc.def");
121 Assert.AreEqual ("xmlns='http://abc.def'", Output);
125 public void AttributeNamespacesThreeParamWithTextInNamespaceParam ()
129 xw.WriteAttributeString ("xmlns", "http://somenamespace.com", "http://abc.def");
131 catch (ArgumentException) {}
135 public void AttributeNamespacesWithNullInNamespaceParam ()
137 xw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
138 Assert.AreEqual ("xmlns:abc='http://abc.def'", Output);
142 public void AttributeNamespacesWithTextInNamespaceParam ()
145 xw.WriteAttributeString ("xmlns", "abc", "http://somenamespace.com", "http://abc.def");
146 } catch (ArgumentException) {}
150 public void AttributeNamespacesXmlnsXmlns ()
152 xw.WriteStartElement ("foo");
153 // When namespaceURI argument is null, constraints by
154 // namespaces in XML are ignored.
155 xw.WriteAttributeString ("xmlns", "xmlns", null, "http://abc.def");
156 xw.WriteAttributeString ("", "xmlns", null, "http://abc.def");
160 public void AttributeWriteAttributeString ()
162 xw.WriteStartElement ("foo");
164 xw.WriteAttributeString ("foo", "bar");
165 Assert.AreEqual ("<foo foo='bar'", Output);
167 xw.WriteAttributeString ("bar", "");
168 Assert.AreEqual ("<foo foo='bar' bar=''", Output);
170 xw.WriteAttributeString ("baz", null);
171 Assert.AreEqual ("<foo foo='bar' bar='' baz=''", Output);
173 xw.WriteAttributeString ("hoge", "a\nb");
174 Assert.AreEqual ("<foo foo='bar' bar='' baz='' hoge='a
b'", Output);
176 xw.WriteAttributeString ("fuga", " a\t\r\nb\t");
177 Assert.AreEqual ("<foo foo='bar' bar='' baz='' hoge='a
b' fuga=' a\t
b\t'", Output);
180 // Why does this pass Microsoft?
181 // Anyway, Mono should not allow such code.
182 xw.WriteAttributeString ("", "quux");
183 // Assert.AreEqual ("<foo foo='bar' bar='' baz='' ='quux'", Output);
184 Assert.Fail ("empty name not allowed.");
185 } catch (Exception) {
189 // Why does this pass Microsoft?
190 // Anyway, Mono should not allow such code.
191 xw.WriteAttributeString (null, "quuux");
192 // Assert.AreEqual ("<foo foo='bar' bar='' baz='' ='quux' ='quuux'", Output);
193 Assert.Fail ("null name not allowed.");
194 } catch (Exception) {
199 [ExpectedException (typeof (InvalidOperationException))]
200 public void AttributeWriteAttributeStringNotInsideOpenStartElement ()
202 xw.WriteStartElement ("foo");
203 xw.WriteString ("bar");
205 xw.WriteAttributeString ("baz", "quux");
209 public void AttributeWriteAttributeStringWithoutParentElement ()
211 xw.WriteAttributeString ("foo", "bar");
212 Assert.AreEqual ("foo='bar'", Output);
214 xw.WriteAttributeString ("baz", "quux");
215 Assert.AreEqual ("foo='bar' baz='quux'", Output);
219 public void CDataValid ()
221 xw.WriteCData ("foo");
222 Assert.AreEqual ("<![CDATA[foo]]>", Output,
223 "WriteCData had incorrect output.");
227 [ExpectedException (typeof (ArgumentException))]
228 public void CDataInvalid ()
230 xw.WriteCData("foo]]>bar");
234 public void CloseOpenElements ()
236 xw.WriteStartElement("foo");
237 xw.WriteStartElement("bar");
238 xw.WriteStartElement("baz");
240 Assert.AreEqual ("<foo><bar><baz /></bar></foo>", Output,
241 "Close didn't write out end elements properly.");
245 public void CloseWriteAfter ()
247 xw.WriteElementString ("foo", "bar");
250 // WriteEndElement and WriteStartDocument aren't tested here because
251 // they will always throw different exceptions besides 'The Writer is closed.'
252 // and there are already tests for those exceptions.
255 xw.WriteCData ("foo");
256 Assert.Fail ("WriteCData after Close Should have thrown an InvalidOperationException.");
258 catch (InvalidOperationException) {
259 // Don't rely on English message assertion.
260 // It is enough to check an exception occurs.
261 // Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
265 xw.WriteComment ("foo");
266 Assert.Fail ("WriteComment after Close Should have thrown an InvalidOperationException.");
268 catch (InvalidOperationException) {
269 // Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
273 xw.WriteProcessingInstruction ("foo", "bar");
274 Assert.Fail ("WriteProcessingInstruction after Close Should have thrown an InvalidOperationException.");
276 catch (InvalidOperationException) {
277 // Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
281 xw.WriteStartElement ("foo", "bar", "baz");
282 Assert.Fail ("WriteStartElement after Close Should have thrown an InvalidOperationException.");
284 catch (InvalidOperationException) {
285 // Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
290 xw.WriteAttributeString ("foo", "bar");
291 Assert.Fail ("WriteAttributeString after Close Should have thrown an InvalidOperationException.");
293 catch (InvalidOperationException)
295 // Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
299 xw.WriteString ("foo");
300 Assert.Fail ("WriteString after Close Should have thrown an InvalidOperationException.");
302 catch (InvalidOperationException) {
303 // Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
308 public void CommentValid ()
310 xw.WriteComment ("foo");
311 Assert.AreEqual ("<!--foo-->", Output,
312 "WriteComment had incorrect output.");
316 public void CommentInvalid ()
319 xw.WriteComment("foo-");
320 Assert.Fail ("Should have thrown an ArgumentException.");
322 catch (ArgumentException) { }
325 xw.WriteComment("foo-->bar");
326 Assert.Fail ("Should have thrown an ArgumentException.");
328 catch (ArgumentException) { }
332 public void DocumentStart ()
334 xw.WriteStartDocument ();
335 Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?>", Output,
336 "XmlDeclaration is incorrect.");
340 xw.WriteStartDocument ();
341 Assert.Fail ("Should have thrown an InvalidOperationException.");
343 catch (InvalidOperationException) {
344 // Don't rely on English message assertion.
345 // It is enough to check an exception occurs.
346 // Assert.AreEqual ("Exception message is incorrect.",
347 // "WriteStartDocument should be the first call.", e.Message);
351 xw.WriteStartDocument (true);
352 Assert.AreEqual ("<?xml version='1.0' encoding='utf-16' standalone='yes'?>", Output);
355 xw.WriteStartDocument (false);
356 Assert.AreEqual ("<?xml version='1.0' encoding='utf-16' standalone='no'?>", Output);
360 public void ElementAndAttributeSameXmlns ()
362 xw.WriteStartElement ("ped", "foo", "urn:foo");
363 xw.WriteStartAttribute ("ped", "foo", "urn:foo");
364 xw.WriteEndElement ();
365 Assert.AreEqual ("<ped:foo ped:foo='' xmlns:ped='urn:foo' />", Output);
369 [Category ("NotDotNet")]
370 public void ElementXmlnsNeedEscape ()
372 xw.WriteStartElement ("test", "foo", "'");
373 xw.WriteEndElement ();
374 // MS.NET output is : xmlns:test='''
375 Assert.AreEqual ("<test:foo xmlns:test=''' />", Output);
379 public void ElementEmpty ()
381 xw.WriteStartElement ("foo");
382 xw.WriteEndElement ();
383 Assert.AreEqual ("<foo />", Output);
387 public void ElementWriteElementString ()
389 xw.WriteElementString ("foo", "bar");
390 Assert.AreEqual ("<foo>bar</foo>", Output,
391 "WriteElementString has incorrect output.");
393 xw.WriteElementString ("baz", "");
394 Assert.AreEqual ("<foo>bar</foo><baz />", Output);
396 xw.WriteElementString ("quux", null);
397 Assert.AreEqual ("<foo>bar</foo><baz /><quux />", Output);
399 xw.WriteElementString ("", "quuux");
400 Assert.AreEqual ("<foo>bar</foo><baz /><quux /><>quuux</>", Output);
402 xw.WriteElementString (null, "quuuux");
403 Assert.AreEqual ("<foo>bar</foo><baz /><quux /><>quuux</><>quuuux</>", Output);
407 public void LookupPrefix ()
409 xw.WriteStartElement ("root");
411 xw.WriteStartElement ("one");
412 xw.WriteAttributeString ("xmlns", "foo", null, "http://abc.def");
413 xw.WriteAttributeString ("xmlns", "bar", null, "http://ghi.jkl");
414 Assert.AreEqual ("foo", xw.LookupPrefix ("http://abc.def"));
415 Assert.AreEqual ("bar", xw.LookupPrefix ("http://ghi.jkl"));
416 xw.WriteEndElement ();
418 xw.WriteStartElement ("two");
419 xw.WriteAttributeString ("xmlns", "baz", null, "http://mno.pqr");
420 xw.WriteString("quux");
421 Assert.AreEqual ("baz", xw.LookupPrefix ("http://mno.pqr"));
422 Assert.IsNull (xw.LookupPrefix ("http://abc.def"));
423 Assert.IsNull (xw.LookupPrefix ("http://ghi.jkl"));
425 Assert.IsNull (xw.LookupPrefix ("http://bogus"));
429 public void NamespacesNoNamespaceClearsDefaultNamespace ()
431 xw.WriteStartElement(String.Empty, "foo", "http://netsack.com/");
432 xw.WriteStartElement(String.Empty, "bar", String.Empty);
433 xw.WriteElementString("baz", String.Empty, String.Empty);
434 xw.WriteEndElement();
435 xw.WriteEndElement();
437 "<foo xmlns='http://netsack.com/'><bar xmlns=''><baz /></bar></foo>",
439 "XmlTextWriter is incorrectly outputting namespaces.");
443 public void NamespacesPrefix ()
445 xw.WriteStartElement ("foo", "bar", "http://netsack.com/");
446 xw.WriteStartElement ("foo", "baz", "http://netsack.com/");
447 xw.WriteElementString ("qux", "http://netsack.com/", String.Empty);
448 xw.WriteEndElement ();
449 xw.WriteEndElement ();
450 Assert.AreEqual ("<foo:bar xmlns:foo='http://netsack.com/'><foo:baz><foo:qux /></foo:baz></foo:bar>",
452 "XmlTextWriter is incorrectly outputting prefixes.");
456 // [ExpectedException (typeof (ArgumentException))]
457 public void NamespacesPrefixWithEmptyAndNullNamespaceEmpty ()
459 xw.WriteStartElement ("foo", "bar", "");
463 [ExpectedException (typeof (ArgumentException))]
464 public void NamespacesPrefixWithEmptyAndNullNamespaceNull ()
466 xw.WriteStartElement ("foo", "bar", null);
470 public void ProcessingInstructionValid ()
472 xw.WriteProcessingInstruction("foo", "bar");
473 Assert.AreEqual ("<?foo bar?>", Output, "WriteProcessingInstruction had incorrect output.");
477 [ExpectedException (typeof (ArgumentException))]
478 public void ProcessingInstructionInvalid1 ()
480 xw.WriteProcessingInstruction("fo?>o", "bar");
484 [ExpectedException (typeof (ArgumentException))]
485 public void ProcessingInstructionInvalid2 ()
487 xw.WriteProcessingInstruction("foo", "ba?>r");
491 [ExpectedException (typeof (ArgumentException))]
492 public void ProcessingInstructionInvalid3 ()
494 xw.WriteProcessingInstruction("", "bar");
498 [ExpectedException (typeof (ArgumentException))]
499 public void ProcessingInstructionInvalid4 ()
501 xw.WriteProcessingInstruction(null, "bar");
505 public void WriteBase64 ()
507 UTF8Encoding encoding = new UTF8Encoding();
508 byte[] fooBar = encoding.GetBytes("foobar");
509 xw.WriteBase64 (fooBar, 0, 6);
510 Assert.AreEqual("Zm9vYmFy", Output);
513 xw.WriteBase64 (fooBar, 3, 6);
514 Assert.Fail ("Expected an Argument Exception to be thrown.");
515 } catch (ArgumentException) {}
518 xw.WriteBase64 (fooBar, -1, 6);
519 Assert.Fail ("Expected an Argument Exception to be thrown.");
520 } catch (ArgumentOutOfRangeException) {}
523 xw.WriteBase64 (fooBar, 3, -1);
524 Assert.Fail ("Expected an Argument Exception to be thrown.");
525 } catch (ArgumentOutOfRangeException) {}
528 xw.WriteBase64 (null, 0, 6);
529 Assert.Fail ("Expected an Argument Exception to be thrown.");
530 } catch (ArgumentNullException) {}
534 public void WriteBinHex ()
536 byte [] bytes = new byte [] {4,14,34, 54,94,114, 134,194,255, 0,5};
537 xw.WriteBinHex (bytes, 0, 11);
538 Assert.AreEqual ("040E22365E7286C2FF0005", Output);
542 public void WriteCharEntity ()
544 xw.WriteCharEntity ('a');
545 Assert.AreEqual ("a", Output);
547 xw.WriteCharEntity ('A');
548 Assert.AreEqual ("aA", Output);
550 xw.WriteCharEntity ('1');
551 Assert.AreEqual ("aA1", Output);
553 xw.WriteCharEntity ('K');
554 Assert.AreEqual ("aA1K", Output);
557 xw.WriteCharEntity ((char)0xd800);
558 } catch (ArgumentException) {}
562 [ExpectedException (typeof (InvalidOperationException))]
563 public void WriteEndAttribute ()
565 xw.WriteEndAttribute ();
569 public void WriteEndDocument ()
572 xw.WriteEndDocument ();
573 Assert.Fail ("Expected an Exception.");
574 // in .NET 2.0 it is InvalidOperationException.
575 // in .NET 1,1 it is ArgumentException.
576 } catch (Exception) {}
580 public void WriteEndDocument2 ()
582 xw.WriteStartDocument ();
585 xw.WriteEndDocument ();
586 Assert.Fail ("Expected an Exception.");
587 // in .NET 2.0 it is InvalidOperationException.
588 // in .NET 1,1 it is ArgumentException.
589 } catch (Exception) {}
593 public void WriteEndDocument3 ()
595 xw.WriteStartDocument ();
596 xw.WriteStartElement ("foo");
597 xw.WriteStartAttribute ("bar", null);
598 Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo bar='", Output);
600 xw.WriteEndDocument ();
601 Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo bar='' />", Output);
602 Assert.AreEqual (WriteState.Start, xw.WriteState);
606 [ExpectedException (typeof (InvalidOperationException))]
607 public void WriteEndElement ()
609 // no matching StartElement
610 xw.WriteEndElement ();
614 public void WriteEndElement2 ()
616 xw.WriteStartElement ("foo");
617 xw.WriteEndElement ();
618 Assert.AreEqual ("<foo />", Output);
620 xw.WriteStartElement ("bar");
621 xw.WriteStartAttribute ("baz", null);
622 xw.WriteEndElement ();
623 Assert.AreEqual ("<foo /><bar baz='' />", Output);
627 public void FullEndElement ()
629 xw.WriteStartElement ("foo");
630 xw.WriteFullEndElement ();
631 Assert.AreEqual ("<foo></foo>", Output);
633 xw.WriteStartElement ("bar");
634 xw.WriteAttributeString ("foo", "bar");
635 xw.WriteFullEndElement ();
636 Assert.AreEqual ("<foo></foo><bar foo='bar'></bar>", Output);
638 xw.WriteStartElement ("baz");
639 xw.WriteStartAttribute ("bar", null);
640 xw.WriteFullEndElement ();
641 Assert.AreEqual ("<foo></foo><bar foo='bar'></bar><baz bar=''></baz>", Output);
645 public void WriteQualifiedName ()
647 xw.WriteStartElement (null, "test", null);
648 xw.WriteAttributeString ("xmlns", "me", null, "http://localhost/");
649 xw.WriteQualifiedName ("bob", "http://localhost/");
650 xw.WriteEndElement ();
652 Assert.AreEqual ("<test xmlns:me='http://localhost/'>me:bob</test>", Output);
656 public void WriteQualifiedNameNonDeclaredAttribute ()
658 xw.WriteStartElement ("foo");
659 xw.WriteStartAttribute ("a", "");
660 xw.WriteQualifiedName ("attr", "urn:a");
661 xw.WriteWhitespace (" ");
662 xw.WriteQualifiedName ("attr", "urn:b");
663 xw.WriteEndAttribute ();
664 xw.WriteEndElement ();
665 string xml = sw.ToString ();
667 xml.IndexOf ("<foo ") >= 0,
670 xml.IndexOf ("a='d1p1:attr d1p2:attr'") > 0,
673 xml.IndexOf (" xmlns:d1p1='urn:a'") > 0,
676 xml.IndexOf (" xmlns:d1p2='urn:b'") > 0,
681 [ExpectedException (typeof (ArgumentException))]
682 public void WriteQualifiedNameNonDeclaredContent ()
684 xw.WriteStartElement ("foo");
685 xw.WriteQualifiedName ("abc", "urn:abc");
689 [ExpectedException (typeof (ArgumentException))]
690 public void WriteQualifiedNameNonNCName ()
692 xw.WriteStartElement ("foo");
693 xw.WriteAttributeString ("xmlns", "urn:default");
694 xw.WriteStartElement ("child");
695 xw.WriteStartAttribute ("a", "");
696 xw.WriteQualifiedName ("x:def", "urn:def");
700 public void WriteRaw ()
702 xw.WriteRaw("&<>\"'");
703 Assert.AreEqual ("&<>\"'", Output);
706 Assert.AreEqual ("&<>\"'", Output);
709 Assert.AreEqual ("&<>\"'", Output);
713 public void WriteRawInvalidInAttribute ()
715 xw.WriteStartElement ("foo");
716 xw.WriteStartAttribute ("bar", null);
717 xw.WriteRaw ("&<>\"'");
718 xw.WriteEndAttribute ();
719 xw.WriteEndElement ();
720 Assert.AreEqual ("<foo bar='&<>\"'' />", Output);
724 public void WriteStateTest ()
726 Assert.AreEqual (WriteState.Start, xw.WriteState);
727 xw.WriteStartDocument ();
728 Assert.AreEqual (WriteState.Prolog, xw.WriteState);
729 xw.WriteStartElement ("root");
730 Assert.AreEqual (WriteState.Element, xw.WriteState);
731 xw.WriteElementString ("foo", "bar");
732 Assert.AreEqual (WriteState.Content, xw.WriteState);
734 Assert.AreEqual (WriteState.Closed, xw.WriteState);
738 public void WriteString ()
740 xw.WriteStartDocument ();
742 xw.WriteString("foo");
743 } catch (InvalidOperationException) {}
747 public void WriteString2 ()
749 xw.WriteStartDocument ();
750 // Testing attribute values
752 xw.WriteStartElement ("foo");
753 xw.WriteAttributeString ("bar", "&<>");
754 Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo bar='&<>'", Output);
758 public void WriteStringWithEntities()
760 // Testing element values
761 xw.WriteElementString ("foo", "&<>\"'");
762 Assert.AreEqual ("<foo>&<>\"'</foo>", Output);
766 public void XmlLang ()
768 Assert.IsNull (xw.XmlLang);
770 xw.WriteStartElement ("foo");
771 xw.WriteAttributeString ("xml", "lang", null, "langfoo");
772 Assert.AreEqual ("langfoo", xw.XmlLang);
773 Assert.AreEqual ("<foo xml:lang='langfoo'", Output);
775 xw.WriteAttributeString ("boo", "yah");
776 Assert.AreEqual ("langfoo", xw.XmlLang);
777 Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'", Output);
779 xw.WriteElementString("bar", "baz");
780 Assert.AreEqual ("langfoo", xw.XmlLang);
781 Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>", Output);
783 xw.WriteString("baz");
784 Assert.AreEqual ("langfoo", xw.XmlLang);
785 Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz", Output);
787 xw.WriteStartElement ("quux");
788 xw.WriteStartAttribute ("xml", "lang", null);
789 Assert.AreEqual ("langfoo", xw.XmlLang);
790 Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", Output);
792 xw.WriteString("langbar");
793 // Commented out there: it is implementation-dependent.
794 // and incompatible between .NET 1.0 and 1.1
795 // Assert.AreEqual ("langfoo", xw.XmlLang);
796 // Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", Output);
798 xw.WriteEndAttribute ();
799 // Commented out there: it is implementation-dependent.
800 // and incompatible between .NET 1.0 and 1.1
801 // Assert.AreEqual ("langbar", xw.XmlLang);
802 // Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'", Output);
804 // check if xml:lang repeats output even if same as current scope.
805 xw.WriteStartElement ("joe");
806 xw.WriteAttributeString ("xml", "lang", null, "langbar");
807 Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'", Output);
810 xw.WriteElementString ("quuux", "squonk");
811 Assert.AreEqual ("langbar", xw.XmlLang);
812 Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux>", Output);
814 xw.WriteEndElement ();
815 xw.WriteEndElement ();
816 Assert.AreEqual ("langfoo", xw.XmlLang);
817 Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux></joe></quux>", Output);
819 xw.WriteEndElement ();
820 Assert.IsNull (xw.XmlLang);
821 Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux></joe></quux></foo>", Output);
824 Assert.IsNull (xw.XmlLang);
827 // TODO: test operational aspects
829 public void XmlSpaceTest ()
831 xw.WriteStartElement ("foo");
832 Assert.AreEqual (XmlSpace.None, xw.XmlSpace);
834 xw.WriteStartElement ("bar");
835 xw.WriteAttributeString ("xml", "space", null, "preserve");
836 Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
837 Assert.AreEqual ("<foo><bar xml:space='preserve'", Output);
839 xw.WriteStartElement ("baz");
840 xw.WriteAttributeString ("xml", "space", null, "preserve");
841 Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
842 Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'", Output);
844 xw.WriteStartElement ("quux");
845 xw.WriteStartAttribute ("xml", "space", null);
846 Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
847 Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", Output);
849 // Commented out there: it is implementation-dependent
850 // and incompatible between .NET 1.0 and 1.1
851 xw.WriteString ("default");
852 // Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
853 // Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", Output);
855 xw.WriteEndAttribute ();
856 Assert.AreEqual (XmlSpace.Default, xw.XmlSpace);
857 Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='default'", Output);
859 xw.WriteEndElement ();
860 Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
861 xw.WriteEndElement ();
862 Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
863 xw.WriteEndElement ();
864 Assert.AreEqual (XmlSpace.None, xw.XmlSpace);
866 xw.WriteStartElement ("quux");
870 [ExpectedException (typeof (ArgumentException))]
871 public void XmlSpaceTestInvalidValue1 ()
873 xw.WriteStartElement ("foo");
874 xw.WriteAttributeString ("xml", "space", null, "bubba");
878 [ExpectedException (typeof (ArgumentException))]
879 public void XmlSpaceTestInvalidValue2 ()
881 xw.WriteStartElement ("foo");
882 xw.WriteAttributeString ("xml", "space", null, "PRESERVE");
886 [ExpectedException (typeof (ArgumentException))]
887 public void XmlSpaceTestInvalidValue3 ()
889 xw.WriteStartElement ("foo");
890 xw.WriteAttributeString ("xml", "space", null, "Default");
894 [ExpectedException (typeof (ArgumentException))]
895 public void XmlSpaceTestInvalidValue4 ()
897 xw.WriteStartElement ("foo");
898 xw.WriteAttributeString ("xml", "space", null, "bubba");
902 [ExpectedException (typeof (ArgumentException))]
903 public void WriteWhitespaceNonWhitespace ()
905 xw.WriteWhitespace ("x");
909 public void XmlSpaceRaw ()
911 xw.WriteStartElement ("foo");
912 xw.WriteStartAttribute ("xml", "space", null);
913 Assert.AreEqual (XmlSpace.None, xw.XmlSpace);
914 Assert.AreEqual ("<foo xml:space='", Output);
916 xw.WriteString ("default");
917 // Commented out there: it is implementation-dependent
918 // and incompatible between .NET 1.0 and 1.1
919 // Assert.AreEqual (XmlSpace.None, xw.XmlSpace);
920 // Assert.AreEqual ("<foo xml:space='", Output);
922 xw.WriteEndAttribute ();
923 Assert.AreEqual (XmlSpace.Default, xw.XmlSpace);
924 Assert.AreEqual ("<foo xml:space='default'", Output);
928 public void WriteAttributes ()
930 XmlDocument doc = new XmlDocument();
931 StringWriter sw = new StringWriter();
932 XmlWriter wr = new XmlTextWriter(sw);
933 StringBuilder sb = sw.GetStringBuilder();
934 XmlParserContext ctx = new XmlParserContext(doc.NameTable, new XmlNamespaceManager(doc.NameTable), "", XmlSpace.Default);
935 XmlTextReader xtr = new XmlTextReader("<?xml version='1.0' encoding='utf-8' standalone='no'?><root a1='A' b2='B' c3='C'><foo><bar /></foo></root>", XmlNodeType.Document, ctx);
937 xtr.Read(); // read XMLDecl
938 wr.WriteAttributes(xtr, false);
939 // This method don't always have to take this double-quoted style...
940 Assert.AreEqual("version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"", sw.ToString().Trim(), "#WriteAttributes.XmlDecl.1");
942 sb.Remove(0, sb.Length); // init
943 ctx = new XmlParserContext(doc.NameTable, new XmlNamespaceManager(doc.NameTable), "", XmlSpace.Default);
944 xtr = new XmlTextReader("<?xml version='1.0' standalone='no'?><root a1='A' b2='B' c3='C'><foo><bar /></foo></root>", XmlNodeType.Document, ctx);
945 xtr.Read(); // read XMLDecl
946 Assert.AreEqual (XmlNodeType.XmlDeclaration, xtr.NodeType);
947 sw = new StringWriter ();
948 wr = new XmlTextWriter (sw);
950 // This block raises an error on MS.NET 1.0.
951 wr.WriteAttributes(xtr, false);
952 // This method don't always have to take this double-quoted style...
953 Assert.AreEqual("version=\"1.0\" standalone=\"no\"", sw.ToString().Trim(), "#WriteAttributes.XmlDecl.2");
955 sw = new StringWriter ();
956 wr = new XmlTextWriter (sw);
957 sb.Remove(0, sb.Length); // init
959 xtr.Read(); // read root
960 Assert.AreEqual (XmlNodeType.Element, xtr.NodeType);
961 wr.WriteStartElement(xtr.LocalName, xtr.NamespaceURI);
962 wr.WriteAttributes(xtr, false);
963 wr.WriteEndElement();
965 // This method don't always have to take this double-quoted style...
966 Assert.AreEqual("<root a1=\"A\" b2=\"B\" c3=\"C\" />", sw.ToString().Trim(), "#WriteAttributes.Element");
971 public void WriteWhitespace ()
973 xw.WriteStartElement ("a");
974 xw.WriteWhitespace ("\n\t");
975 xw.WriteStartElement ("b");
976 xw.WriteWhitespace ("\n\t");
977 xw.WriteEndElement ();
978 xw.WriteWhitespace ("\n");
979 xw.WriteEndElement ();
980 xw.WriteWhitespace ("\n");
982 Assert.AreEqual ("<a>\n\t<b>\n\t</b>\n</a>\n", Output);
986 public void FlushDoesntCloseTag ()
988 xw.WriteStartElement ("foo");
989 xw.WriteAttributeString ("bar", "baz");
991 Assert.AreEqual ("<foo bar='baz'", Output);
995 public void WriteWhitespaceClosesTag ()
997 xw.WriteStartElement ("foo");
998 xw.WriteAttributeString ("bar", "baz");
999 xw.WriteWhitespace (" ");
1000 Assert.AreEqual ("<foo bar='baz'> ", Output);
1004 public void DontOutputMultipleXmlns ()
1006 XmlDocument doc = new XmlDocument();
1007 doc.LoadXml("<a xmlns:dt=\"b\" dt:dt=\"c\"/>");
1008 XmlDocument doc2 = new XmlDocument();
1009 doc2.LoadXml(doc.InnerXml);
1010 Assert.AreEqual ("<a xmlns:dt=\"b\" dt:dt=\"c\" />",
1015 public void DontOutputNonDeclaredXmlns ()
1017 string xml = "<x:a foo='foo' xmlns:x='urn:foo'><b /></x:a>";
1018 XmlDocument doc = new XmlDocument();
1020 XmlDocument doc2 = new XmlDocument();
1021 doc2.LoadXml(doc.InnerXml);
1022 Assert.AreEqual (xml.Replace ('\'', '"'), doc2.OuterXml);
1026 public void DontOutputRemovalDefaultNSDeclaration ()
1028 xw.WriteStartDocument ();
1029 xw.WriteStartElement ("foo");
1030 xw.WriteAttributeString ("xmlns", "probe");
1031 Assert.AreEqual (String.Empty, xw.LookupPrefix ("probe"));
1032 xw.WriteStartElement ("b");
1033 Assert.AreEqual (String.Empty, xw.LookupPrefix ("probe"));
1034 xw.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""
1035 xw.WriteEndElement (); // b2
1036 xw.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""
1037 xw.WriteEndElement (); // b2
1038 xw.WriteEndElement (); // b
1039 xw.WriteEndElement (); // foo
1040 xw.WriteEndDocument ();
1043 Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 xmlns='' /></b></foo>", Output);
1047 public void DontOutputRemovalDefaultNSDeclaration2 ()
1049 xw.WriteStartDocument ();
1050 // IMPORTANT DIFFERENCE!! ns = "", not null
1051 xw.WriteStartElement ("foo", "");
1052 xw.WriteAttributeString ("xmlns", "probe");
1053 Assert.IsNull (xw.LookupPrefix ("probe"));
1054 xw.WriteStartElement ("b");
1055 Assert.IsNull (xw.LookupPrefix ("probe"));
1056 xw.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""
1057 xw.WriteEndElement (); // b2
1058 xw.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""
1059 xw.WriteEndElement (); // b2
1060 xw.WriteEndElement (); // b
1061 xw.WriteEndElement (); // foo
1062 xw.WriteEndDocument ();
1065 Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 /></b></foo>", Output);
1069 public void DoOutputRemovalDefaultNSDeclaration ()
1071 xw.WriteStartElement ("docelem", "a-namespace");
1073 XmlDocument doc = new XmlDocument ();
1074 doc.CreateElement ("hola").WriteTo (xw);
1075 // This means, WriteTo never passes null NamespaceURI argument to XmlWriter.
1076 xw.WriteEndElement ();
1079 Assert.AreEqual ("<docelem xmlns='a-namespace'><hola xmlns='' /></docelem>", Output);
1083 public void WriteAttributeTakePrecedenceOnXmlns ()
1085 xw.WriteStartElement ("root", "urn:foo");
1086 xw.WriteAttributeString ("xmlns", "urn:bar");
1087 xw.WriteEndElement ();
1089 Assert.AreEqual ("<root xmlns='urn:bar' />", Output);
1093 [ExpectedException (typeof (ArgumentException))]
1094 public void LookupPrefixNull ()
1096 xw.LookupPrefix (null);
1100 [ExpectedException (typeof (ArgumentException))]
1101 public void LookupPrefixEmpty ()
1103 xw.LookupPrefix (String.Empty);
1107 public void LookupPrefixIgnoresXmlnsAttribute ()
1109 Assert.IsNull (xw.LookupPrefix ("urn:foo"));
1110 xw.WriteStartElement ("root");
1111 Assert.IsNull (xw.LookupPrefix ("urn:foo"));
1112 xw.WriteAttributeString ("xmlns", "urn:foo");
1113 // Surprisingly to say, it is ignored!!
1114 Assert.AreEqual (String.Empty, xw.LookupPrefix ("urn:foo"));
1115 xw.WriteStartElement ("hoge");
1116 // (still after flushing previous start element.)
1117 Assert.AreEqual (String.Empty, xw.LookupPrefix ("urn:foo"));
1118 xw.WriteStartElement ("fuga", "urn:foo");
1119 // Is this testing on the correct way? Yes, here it is.
1120 Assert.AreEqual (String.Empty, xw.LookupPrefix ("urn:foo"));
1124 public void WriteInvalidNames ()
1126 xw.WriteStartElement ("foo<>");
1127 xw.WriteAttributeString ("ho<>ge", "value");
1131 [ExpectedException (typeof (ArgumentException))]
1132 public void AttributeWriteStartAttributePrefixWithoutNS ()
1134 xw.WriteStartAttribute ("some", "foo", null);
1138 public void AttributeWriteStartAttributeXmlnsNullNS ()
1140 xw.WriteStartAttribute ("xmlns", "foo", null);
1144 [ExpectedException (typeof (ArgumentException))]
1145 public void AttributeWriteEndAttributeXmlnsNullNs ()
1147 // Compare with the test AttributeWriteStartAttributeXmlnsNullNS().
1148 xw.WriteStartAttribute ("xmlns", "foo", null);
1149 xw.WriteEndAttribute ();
1153 [ExpectedException (typeof (ArgumentException))]
1154 public void AttributeWriteStartAttributePrefixXmlnsNonW3CNS ()
1156 xw.WriteStartAttribute ("xmlns", "foo", "urn:foo");
1160 [ExpectedException (typeof (ArgumentException))]
1161 public void AttributeWriteStartAttributeLocalXmlnsNonW3CNS ()
1163 xw.WriteStartAttribute ("", "xmlns", "urn:foo");
1167 public void WriteRawProceedToProlog ()
1169 XmlTextWriter xw = new XmlTextWriter (new StringWriter ());
1171 Assert.AreEqual (WriteState.Prolog, xw.WriteState);
1175 public void CloseTwice ()
1177 StringWriter sw = new StringWriter ();
1178 XmlTextWriter writer = new XmlTextWriter (sw);
1180 // should not result in an exception
1185 public void WriteRawWriteString ()
1187 // WriteRaw () -> WriteString ().
1189 xw.WriteString ("foo");
1190 Assert.AreEqual (WriteState.Content, xw.WriteState);
1194 public void LookupOverridenPrefix ()
1196 xw.WriteStartElement ("out");
1197 xw.WriteAttributeString ("xmlns", "baz", "http://www.w3.org/2000/xmlns/", "xyz");
1198 xw.WriteStartElement ("baz", "foo", "abc");
1199 Assert.IsNull (xw.LookupPrefix ("xyz"));
1203 public void DuplicatingNamespaceMappingInAttributes ()
1205 xw.WriteStartElement ("out");
1206 xw.WriteAttributeString ("p", "foo", "urn:foo", "xyz");
1207 xw.WriteAttributeString ("p", "bar", "urn:bar", "xyz");
1208 xw.WriteAttributeString ("p", "baz", "urn:baz", "xyz");
1209 xw.WriteStartElement ("out");
1210 xw.WriteAttributeString ("p", "foo", "urn:foo", "xyz");
1211 xw.WriteStartElement ("out");
1212 xw.WriteAttributeString ("p", "foo", "urn:foo", "xyz");
1213 xw.WriteEndElement ();
1214 xw.WriteEndElement ();
1215 xw.WriteEndElement ();
1216 string xml = sw.ToString ();
1218 xml.IndexOf ("p:foo='xyz'") > 0,
1221 xml.IndexOf ("d1p1:bar='xyz'") > 0,
1224 xml.IndexOf ("d1p2:baz='xyz'") > 0,
1227 xml.IndexOf ("xmlns:d1p2='urn:baz'") > 0,
1230 xml.IndexOf ("xmlns:d1p1='urn:bar'") > 0,
1233 xml.IndexOf ("xmlns:p='urn:foo'") > 0,
1236 xml.IndexOf ("<out p:foo='xyz'><out p:foo='xyz' /></out></out>") > 0,
1241 public void WriteXmlSpaceIgnoresNS ()
1243 xw.WriteStartElement ("root");
1244 xw.WriteAttributeString ("xml", "space", "abc", "preserve");
1245 xw.WriteEndElement ();
1246 Assert.AreEqual ("<root xml:space='preserve' />", sw.ToString ());
1249 [Test] // bug #75546
1250 public void WriteEmptyNSQNameInAttribute ()
1252 XmlTextWriter xw = new XmlTextWriter (TextWriter.Null);
1253 xw.WriteStartElement ("foo", "urn:goo");
1254 xw.WriteAttributeString ("xmlns:bar", "urn:bar");
1255 xw.WriteStartAttribute ("foo", "");
1256 xw.WriteQualifiedName ("n1", "urn:bar");
1257 xw.WriteEndAttribute ();
1258 xw.WriteStartAttribute ("foo", "");
1259 xw.WriteQualifiedName ("n2", "");
1260 xw.WriteEndAttribute ();
1263 [Test] // bug #76095
1264 public void SurrogatePairsInWriteString ()
1266 MemoryStream ms = new MemoryStream ();
1267 XmlWriter writer = new XmlTextWriter(ms, null);
1268 writer.WriteElementString("a", "\ud800\udf39");
1270 byte [] referent = new byte [] {0x3c, 0x61, 0x3e, 0xf0,
1271 0x90, 0x8c, 0xb9, 0x3c, 0x2f, 0x61, 0x3e};
1272 NUnit.Framework.Assert.AreEqual (referent, ms.ToArray ());
1276 [ExpectedException (typeof (InvalidOperationException))]
1277 public void RejectWritingAtErrorState ()
1280 xw.WriteEndElement ();
1281 } catch (Exception) {
1284 xw.WriteStartElement ("foo");
1290 public void WriteBooleanArray ()
1292 bool [] array = new bool [] {true, false, true, true, false};
1293 xw.WriteArray ("", "root", "", array, 1, 3);
1294 Assert.AreEqual ("<root>false</root><root>true</root><root>true</root>", Output, "#1");
1298 public void WriteNode ()
1300 string s = @"<Resolve xmlns='http://schemas.microsoft.com/net/2006/05/peer' xmlns:i='http://www.w3.org/2001/XMLSchema-instance'><ClientId>79310c9f-18d4-4337-a95a-1865ca54a66e</ClientId><MaxAddresses>3</MaxAddresses><MeshId>amesh</MeshId></Resolve>".Replace ('\'', '"');
1301 var sw = new StringWriter ();
1302 var xw = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (sw, new XmlWriterSettings () { OmitXmlDeclaration = true }));
1303 var xr = XmlDictionaryReader.CreateDictionaryReader (XmlReader.Create (new StringReader (s)));
1304 xr.MoveToContent ();
1305 while (!xr.EOF && xr.NodeType != XmlNodeType.EndElement)
1306 xw.WriteNode (xr, false);
1308 Assert.AreEqual (s, sw.ToString ());