diff options
-rw-r--r-- | mcs/class/System.XML/Mono.System.XML.csproj | 5 | ||||
-rw-r--r-- | mcs/class/System.XML/System.Xml/ChangeLog | 16 | ||||
-rw-r--r-- | mcs/class/System.XML/System.Xml/XmlNodeListChildren.cs | 2 | ||||
-rw-r--r-- | mcs/class/System.XML/System.Xml/XmlTextWriter.cs | 122 | ||||
-rw-r--r-- | mcs/class/System.XML/Test/ChangeLog | 8 | ||||
-rw-r--r-- | mcs/class/System.XML/Test/XmlTextWriterTests.cs | 106 |
6 files changed, 233 insertions, 26 deletions
diff --git a/mcs/class/System.XML/Mono.System.XML.csproj b/mcs/class/System.XML/Mono.System.XML.csproj index 1d730000fe7..3bcb502777d 100644 --- a/mcs/class/System.XML/Mono.System.XML.csproj +++ b/mcs/class/System.XML/Mono.System.XML.csproj @@ -316,6 +316,11 @@ BuildAction = "Compile" /> <File + RelPath = "System.Xml\XmlTextWriterOpenElement.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "System.Xml\XmlTokenizedType.cs" SubType = "Code" BuildAction = "Compile" diff --git a/mcs/class/System.XML/System.Xml/ChangeLog b/mcs/class/System.XML/System.Xml/ChangeLog index db6058fb974..74aef79615f 100644 --- a/mcs/class/System.XML/System.Xml/ChangeLog +++ b/mcs/class/System.XML/System.Xml/ChangeLog @@ -1,3 +1,19 @@ +2002-03-23 Kral Ferch <kral_ferch@hotmail.com> + + * XmlNodeListChildren.cs: made class internal + instead of public. Shouldn't be visible outside + of System.Xml. + + * XmlTextWriter.cs: Implementations for Formatting, + IndentChar, Indenting, QuoteChar, WriteStartDocument(standalone). + Suppresses encoding on xml declaration if null stream passed in. + Formats output including suppressing indentation for elements in + mixed content mode. + + * XmlTextWriterOpenElement.cs: Initial checkin. + XmlTextWriter uses stack of these objects to track + state. + 2002-03-22 Mike Kestner <mkestner@speakeasy.net> * XmlElement.cs: impl HasAttribute(string name). diff --git a/mcs/class/System.XML/System.Xml/XmlNodeListChildren.cs b/mcs/class/System.XML/System.Xml/XmlNodeListChildren.cs index ad462577804..c5d62823503 100644 --- a/mcs/class/System.XML/System.Xml/XmlNodeListChildren.cs +++ b/mcs/class/System.XML/System.Xml/XmlNodeListChildren.cs @@ -12,7 +12,7 @@ using System.Collections; namespace System.Xml { - public class XmlNodeListChildren : XmlNodeList + internal class XmlNodeListChildren : XmlNodeList { #region Enumerator diff --git a/mcs/class/System.XML/System.Xml/XmlTextWriter.cs b/mcs/class/System.XML/System.Xml/XmlTextWriter.cs index 38eaee5d552..f88e20f6a72 100644 --- a/mcs/class/System.XML/System.Xml/XmlTextWriter.cs +++ b/mcs/class/System.XML/System.Xml/XmlTextWriter.cs @@ -19,11 +19,19 @@ namespace System.Xml #region Fields protected TextWriter w; + protected bool nullEncoding = false; protected bool openWriter = true; protected bool openStartElement; protected bool documentStarted = false; protected Stack openElements = new Stack (); protected XmlNamespaceManager namespaceManager = new XmlNamespaceManager (new NameTable ()); + protected Formatting formatting = Formatting.None; + protected int indentation = 2; + protected char indentChar = ' '; + protected string indentChars = " "; + protected char quoteChar = '\"'; + protected int indentLevel = 0; + protected string indentFormatting; #endregion @@ -36,6 +44,11 @@ namespace System.Xml public XmlTextWriter (Stream w, Encoding encoding) : base () { + if (encoding == null) { + nullEncoding = true; + encoding = new UTF8Encoding (); + } + this.w = new StreamWriter(w, encoding); } @@ -54,22 +67,39 @@ namespace System.Xml } - [MonoTODO] public Formatting Formatting { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } + get { return formatting; } + set { formatting = value; } + } + + public bool IndentingOverriden + { + get { + if (openElements.Count == 0) + return false; + else + return (((XmlTextWriterOpenElement)openElements.Peek()).IndentingOverriden); + } + set { + if (openElements.Count > 0) + ((XmlTextWriterOpenElement)openElements.Peek()).IndentingOverriden = value; + } } - [MonoTODO] public int Indentation { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } + get { return indentation; } + set { + indentation = value; + UpdateIndentChars (); + } } - [MonoTODO] public char IndentChar { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } + get { return indentChar; } + set { + indentChar = value; + UpdateIndentChars (); + } } [MonoTODO] @@ -80,8 +110,13 @@ namespace System.Xml [MonoTODO] public char QuoteChar { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } + get { return quoteChar; } + set { + if ((value != '\'') && (value != '\"')) + throw new ArgumentException ("This is an invalid XML attribute quote character. Valid attribute quote characters are ' and \"."); + + quoteChar = value; + } } [MonoTODO] @@ -109,6 +144,16 @@ namespace System.Xml throw new InvalidOperationException ("The Writer is closed."); } + if ((documentStarted == true) && (formatting == Formatting.Indented) && (!IndentingOverriden)) { + indentFormatting = "\r\n"; + if (indentLevel > 0) { + for (int i = 0; i < indentLevel; i++) + indentFormatting += indentChars; + } + } + else + indentFormatting = ""; + documentStarted = true; } @@ -132,10 +177,9 @@ namespace System.Xml } } - [MonoTODO] public override void Flush () { - throw new NotImplementedException (); + w.Flush (); } [MonoTODO] @@ -144,6 +188,13 @@ namespace System.Xml throw new NotImplementedException (); } + private void UpdateIndentChars () + { + indentChars = ""; + for (int i = 0; i < indentation; i++) + indentChars += indentChar; + } + [MonoTODO] public override void WriteBase64 (byte[] buffer, int index, int count) { @@ -216,6 +267,8 @@ namespace System.Xml if (openElements.Count == 0) throw new InvalidOperationException("There was no XML start tag open."); + indentLevel--; + CheckState (); if (openStartElement) { @@ -224,7 +277,7 @@ namespace System.Xml openStartElement = false; } else { - w.Write ("</{0}>", openElements.Pop ()); + w.Write ("{0}</{1}>", indentFormatting, openElements.Pop ()); namespaceManager.PopScope(); } } @@ -262,7 +315,7 @@ namespace System.Xml CheckState (); CloseStartElement (); - w.Write ("<?{0} {1}?>", name, text); + w.Write ("{0}<?{1} {2}?>", indentFormatting, name, text); } [MonoTODO] @@ -291,19 +344,34 @@ namespace System.Xml public override void WriteStartDocument () { - if (documentStarted == true) { - throw new InvalidOperationException("WriteStartDocument should be the first call."); - } + WriteStartDocument (""); + } - CheckState (); + public override void WriteStartDocument (bool standalone) + { + string standaloneFormatting; + + if (standalone == true) + standaloneFormatting = " standalone=\"yes\""; + else + standaloneFormatting = " standalone=\"no\""; - w.Write("<?xml version=\"1.0\" encoding=\"" + w.Encoding.HeaderName + "\"?>"); + WriteStartDocument (standaloneFormatting); } - [MonoTODO] - public override void WriteStartDocument (bool standalone) + private void WriteStartDocument (string standaloneFormatting) { - throw new NotImplementedException (); + if (documentStarted == true) + throw new InvalidOperationException("WriteStartDocument should be the first call."); + + CheckState (); + + string encodingFormatting = ""; + + if (!nullEncoding) + encodingFormatting = " encoding=\"" + w.Encoding.HeaderName + "\""; + + w.Write("<?xml version=\"1.0\"{0}{1}?>", encodingFormatting, standaloneFormatting); } public override void WriteStartElement (string prefix, string localName, string ns) @@ -337,13 +405,15 @@ namespace System.Xml formatPrefix = prefix + ":"; } - w.Write ("<{0}{1}{2}", formatPrefix, localName, formatXmlns); + w.Write ("{0}<{1}{2}{3}", indentFormatting, formatPrefix, localName, formatXmlns); - openElements.Push (formatPrefix + localName); + openElements.Push (new XmlTextWriterOpenElement (formatPrefix + localName)); openStartElement = true; namespaceManager.PushScope (); namespaceManager.AddNamespace (prefix, ns); + + indentLevel++; } [MonoTODO("Haven't done any entity replacements yet.")] @@ -354,6 +424,8 @@ namespace System.Xml CloseStartElement (); w.Write (text); } + + IndentingOverriden = true; } [MonoTODO] diff --git a/mcs/class/System.XML/Test/ChangeLog b/mcs/class/System.XML/Test/ChangeLog index bf710249c65..2bd719d4050 100644 --- a/mcs/class/System.XML/Test/ChangeLog +++ b/mcs/class/System.XML/Test/ChangeLog @@ -1,3 +1,11 @@ +2002-03-23 Kral Ferch <kral_ferch@hotmail.com> + + * XmlTextWriterTests.cs: constructor tests with + different encodings to test that encoding gets suppressed + on xml declaration when null stream passed to constructor. + WriteStartDocument(standalone) tests. Tests for formatting + and indentation. Test for invalid value set on QuoteChar. + 2002-03-22 Duncan Mak <duncan@ximian.com> * AllTests.cs: diff --git a/mcs/class/System.XML/Test/XmlTextWriterTests.cs b/mcs/class/System.XML/Test/XmlTextWriterTests.cs index 1cd2aa83bfb..805ae83a899 100644 --- a/mcs/class/System.XML/Test/XmlTextWriterTests.cs +++ b/mcs/class/System.XML/Test/XmlTextWriterTests.cs @@ -9,6 +9,7 @@ using System; using System.IO; +using System.Text; using System.Xml; using NUnit.Framework; @@ -125,6 +126,53 @@ namespace Ximian.Mono.Tests catch (ArgumentException) { } } + public void TestConstructors () + { + MemoryStream ms; + StreamReader sr; + XmlTextWriter xtw; + + ms = new MemoryStream (); + xtw = new XmlTextWriter (ms, new UnicodeEncoding ()); + xtw.WriteStartDocument (); + xtw.Flush (); + ms.Seek (0, SeekOrigin.Begin); + sr = new StreamReader (ms); + AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", sr.ReadToEnd ()); + + ms = new MemoryStream (); + xtw = new XmlTextWriter (ms, new UnicodeEncoding ()); + xtw.WriteStartDocument (true); + xtw.Flush (); + ms.Seek (0, SeekOrigin.Begin); + sr = new StreamReader (ms); + AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?>", sr.ReadToEnd ()); + + ms = new MemoryStream (); + xtw = new XmlTextWriter (ms, new UTF8Encoding ()); + xtw.WriteStartDocument (); + xtw.Flush (); + ms.Seek (0, SeekOrigin.Begin); + sr = new StreamReader (ms); + AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-8\"?>", sr.ReadToEnd ()); + + ms = new MemoryStream (); + xtw = new XmlTextWriter (ms, null); + xtw.WriteStartDocument (); + xtw.Flush (); + ms.Seek (0, SeekOrigin.Begin); + sr = new StreamReader (ms); + AssertEquals ("<?xml version=\"1.0\"?>", sr.ReadToEnd ()); + + ms = new MemoryStream (); + xtw = new XmlTextWriter (ms, null); + xtw.WriteStartDocument (true); + xtw.Flush (); + ms.Seek (0, SeekOrigin.Begin); + sr = new StreamReader (ms); + AssertEquals ("<?xml version=\"1.0\" standalone=\"yes\"?>", sr.ReadToEnd ()); + } + public void TestDocumentStart () { xtw.WriteStartDocument (); @@ -140,6 +188,16 @@ namespace Ximian.Mono.Tests AssertEquals ("Exception message is incorrect.", "WriteStartDocument should be the first call.", e.Message); } + + xtw = new XmlTextWriter (sw = new StringWriter ()); + xtw.WriteStartDocument (true); + AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?>", + sw.GetStringBuilder ().ToString ()); + + xtw = new XmlTextWriter (sw = new StringWriter ()); + xtw.WriteStartDocument (false); + AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"no\"?>", + sw.GetStringBuilder ().ToString ()); } public void TestElementEmpty () @@ -155,6 +213,46 @@ namespace Ximian.Mono.Tests AssertEquals ("WriteElementString has incorrect output.", "<foo>bar</foo>", sw.GetStringBuilder().ToString()); } + public void TestFormatting () + { + xtw.Formatting = Formatting.Indented; + xtw.WriteStartDocument (); + xtw.WriteStartElement ("foo"); + xtw.WriteElementString ("bar", ""); + xtw.Close (); + AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<foo>\r\n <bar />\r\n</foo>", + sw.GetStringBuilder ().ToString ()); + } + + public void TestFormattingInvalidXmlForFun () + { + xtw.Formatting = Formatting.Indented; + xtw.IndentChar = 'x'; + xtw.WriteStartDocument (); + xtw.WriteStartElement ("foo"); + xtw.WriteStartElement ("bar"); + xtw.WriteElementString ("baz", ""); + xtw.Close (); + AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<foo>\r\nxx<bar>\r\nxxxx<baz />\r\nxx</bar>\r\n</foo>", + sw.GetStringBuilder ().ToString ()); + } + + public void TestFormattingFromRemarks () + { + // Remarks section of on-line help for XmlTextWriter.Formatting suggests this test. + xtw.Formatting = Formatting.Indented; + xtw.WriteStartElement ("ol"); + xtw.WriteStartElement ("li"); + xtw.WriteString ("The big "); // This means "li" now has a mixed content model. + xtw.WriteElementString ("b", "E"); + xtw.WriteElementString ("i", "lephant"); + xtw.WriteString (" walks slowly."); + xtw.WriteEndElement (); + xtw.WriteEndElement (); + AssertEquals ("<ol>\r\n <li>The big <b>E</b><i>lephant</i> walks slowly.</li>\r\n</ol>", + sw.GetStringBuilder ().ToString ()); + } + public void TestProcessingInstructionValid () { xtw.WriteProcessingInstruction("foo", "bar"); @@ -220,6 +318,14 @@ namespace Ximian.Mono.Tests } } + public void TestQuoteCharInvalid () + { + try { + xtw.QuoteChar = 'x'; + Fail ("Should have thrown an ArgumentException."); + } catch (ArgumentException) {} + } + public void TestWriteEndElement () { try |