2 // System.Xml.XmlTextWriterTests
5 // Kral Ferch <kral_ferch@hotmail.com>
6 // Martin Willemoes Hansen <mwh@sysrq.dk>
9 // (C) 2003 Martin Willemoes Hansen
17 using NUnit
.Framework
;
19 namespace MonoTests
.System
.Xml
22 public class XmlTextWriterTests
: Assertion
28 public void GetReady ()
30 sw
= new StringWriter ();
31 xtw
= new XmlTextWriter (sw
);
35 private string StringWriterText
37 get { return sw.GetStringBuilder ().ToString (); }
41 public void AttributeNamespacesNonNamespaceAttributeBefore ()
43 xtw
.WriteStartElement ("foo");
44 xtw
.WriteAttributeString("bar", "baz");
45 xtw
.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
46 AssertEquals ("<foo bar='baz' xmlns:abc='http://abc.def'", StringWriterText
);
50 public void AttributeNamespacesNonNamespaceAttributeAfter ()
52 xtw
.WriteStartElement ("foo");
54 xtw
.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
55 xtw
.WriteAttributeString("bar", "baz");
56 AssertEquals ("<foo xmlns:abc='http://abc.def' bar='baz'", StringWriterText
);
60 public void AttributeNamespacesThreeParamWithNullInNamespaceParam ()
62 xtw
.WriteAttributeString ("xmlns", null, "http://abc.def");
63 AssertEquals ("xmlns='http://abc.def'", StringWriterText
);
67 public void AttributeNamespacesThreeParamWithTextInNamespaceParam ()
71 xtw
.WriteAttributeString ("xmlns", "http://somenamespace.com", "http://abc.def");
73 catch (ArgumentException
) {}
77 public void AttributeNamespacesWithNullInNamespaceParam ()
79 xtw
.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
80 AssertEquals ("xmlns:abc='http://abc.def'", StringWriterText
);
84 public void AttributeNamespacesWithTextInNamespaceParam ()
87 xtw
.WriteAttributeString ("xmlns", "abc", "http://somenamespace.com", "http://abc.def");
88 } catch (ArgumentException
) {}
92 public void AttributeNamespacesXmlnsXmlns ()
94 xtw
.WriteStartElement ("foo");
96 xtw
.WriteAttributeString ("xmlns", "xmlns", null, "http://abc.def");
97 // This should not be allowed, even though MS.NET doesn't treat as an error.
98 // See http://www.w3.org/TR/REC-xml-names/ Namespace Constraint: Prefix Declared
99 Fail ("any prefix which name starts from \"xml\" must not be allowed.");
101 catch (ArgumentException
) {}
102 xtw
.WriteAttributeString ("", "xmlns", null, "http://abc.def");
106 public void AttributeWriteAttributeString ()
108 xtw
.WriteStartElement ("foo");
110 xtw
.WriteAttributeString ("foo", "bar");
111 AssertEquals ("<foo foo='bar'", StringWriterText
);
113 xtw
.WriteAttributeString ("bar", "");
114 AssertEquals ("<foo foo='bar' bar=''", StringWriterText
);
116 xtw
.WriteAttributeString ("baz", null);
117 AssertEquals ("<foo foo='bar' bar='' baz=''", StringWriterText
);
119 xtw
.WriteAttributeString ("hoge", "a\nb");
120 AssertEquals ("<foo foo='bar' bar='' baz='' hoge='a
b'", StringWriterText
);
122 xtw
.WriteAttributeString ("fuga", " a\t\r\nb\t");
123 AssertEquals ("<foo foo='bar' bar='' baz='' hoge='a
b' fuga=' a\t
b\t'", StringWriterText
);
126 // Why does this pass Microsoft?
127 // Anyway, Mono should not allow such code.
128 xtw
.WriteAttributeString ("", "quux");
129 // AssertEquals ("<foo foo='bar' bar='' baz='' ='quux'", StringWriterText);
130 Fail ("empty name not allowed.");
131 } catch (Exception
) {
135 // Why does this pass Microsoft?
136 // Anyway, Mono should not allow such code.
137 xtw
.WriteAttributeString (null, "quuux");
138 // AssertEquals ("<foo foo='bar' bar='' baz='' ='quux' ='quuux'", StringWriterText);
139 Fail ("null name not allowed.");
140 } catch (Exception
) {
145 [ExpectedException (typeof (InvalidOperationException
))]
146 public void AttributeWriteAttributeStringNotInsideOpenStartElement ()
148 xtw
.WriteStartElement ("foo");
149 xtw
.WriteString ("bar");
151 xtw
.WriteAttributeString ("baz", "quux");
155 public void AttributeWriteAttributeStringWithoutParentElement ()
157 xtw
.WriteAttributeString ("foo", "bar");
158 AssertEquals ("foo='bar'", StringWriterText
);
160 xtw
.WriteAttributeString ("baz", "quux");
161 AssertEquals ("foo='bar' baz='quux'", StringWriterText
);
165 public void CDataValid ()
167 xtw
.WriteCData ("foo");
168 AssertEquals ("WriteCData had incorrect output.", "<![CDATA[foo]]>", StringWriterText
);
172 [ExpectedException (typeof (ArgumentException
))]
173 public void CDataInvalid ()
175 xtw
.WriteCData("foo]]>bar");
179 public void CloseOpenElements ()
181 xtw
.WriteStartElement("foo");
182 xtw
.WriteStartElement("bar");
183 xtw
.WriteStartElement("baz");
185 AssertEquals ("Close didn't write out end elements properly.", "<foo><bar><baz /></bar></foo>", StringWriterText
);
189 public void CloseWriteAfter ()
191 xtw
.WriteElementString ("foo", "bar");
194 // WriteEndElement and WriteStartDocument aren't tested here because
195 // they will always throw different exceptions besides 'The Writer is closed.'
196 // and there are already tests for those exceptions.
199 xtw
.WriteCData ("foo");
200 Fail ("WriteCData after Close Should have thrown an InvalidOperationException.");
202 catch (InvalidOperationException
) {
203 // Don't rely on English message assertion.
204 // It is enough to check an exception occurs.
205 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
209 xtw
.WriteComment ("foo");
210 Fail ("WriteComment after Close Should have thrown an InvalidOperationException.");
212 catch (InvalidOperationException
) {
213 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
217 xtw
.WriteProcessingInstruction ("foo", "bar");
218 Fail ("WriteProcessingInstruction after Close Should have thrown an InvalidOperationException.");
220 catch (InvalidOperationException
) {
221 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
225 xtw
.WriteStartElement ("foo", "bar", "baz");
226 Fail ("WriteStartElement after Close Should have thrown an InvalidOperationException.");
228 catch (InvalidOperationException
) {
229 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
234 xtw
.WriteAttributeString ("foo", "bar");
235 Fail ("WriteAttributeString after Close Should have thrown an InvalidOperationException.");
237 catch (InvalidOperationException
)
239 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
243 xtw
.WriteString ("foo");
244 Fail ("WriteString after Close Should have thrown an InvalidOperationException.");
246 catch (InvalidOperationException
) {
247 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
252 public void CommentValid ()
254 xtw
.WriteComment ("foo");
255 AssertEquals ("WriteComment had incorrect output.", "<!--foo-->", StringWriterText
);
259 public void CommentInvalid ()
262 xtw
.WriteComment("foo-");
263 Fail("Should have thrown an ArgumentException.");
265 catch (ArgumentException
) { }
268 xtw
.WriteComment("foo-->bar");
269 Fail("Should have thrown an ArgumentException.");
271 catch (ArgumentException
) { }
275 public void ConstructorsAndBaseStream ()
277 Assert ("BaseStream property returned wrong value.", Object
.ReferenceEquals (null, this.xtw
.BaseStream
));
283 ms
= new MemoryStream ();
284 xtw
= new XmlTextWriter (ms
, new UnicodeEncoding ());
285 xtw
.WriteStartDocument ();
287 ms
.Seek (0, SeekOrigin
.Begin
);
288 sr
= new StreamReader (ms
, Encoding
.Unicode
);
289 string expectedXmlDeclaration
= "<?xml version=\"1.0\" encoding=\"utf-16\"?>";
290 string actualXmlDeclaration
= sr
.ReadToEnd();
291 AssertEquals (expectedXmlDeclaration
, actualXmlDeclaration
);
292 Assert ("BaseStream property returned wrong value.", Object
.ReferenceEquals (ms
, xtw
.BaseStream
));
294 ms
= new MemoryStream ();
295 xtw
= new XmlTextWriter (ms
, new UnicodeEncoding ());
296 xtw
.WriteStartDocument (true);
298 ms
.Seek (0, SeekOrigin
.Begin
);
299 sr
= new StreamReader (ms
, Encoding
.Unicode
);
300 AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?>", sr
.ReadToEnd ());
302 ms
= new MemoryStream ();
303 xtw
= new XmlTextWriter (ms
, new UTF8Encoding ());
304 xtw
.WriteStartDocument ();
306 ms
.Seek (0, SeekOrigin
.Begin
);
307 sr
= new StreamReader (ms
, Encoding
.UTF8
);
308 AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-8\"?>", sr
.ReadToEnd ());
310 ms
= new MemoryStream ();
311 xtw
= new XmlTextWriter (ms
, null);
312 xtw
.WriteStartDocument ();
314 ms
.Seek (0, SeekOrigin
.Begin
);
315 sr
= new StreamReader (ms
, Encoding
.UTF8
);
316 AssertEquals ("<?xml version=\"1.0\"?>", sr
.ReadToEnd ());
318 ms
= new MemoryStream ();
319 xtw
= new XmlTextWriter (ms
, null);
320 xtw
.WriteStartDocument (true);
322 ms
.Seek (0, SeekOrigin
.Begin
);
323 sr
= new StreamReader (ms
, Encoding
.UTF8
);
324 AssertEquals ("<?xml version=\"1.0\" standalone=\"yes\"?>", sr
.ReadToEnd ());
325 Assert ("BaseStream property returned wrong value.", Object
.ReferenceEquals (ms
, xtw
.BaseStream
));
329 public void DocumentStart ()
331 xtw
.WriteStartDocument ();
332 AssertEquals ("XmlDeclaration is incorrect.", "<?xml version='1.0' encoding='utf-16'?>", StringWriterText
);
336 xtw
.WriteStartDocument ();
337 Fail("Should have thrown an InvalidOperationException.");
339 catch (InvalidOperationException
) {
340 // Don't rely on English message assertion.
341 // It is enough to check an exception occurs.
342 // AssertEquals ("Exception message is incorrect.",
343 // "WriteStartDocument should be the first call.", e.Message);
346 xtw
= new XmlTextWriter (sw
= new StringWriter ());
347 xtw
.QuoteChar
= '\'';
348 xtw
.WriteStartDocument (true);
349 AssertEquals ("<?xml version='1.0' encoding='utf-16' standalone='yes'?>", StringWriterText
);
351 xtw
= new XmlTextWriter (sw
= new StringWriter ());
352 xtw
.QuoteChar
= '\'';
353 xtw
.WriteStartDocument (false);
354 AssertEquals ("<?xml version='1.0' encoding='utf-16' standalone='no'?>", StringWriterText
);
358 public void ElementAndAttributeSameXmlns ()
360 xtw
.WriteStartElement ("ped", "foo", "urn:foo");
361 xtw
.WriteStartAttribute ("ped", "foo", "urn:foo");
362 xtw
.WriteEndElement ();
363 AssertEquals ("<ped:foo ped:foo='' xmlns:ped='urn:foo' />", StringWriterText
);
367 public void ElementXmlnsNeedEscape ()
369 xtw
.WriteStartElement ("test", "foo", "'");
370 xtw
.WriteEndElement ();
371 // MS.NET fails this case.
372 AssertEquals ("<test:foo xmlns:test=''' />", StringWriterText
);
376 public void ElementEmpty ()
378 xtw
.WriteStartElement ("foo");
379 xtw
.WriteEndElement ();
380 AssertEquals ("Incorrect output.", "<foo />", StringWriterText
);
384 public void ElementWriteElementString ()
386 xtw
.WriteElementString ("foo", "bar");
387 AssertEquals ("WriteElementString has incorrect output.", "<foo>bar</foo>", StringWriterText
);
389 xtw
.WriteElementString ("baz", "");
390 AssertEquals ("<foo>bar</foo><baz />", StringWriterText
);
392 xtw
.WriteElementString ("quux", null);
393 AssertEquals ("<foo>bar</foo><baz /><quux />", StringWriterText
);
395 xtw
.WriteElementString ("", "quuux");
396 AssertEquals ("<foo>bar</foo><baz /><quux /><>quuux</>", StringWriterText
);
398 xtw
.WriteElementString (null, "quuuux");
399 AssertEquals ("<foo>bar</foo><baz /><quux /><>quuux</><>quuuux</>", StringWriterText
);
403 public void FormattingTest ()
405 xtw
.Formatting
= Formatting
.Indented
;
406 xtw
.WriteStartDocument ();
407 xtw
.WriteStartElement ("foo");
408 xtw
.WriteElementString ("bar", "");
410 AssertEquals (String
.Format ("<?xml version='1.0' encoding='utf-16'?>{0}<foo>{0} <bar />{0}</foo>", Environment
.NewLine
), StringWriterText
);
414 public void FormattingInvalidXmlForFun ()
416 xtw
.Formatting
= Formatting
.Indented
;
417 xtw
.IndentChar
= 'x';
418 xtw
.WriteStartDocument ();
419 xtw
.WriteStartElement ("foo");
420 xtw
.WriteStartElement ("bar");
421 xtw
.WriteElementString ("baz", "");
423 AssertEquals (String
.Format ("<?xml version='1.0' encoding='utf-16'?>{0}<foo>{0}xx<bar>{0}xxxx<baz />{0}xx</bar>{0}</foo>", Environment
.NewLine
), StringWriterText
);
427 public void FormattingFromRemarks ()
429 // Remarks section of on-line help for XmlTextWriter.Formatting suggests this test.
430 xtw
.Formatting
= Formatting
.Indented
;
431 xtw
.WriteStartElement ("ol");
432 xtw
.WriteStartElement ("li");
433 xtw
.WriteString ("The big "); // This means "li" now has a mixed content model.
434 xtw
.WriteElementString ("b", "E");
435 xtw
.WriteElementString ("i", "lephant");
436 xtw
.WriteString (" walks slowly.");
437 xtw
.WriteEndElement ();
438 xtw
.WriteEndElement ();
439 AssertEquals (String
.Format ("<ol>{0} <li>The big <b>E</b><i>lephant</i> walks slowly.</li>{0}</ol>", Environment
.NewLine
), StringWriterText
);
443 public void LookupPrefix ()
445 xtw
.WriteStartElement ("root");
447 xtw
.WriteStartElement ("one");
448 xtw
.WriteAttributeString ("xmlns", "foo", null, "http://abc.def");
449 xtw
.WriteAttributeString ("xmlns", "bar", null, "http://ghi.jkl");
450 AssertEquals ("foo", xtw
.LookupPrefix ("http://abc.def"));
451 AssertEquals ("bar", xtw
.LookupPrefix ("http://ghi.jkl"));
452 xtw
.WriteEndElement ();
454 xtw
.WriteStartElement ("two");
455 xtw
.WriteAttributeString ("xmlns", "baz", null, "http://mno.pqr");
456 xtw
.WriteString("quux");
457 AssertEquals ("baz", xtw
.LookupPrefix ("http://mno.pqr"));
458 AssertNull (xtw
.LookupPrefix ("http://abc.def"));
459 AssertNull (xtw
.LookupPrefix ("http://ghi.jkl"));
461 AssertNull (xtw
.LookupPrefix ("http://bogus"));
465 public void NamespacesAttributesPassingInNamespaces ()
467 xtw
.Namespaces
= false;
468 xtw
.WriteStartElement ("foo");
470 // These shouldn't throw any exceptions since they don't pass in
472 xtw
.WriteAttributeString ("bar", "baz");
473 xtw
.WriteAttributeString ("", "a", "", "b");
474 xtw
.WriteAttributeString (null, "c", "", "d");
475 xtw
.WriteAttributeString ("", "e", null, "f");
476 xtw
.WriteAttributeString (null, "g", null, "h");
478 AssertEquals ("<foo bar='baz' a='b' c='d' e='f' g='h'", StringWriterText
);
480 // These should throw ArgumentException because they pass in a
481 // namespace when Namespaces = false.
485 public void NamespacesElementsPassingInNamespaces ()
487 xtw
.Namespaces
= false;
489 // These shouldn't throw any exceptions since they don't pass in
491 xtw
.WriteElementString ("foo", "bar");
492 xtw
.WriteStartElement ("baz");
493 xtw
.WriteStartElement ("quux", "");
494 xtw
.WriteStartElement ("quuux", null);
495 xtw
.WriteStartElement (null, "a", null);
496 xtw
.WriteStartElement (null, "b", "");
497 xtw
.WriteStartElement ("", "c", null);
498 xtw
.WriteStartElement ("", "d", "");
500 AssertEquals ("<foo>bar</foo><baz><quux><quuux><a><b><c><d", StringWriterText
);
502 // These should throw ArgumentException because they pass in a
503 // namespace when Namespaces = false.
505 xtw
.WriteElementString ("qux", "http://netsack.com/", String
.Empty
);
506 Fail ("Expected an ArgumentException.");
507 } catch (ArgumentException
) {}
510 xtw
.WriteStartElement ("foo", "http://netsack.com/");
511 Fail ("Expected an ArgumentException.");
512 } catch (ArgumentException
) {}
515 xtw
.WriteStartElement ("foo", "bar", "http://netsack.com/");
516 Fail ("Expected an ArgumentException.");
517 } catch (ArgumentException
) {}
520 xtw
.WriteStartElement ("foo", "bar", null);
521 Fail ("Expected an ArgumentException.");
522 } catch (ArgumentException
) {}
525 xtw
.WriteStartElement ("foo", "bar", "");
526 Fail ("Expected an ArgumentException.");
527 } catch (ArgumentException
) {}
530 xtw
.WriteStartElement ("foo", "", "");
531 Fail ("Expected an ArgumentException.");
532 } catch (ArgumentException
) {}
536 public void NamespacesNoNamespaceClearsDefaultNamespace ()
538 xtw
.WriteStartElement(String
.Empty
, "foo", "http://netsack.com/");
539 xtw
.WriteStartElement(String
.Empty
, "bar", String
.Empty
);
540 xtw
.WriteElementString("baz", String
.Empty
, String
.Empty
);
541 xtw
.WriteEndElement();
542 xtw
.WriteEndElement();
543 AssertEquals ("XmlTextWriter is incorrectly outputting namespaces.",
544 "<foo xmlns='http://netsack.com/'><bar xmlns=''><baz /></bar></foo>", StringWriterText
);
548 public void NamespacesPrefix ()
550 xtw
.WriteStartElement ("foo", "bar", "http://netsack.com/");
551 xtw
.WriteStartElement ("foo", "baz", "http://netsack.com/");
552 xtw
.WriteElementString ("qux", "http://netsack.com/", String
.Empty
);
553 xtw
.WriteEndElement ();
554 xtw
.WriteEndElement ();
555 AssertEquals ("XmlTextWriter is incorrectly outputting prefixes.",
556 "<foo:bar xmlns:foo='http://netsack.com/'><foo:baz><foo:qux /></foo:baz></foo:bar>", StringWriterText
);
560 [ExpectedException (typeof (ArgumentException
))]
561 public void NamespacesPrefixWithEmptyAndNullNamespaceEmpty ()
563 xtw
.WriteStartElement ("foo", "bar", "");
567 [ExpectedException (typeof (ArgumentException
))]
568 public void NamespacesPrefixWithEmptyAndNullNamespaceNull ()
570 xtw
.WriteStartElement ("foo", "bar", null);
574 public void NamespacesSettingWhenWriteStateNotStart ()
576 xtw
.WriteStartElement ("foo");
579 xtw
.Namespaces
= false;
580 Fail ("Expected an InvalidOperationException.");
582 catch (InvalidOperationException
) {}
583 AssertEquals (true, xtw
.Namespaces
);
587 public void ProcessingInstructionValid ()
589 xtw
.WriteProcessingInstruction("foo", "bar");
590 AssertEquals ("WriteProcessingInstruction had incorrect output.", "<?foo bar?>", StringWriterText
);
594 public void ProcessingInstructionInvalid ()
598 xtw
.WriteProcessingInstruction("fo?>o", "bar");
599 Fail("Should have thrown an ArgumentException.");
601 catch (ArgumentException
) { }
605 xtw
.WriteProcessingInstruction("foo", "ba?>r");
606 Fail("Should have thrown an ArgumentException.");
608 catch (ArgumentException
) { }
612 xtw
.WriteProcessingInstruction("", "bar");
613 Fail("Should have thrown an ArgumentException.");
615 catch (ArgumentException
) { }
619 xtw
.WriteProcessingInstruction(null, "bar");
620 Fail("Should have thrown an ArgumentException.");
622 catch (ArgumentException
) { }
626 public void QuoteCharDoubleQuote ()
630 // version, encoding, standalone
631 xtw
.WriteStartDocument (true);
633 // namespace declaration
634 xtw
.WriteElementString ("foo", "http://netsack.com", "bar");
636 AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?><foo xmlns=\"http://netsack.com\">bar</foo>", StringWriterText
);
642 [ExpectedException (typeof (ArgumentException
))]
643 public void QuoteCharInvalid ()
649 public void WriteBase64 ()
651 UTF8Encoding encoding
= new UTF8Encoding();
652 byte[] fooBar
= encoding
.GetBytes("foobar");
653 xtw
.WriteBase64 (fooBar
, 0, 6);
654 AssertEquals("Zm9vYmFy", StringWriterText
);
657 xtw
.WriteBase64 (fooBar
, 3, 6);
658 Fail ("Expected an Argument Exception to be thrown.");
659 } catch (ArgumentException
) {}
662 xtw
.WriteBase64 (fooBar
, -1, 6);
663 Fail ("Expected an Argument Exception to be thrown.");
664 } catch (ArgumentOutOfRangeException
) {}
667 xtw
.WriteBase64 (fooBar
, 3, -1);
668 Fail ("Expected an Argument Exception to be thrown.");
669 } catch (ArgumentOutOfRangeException
) {}
672 xtw
.WriteBase64 (null, 0, 6);
673 Fail ("Expected an Argument Exception to be thrown.");
674 } catch (ArgumentNullException
) {}
678 public void WriteBinHex ()
680 byte [] bytes
= new byte [] {4,14,34, 54,94,114, 134,194,255, 0,5}
;
681 xtw
.WriteBinHex (bytes
, 0, 11);
682 AssertEquals ("040E22365E7286C2FF0005", StringWriterText
);
686 public void WriteCharEntity ()
688 xtw
.WriteCharEntity ('a');
689 AssertEquals ("a", StringWriterText
);
691 xtw
.WriteCharEntity ('A');
692 AssertEquals ("aA", StringWriterText
);
694 xtw
.WriteCharEntity ('1');
695 AssertEquals ("aA1", StringWriterText
);
697 xtw
.WriteCharEntity ('K');
698 AssertEquals ("aA1K", StringWriterText
);
701 xtw
.WriteCharEntity ((char)0xd800);
702 } catch (ArgumentException
) {}
706 [ExpectedException (typeof (InvalidOperationException
))]
707 public void WriteEndAttribute ()
709 xtw
.WriteEndAttribute ();
713 public void WriteEndDocument ()
716 xtw
.WriteEndDocument ();
717 Fail ("Expected an ArgumentException.");
718 } catch (ArgumentException
) {}
720 xtw
.WriteStartDocument ();
724 xtw
.WriteEndDocument ();
725 Fail ("Expected an ArgumentException.");
727 catch (ArgumentException
) {}
729 xtw
.WriteStartElement ("foo");
730 xtw
.WriteStartAttribute ("bar", null);
731 AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='", StringWriterText
);
733 xtw
.WriteEndDocument ();
734 AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='' />", StringWriterText
);
735 AssertEquals (WriteState
.Start
, xtw
.WriteState
);
739 public void WriteEndElement ()
742 xtw
.WriteEndElement ();
743 Fail ("Should have thrown an InvalidOperationException.");
744 } catch (InvalidOperationException
) {
745 // Don't rely on English message assertion.
746 // It is enough to check an exception occurs.
747 // AssertEquals ("Exception message is incorrect.", "There was no XML start tag open.", e.Message);
750 xtw
.WriteStartElement ("foo");
751 xtw
.WriteEndElement ();
752 AssertEquals ("<foo />", StringWriterText
);
754 xtw
.WriteStartElement ("bar");
755 xtw
.WriteStartAttribute ("baz", null);
756 xtw
.WriteEndElement ();
757 AssertEquals ("<foo /><bar baz='' />", StringWriterText
);
761 public void FullEndElement ()
763 xtw
.WriteStartElement ("foo");
764 xtw
.WriteFullEndElement ();
765 AssertEquals ("<foo></foo>", StringWriterText
);
767 xtw
.WriteStartElement ("bar");
768 xtw
.WriteAttributeString ("foo", "bar");
769 xtw
.WriteFullEndElement ();
770 AssertEquals ("<foo></foo><bar foo='bar'></bar>", StringWriterText
);
772 xtw
.WriteStartElement ("baz");
773 xtw
.WriteStartAttribute ("bar", null);
774 xtw
.WriteFullEndElement ();
775 AssertEquals ("<foo></foo><bar foo='bar'></bar><baz bar=''></baz>", StringWriterText
);
779 public void WriteQualifiedName ()
781 xtw
.WriteStartElement (null, "test", null);
782 xtw
.WriteAttributeString ("xmlns", "me", null, "http://localhost/");
783 xtw
.WriteQualifiedName ("bob", "http://localhost/");
784 xtw
.WriteEndElement ();
786 AssertEquals ("<test xmlns:me='http://localhost/'>me:bob</test>", StringWriterText
);
790 public void WriteRaw ()
792 xtw
.WriteRaw("&<>\"'");
793 AssertEquals ("&<>\"'", StringWriterText
);
796 AssertEquals ("&<>\"'", StringWriterText
);
799 AssertEquals ("&<>\"'", StringWriterText
);
803 public void WriteRawInvalidInAttribute ()
805 xtw
.WriteStartElement ("foo");
806 xtw
.WriteStartAttribute ("bar", null);
807 xtw
.WriteRaw ("&<>\"'");
808 xtw
.WriteEndAttribute ();
809 xtw
.WriteEndElement ();
810 AssertEquals ("<foo bar='&<>\"'' />", StringWriterText
);
814 public void WriteStateTest ()
816 AssertEquals (WriteState
.Start
, xtw
.WriteState
);
817 xtw
.WriteStartDocument ();
818 AssertEquals (WriteState
.Prolog
, xtw
.WriteState
);
819 xtw
.WriteStartElement ("root");
820 AssertEquals (WriteState
.Element
, xtw
.WriteState
);
821 xtw
.WriteElementString ("foo", "bar");
822 AssertEquals (WriteState
.Content
, xtw
.WriteState
);
824 AssertEquals (WriteState
.Closed
, xtw
.WriteState
);
828 public void WriteString ()
830 xtw
.WriteStartDocument ();
832 xtw
.WriteString("foo");
833 } catch (InvalidOperationException
) {}
835 // Testing attribute values
837 xtw
.WriteStartElement ("foo");
838 xtw
.WriteAttributeString ("bar", "&<>");
839 AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='&<>'", StringWriterText
);
843 public void WriteAttributeStringSingleQuoteChar()
845 // When QuoteChar is single quote then replaces single quotes within attributes
846 // but not double quotes.
847 xtw
.WriteStartElement ("foo");
848 xtw
.WriteAttributeString ("bar", "\"baz\"");
849 xtw
.WriteAttributeString ("quux", "'baz'");
850 AssertEquals ("<foo bar='\"baz\"' quux=''baz''", StringWriterText
);
854 public void WriteAttributeStringDoubleQuoteChar()
856 // When QuoteChar is double quote then replaces double quotes within attributes
857 // but not single quotes.
859 xtw
.WriteStartElement ("foo");
860 xtw
.WriteAttributeString ("bar", "\"baz\"");
861 xtw
.WriteAttributeString ("quux", "'baz'");
862 AssertEquals ("<foo bar=\""baz"\" quux=\"'baz'\"", StringWriterText
);
866 public void WriteStringWithEntities()
868 // Testing element values
869 xtw
.QuoteChar
= '\'';
870 xtw
.WriteElementString ("foo", "&<>\"'");
871 AssertEquals ("<foo>&<>\"'</foo>", StringWriterText
);
875 public void XmlLang ()
877 AssertNull (xtw
.XmlLang
);
879 xtw
.WriteStartElement ("foo");
880 xtw
.WriteAttributeString ("xml", "lang", null, "langfoo");
881 AssertEquals ("langfoo", xtw
.XmlLang
);
882 AssertEquals ("<foo xml:lang='langfoo'", StringWriterText
);
884 xtw
.WriteAttributeString ("boo", "yah");
885 AssertEquals ("langfoo", xtw
.XmlLang
);
886 AssertEquals ("<foo xml:lang='langfoo' boo='yah'", StringWriterText
);
888 xtw
.WriteElementString("bar", "baz");
889 AssertEquals ("langfoo", xtw
.XmlLang
);
890 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>", StringWriterText
);
892 xtw
.WriteString("baz");
893 AssertEquals ("langfoo", xtw
.XmlLang
);
894 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz", StringWriterText
);
896 xtw
.WriteStartElement ("quux");
897 xtw
.WriteStartAttribute ("xml", "lang", null);
898 AssertEquals ("langfoo", xtw
.XmlLang
);
899 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", StringWriterText
);
901 xtw
.WriteString("langbar");
902 AssertEquals ("langfoo", xtw
.XmlLang
);
903 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", StringWriterText
);
905 xtw
.WriteEndAttribute ();
906 AssertEquals ("langbar", xtw
.XmlLang
);
907 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'", StringWriterText
);
909 // check if xml:lang repeats output even if same as current scope.
910 xtw
.WriteStartElement ("joe");
911 xtw
.WriteAttributeString ("xml", "lang", null, "langbar");
912 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'", StringWriterText
);
915 xtw
.WriteElementString ("quuux", "squonk");
916 AssertEquals ("langbar", xtw
.XmlLang
);
917 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux>", StringWriterText
);
919 xtw
.WriteEndElement ();
920 xtw
.WriteEndElement ();
921 AssertEquals ("langfoo", xtw
.XmlLang
);
922 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux></joe></quux>", StringWriterText
);
924 xtw
.WriteEndElement ();
925 AssertNull (xtw
.XmlLang
);
926 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux></joe></quux></foo>", StringWriterText
);
929 AssertNull (xtw
.XmlLang
);
932 // TODO: test operational aspects
934 public void XmlSpaceTest ()
936 xtw
.WriteStartElement ("foo");
937 AssertEquals (XmlSpace
.None
, xtw
.XmlSpace
);
939 xtw
.WriteStartElement ("bar");
940 xtw
.WriteAttributeString ("xml", "space", null, "preserve");
941 AssertEquals (XmlSpace
.Preserve
, xtw
.XmlSpace
);
942 AssertEquals ("<foo><bar xml:space='preserve'", StringWriterText
);
944 xtw
.WriteStartElement ("baz");
945 xtw
.WriteAttributeString ("xml", "space", null, "preserve");
946 AssertEquals (XmlSpace
.Preserve
, xtw
.XmlSpace
);
947 AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'", StringWriterText
);
949 xtw
.WriteStartElement ("quux");
950 xtw
.WriteStartAttribute ("xml", "space", null);
951 AssertEquals (XmlSpace
.Preserve
, xtw
.XmlSpace
);
952 AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", StringWriterText
);
954 xtw
.WriteString ("default");
955 AssertEquals (XmlSpace
.Preserve
, xtw
.XmlSpace
);
956 AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", StringWriterText
);
958 xtw
.WriteEndAttribute ();
959 AssertEquals (XmlSpace
.Default
, xtw
.XmlSpace
);
960 AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='default'", StringWriterText
);
962 xtw
.WriteEndElement ();
963 AssertEquals (XmlSpace
.Preserve
, xtw
.XmlSpace
);
964 xtw
.WriteEndElement ();
965 AssertEquals (XmlSpace
.Preserve
, xtw
.XmlSpace
);
966 xtw
.WriteEndElement ();
967 AssertEquals (XmlSpace
.None
, xtw
.XmlSpace
);
969 xtw
.WriteStartElement ("quux");
971 xtw
.WriteAttributeString ("xml", "space", null, "bubba");
972 } catch (ArgumentException
) {}
975 xtw
.WriteAttributeString ("xml", "space", null, "PRESERVE");
976 } catch (ArgumentException
) {}
979 xtw
.WriteAttributeString ("xml", "space", null, "Preserve");
980 } catch (ArgumentException
) {}
983 xtw
.WriteAttributeString ("xml", "space", null, "Default");
984 } catch (ArgumentException
) {}
987 xtw
.WriteWhitespace ("x");
988 } catch (ArgumentException
) { }
992 public void XmlSpaceRaw ()
994 xtw
.WriteStartElement ("foo");
995 xtw
.WriteStartAttribute ("xml", "space", null);
996 AssertEquals (XmlSpace
.None
, xtw
.XmlSpace
);
997 AssertEquals ("<foo xml:space='", StringWriterText
);
999 xtw
.WriteString ("default");
1000 AssertEquals (XmlSpace
.None
, xtw
.XmlSpace
);
1001 AssertEquals ("<foo xml:space='", StringWriterText
);
1003 xtw
.WriteEndAttribute ();
1004 AssertEquals (XmlSpace
.Default
, xtw
.XmlSpace
);
1005 AssertEquals ("<foo xml:space='default'", StringWriterText
);
1009 public void WriteAttributes ()
1011 XmlDocument doc
= new XmlDocument();
1012 StringWriter sw
= new StringWriter();
1013 XmlWriter wr
= new XmlTextWriter(sw
);
1014 StringBuilder sb
= sw
.GetStringBuilder();
1015 XmlParserContext ctx
= new XmlParserContext(doc
.NameTable
, new XmlNamespaceManager(doc
.NameTable
), "", XmlSpace
.Default
);
1016 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
);
1018 xtr
.Read(); // read XMLDecl
1019 wr
.WriteAttributes(xtr
, false);
1020 // This method don't always have to take this double-quoted style...
1021 AssertEquals("#WriteAttributes.XmlDecl.1", "version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"", sw
.ToString().Trim());
1023 sb
.Remove(0, sb
.Length
); // init
1024 ctx
= new XmlParserContext(doc
.NameTable
, new XmlNamespaceManager(doc
.NameTable
), "", XmlSpace
.Default
);
1025 xtr
= new XmlTextReader("<?xml version='1.0' standalone='no'?><root a1='A' b2='B' c3='C'><foo><bar /></foo></root>", XmlNodeType
.Document
, ctx
);
1026 xtr
.Read(); // read XMLDecl
1027 AssertEquals (XmlNodeType
.XmlDeclaration
, xtr
.NodeType
);
1028 sw
= new StringWriter ();
1029 wr
= new XmlTextWriter (sw
);
1031 // This block raises an error on MS.NET 1.0.
1032 wr
.WriteAttributes(xtr
, false);
1033 // This method don't always have to take this double-quoted style...
1034 AssertEquals("#WriteAttributes.XmlDecl.2", "version=\"1.0\" standalone=\"no\"", sw
.ToString().Trim());
1036 sw
= new StringWriter ();
1037 wr
= new XmlTextWriter (sw
);
1038 sb
.Remove(0, sb
.Length
); // init
1040 xtr
.Read(); // read root
1041 AssertEquals (XmlNodeType
.Element
, xtr
.NodeType
);
1042 wr
.WriteStartElement(xtr
.LocalName
, xtr
.NamespaceURI
);
1043 wr
.WriteAttributes(xtr
, false);
1044 wr
.WriteEndElement();
1046 // This method don't always have to take this double-quoted style...
1047 AssertEquals("#WriteAttributes.Element", "<root a1=\"A\" b2=\"B\" c3=\"C\" />", sw
.ToString().Trim());
1052 public void WriteWhitespace ()
1054 xtw
.WriteStartElement ("a");
1055 xtw
.WriteWhitespace ("\n\t");
1056 xtw
.WriteStartElement ("b");
1057 xtw
.WriteWhitespace ("\n\t");
1058 xtw
.WriteEndElement ();
1059 xtw
.WriteWhitespace ("\n");
1060 xtw
.WriteEndElement ();
1061 xtw
.WriteWhitespace ("\n");
1063 AssertEquals ("<a>\n\t<b>\n\t</b>\n</a>\n", StringWriterText
);
1067 public void FlushDoesntCloseTag ()
1069 xtw
.WriteStartElement ("foo");
1070 xtw
.WriteAttributeString ("bar", "baz");
1072 AssertEquals ("<foo bar='baz'", StringWriterText
);
1076 public void WriteWhitespaceClosesTag ()
1078 xtw
.WriteStartElement ("foo");
1079 xtw
.WriteAttributeString ("bar", "baz");
1080 xtw
.WriteWhitespace (" ");
1081 AssertEquals ("<foo bar='baz'> ", StringWriterText
);
1085 public void DontOutputMultipleXmlns ()
1087 XmlDocument doc
= new XmlDocument();
1088 doc
.LoadXml("<a xmlns:dt=\"b\" dt:dt=\"c\"/>");
1089 XmlDocument doc2
= new XmlDocument();
1090 doc2
.LoadXml(doc
.InnerXml
);
1091 AssertEquals ("<a xmlns:dt=\"b\" dt:dt=\"c\" />",
1096 public void DontOutputNonDeclaredXmlns ()
1098 string xml
= "<x:a foo='foo' xmlns:x='urn:foo'><b /></x:a>";
1099 XmlDocument doc
= new XmlDocument();
1101 XmlDocument doc2
= new XmlDocument();
1102 doc2
.LoadXml(doc
.InnerXml
);
1103 AssertEquals (xml
.Replace ('\'', '"'), doc2
.OuterXml
);
1107 public void DontOutputRemovalDefaultNSDeclaration ()
1109 xtw
.WriteStartDocument ();
1110 xtw
.WriteStartElement ("foo");
1111 xtw
.WriteAttributeString ("xmlns", "probe");
1112 AssertEquals (String
.Empty
, xtw
.LookupPrefix ("probe"));
1113 xtw
.WriteStartElement ("b");
1114 AssertEquals (String
.Empty
, xtw
.LookupPrefix ("probe"));
1115 xtw
.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""
1116 xtw
.WriteEndElement (); // b2
1117 xtw
.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""
1118 xtw
.WriteEndElement (); // b2
1119 xtw
.WriteEndElement (); // b
1120 xtw
.WriteEndElement (); // foo
1121 xtw
.WriteEndDocument ();
1124 AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 xmlns='' /></b></foo>", StringWriterText
);
1128 public void DontOutputRemovalDefaultNSDeclaration2 ()
1130 xtw
.WriteStartDocument ();
1131 // IMPORTANT DIFFERENCE!! ns = "", not null
1132 xtw
.WriteStartElement ("foo", "");
1133 xtw
.WriteAttributeString ("xmlns", "probe");
1134 AssertNull (xtw
.LookupPrefix ("probe"));
1135 xtw
.WriteStartElement ("b");
1136 AssertNull (xtw
.LookupPrefix ("probe"));
1137 xtw
.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""
1138 xtw
.WriteEndElement (); // b2
1139 xtw
.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""
1140 xtw
.WriteEndElement (); // b2
1141 xtw
.WriteEndElement (); // b
1142 xtw
.WriteEndElement (); // foo
1143 xtw
.WriteEndDocument ();
1146 AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 /></b></foo>", StringWriterText
);
1150 public void DoOutputRemovalDefaultNSDeclaration ()
1152 xtw
.WriteStartElement ("docelem", "a-namespace");
1154 XmlDocument doc
= new XmlDocument ();
1155 doc
.CreateElement ("hola").WriteTo (xtw
);
1156 // This means, WriteTo never passes null NamespaceURI argument to XmlWriter.
1157 xtw
.WriteEndElement ();
1160 AssertEquals ("<docelem xmlns='a-namespace'><hola xmlns='' /></docelem>", StringWriterText
);
1164 public void WriteAttributeTakePrecedenceOnXmlns ()
1166 xtw
.WriteStartElement ("root", "urn:foo");
1167 xtw
.WriteAttributeString ("xmlns", "urn:bar");
1168 xtw
.WriteEndElement ();
1170 AssertEquals ("<root xmlns='urn:bar' />", StringWriterText
);
1174 [ExpectedException (typeof (ArgumentException
))]
1175 public void LookupPrefixNull ()
1177 xtw
.LookupPrefix (null);
1181 [ExpectedException (typeof (ArgumentException
))]
1182 public void LookupPrefixEmpty ()
1184 xtw
.LookupPrefix (String
.Empty
);
1188 public void LookupPrefixIgnoresXmlnsAttribute ()
1190 AssertNull (xtw
.LookupPrefix ("urn:foo"));
1191 xtw
.WriteStartElement ("root");
1192 AssertNull (xtw
.LookupPrefix ("urn:foo"));
1193 xtw
.WriteAttributeString ("xmlns", "urn:foo");
1194 // Surprisingly to say, it is ignored!!
1195 AssertEquals (String
.Empty
, xtw
.LookupPrefix ("urn:foo"));
1196 xtw
.WriteStartElement ("hoge");
1197 // (still after flushing previous start element.)
1198 AssertEquals (String
.Empty
, xtw
.LookupPrefix ("urn:foo"));
1199 xtw
.WriteStartElement ("fuga", "urn:foo");
1200 // Is this testing on the correct way? Yes, here it is.
1201 AssertEquals (String
.Empty
, xtw
.LookupPrefix ("urn:foo"));
1205 public void WriteInvalidNames ()
1207 xtw
.WriteStartElement ("foo<>");
1208 xtw
.WriteAttributeString ("ho<>ge", "value");
1212 [ExpectedException (typeof (ArgumentException
))]
1213 public void AttributeWriteStartAttributePrefixWithoutNS ()
1215 xtw
.WriteStartAttribute ("some", "foo", null);
1219 public void AttributeWriteStartAttributeXmlnsNullNS ()
1221 xtw
.WriteStartAttribute ("xmlns", "foo", null);
1225 [ExpectedException (typeof (ArgumentException
))]
1226 public void AttributeWriteEndAttributeXmlnsNullNs ()
1228 // Compare with the test AttributeWriteStartAttributeXmlnsNullNS().
1229 xtw
.WriteStartAttribute ("xmlns", "foo", null);
1230 xtw
.WriteEndAttribute ();
1234 [ExpectedException (typeof (ArgumentException
))]
1235 public void AttributeWriteStartAttributePrefixXmlnsNonW3CNS ()
1237 xtw
.WriteStartAttribute ("xmlns", "foo", "urn:foo");
1241 [ExpectedException (typeof (ArgumentException
))]
1242 public void AttributeWriteStartAttributeLocalXmlnsNonW3CNS ()
1244 xtw
.WriteStartAttribute ("", "xmlns", "urn:foo");
1248 public void WriteRawProceedToProlog ()
1250 XmlTextWriter xtw
= new XmlTextWriter (new StringWriter ());
1252 AssertEquals (WriteState
.Prolog
, xtw
.WriteState
);
1256 public void Indent ()
1258 XmlDocument doc
= new XmlDocument ();
1259 doc
.LoadXml ("<root><test>test<foo></foo>string</test><test>string</test></root>");
1260 StringWriter sw
= new StringWriter ();
1262 XmlTextWriter xtw
= new XmlTextWriter (sw
);
1263 xtw
.Formatting
= Formatting
.Indented
;
1264 doc
.WriteContentTo (xtw
);
1265 AssertEquals (@"<root>_ <test>test<foo></foo>string</test>_ <test>string</test>_</root>", sw
.ToString ());
1269 public void CloseTwice ()
1271 StringWriter sw
= new StringWriter ();
1272 XmlTextWriter writer
= new XmlTextWriter (sw
);
1274 // should not result in an exception