X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.XML%2FSystem.Xml%2FXmlTextWriter.cs;h=3f6c19e29841cd6cd77cfe291943e82d5c6c3f45;hb=f8abecbb7fc52d6d161dd3a9155437ca4440d72f;hp=c0958b8348d3bbf4a55833303ff0e30725173c60;hpb=ad41847caaa5fe7bc69771b0af206b235d24d339;p=mono.git diff --git a/mcs/class/System.XML/System.Xml/XmlTextWriter.cs b/mcs/class/System.XML/System.Xml/XmlTextWriter.cs index c0958b8348d..3f6c19e2984 100644 --- a/mcs/class/System.XML/System.Xml/XmlTextWriter.cs +++ b/mcs/class/System.XML/System.Xml/XmlTextWriter.cs @@ -40,6 +40,9 @@ namespace System.Xml XmlSpace xmlSpace = XmlSpace.None; bool openXmlLang = false; bool openXmlSpace = false; + string openElementPrefix; + string openElementNS; + bool hasRoot = false; #endregion @@ -67,10 +70,9 @@ namespace System.Xml baseStream = w; } - public XmlTextWriter (string filename, Encoding encoding) : base () + public XmlTextWriter (string filename, Encoding encoding) : + this (new FileStream (filename, FileMode.Create, FileAccess.Write, FileShare.None), encoding) { - this.w = new StreamWriter(filename, false, encoding); - baseStream = ((StreamWriter)w).BaseStream; } #endregion @@ -176,6 +178,44 @@ namespace System.Xml #endregion #region Methods + private void AddMissingElementXmlns () + { + // output namespace declaration if not exist. + string prefix = openElementPrefix; + string ns = openElementNS; + if (ns != null/* && LookupPrefix (ns) != prefix*/) + { + string formatXmlns = String.Empty; + if (ns != String.Empty) + { + string existingPrefix = namespaceManager.LookupPrefix (ns); + bool addDefaultNamespace = false; + + if (existingPrefix == null) + { + namespaceManager.AddNamespace (prefix, ns); + addDefaultNamespace = true; + } + + if (prefix == String.Empty) + prefix = existingPrefix; + + if (prefix != existingPrefix) + formatXmlns = String.Format (" xmlns:{0}={1}{2}{1}", prefix, quoteChar, ns); + else if (addDefaultNamespace) + formatXmlns = String.Format (" xmlns={0}{1}{0}", quoteChar, ns); + } + else if ((prefix == String.Empty) && (namespaceManager.LookupNamespace (prefix) != String.Empty)) + { + namespaceManager.AddNamespace (prefix, ns); + formatXmlns = String.Format (" xmlns={0}{0}", quoteChar); + } + if(formatXmlns != String.Empty) + w.Write(formatXmlns); + openElementPrefix = null; + openElementNS = null; + } + } private void CheckState () { @@ -183,7 +223,7 @@ namespace System.Xml throw new InvalidOperationException ("The Writer is closed."); } if ((documentStarted == true) && (formatting == Formatting.Indented) && (!IndentingOverriden)) { - indentFormatting = "\r\n"; + indentFormatting = w.NewLine; if (indentLevel > 0) { for (int i = 0; i < indentLevel; i++) indentFormatting += indentChars; @@ -216,12 +256,15 @@ namespace System.Xml private void CloseStartElement () { - if (openStartElement) { - w.Write(">"); - ws = WriteState.Content; - openStartElement = false; - attributeWrittenForElement = false; - } + if (!openStartElement) + return; + + AddMissingElementXmlns (); + + w.Write (">"); + ws = WriteState.Content; + openStartElement = false; + attributeWrittenForElement = false; } public override void Flush () @@ -233,9 +276,10 @@ namespace System.Xml { string prefix = namespaceManager.LookupPrefix (ns); - if (prefix == String.Empty) - prefix = null; - + // XmlNamespaceManager has changed to return null when NSURI not found. + // (Contradiction to the documentation.) + //if (prefix == String.Empty) + // prefix = null; return prefix; } @@ -298,10 +342,23 @@ namespace System.Xml w.Write ("", text); } - [MonoTODO] public override void WriteDocType (string name, string pubid, string sysid, string subset) { - throw new NotImplementedException (); + if (name == null || name.Trim ().Length == 0) + throw new ArgumentException ("Invalid DOCTYPE name", "name"); + + w.Write ("'); } public override void WriteEndAttribute () @@ -331,12 +388,13 @@ namespace System.Xml public override void WriteEndDocument () { - if ((ws == WriteState.Start) || (ws == WriteState.Prolog)) - throw new ArgumentException ("This document does not have a root element."); - CloseOpenAttributeAndElements (); + if (!hasRoot) + throw new ArgumentException ("This document does not have a root element."); + ws = WriteState.Start; + hasRoot = false; } public override void WriteEndElement () @@ -351,6 +409,7 @@ namespace System.Xml indentLevel--; CheckState (); + AddMissingElementXmlns (); if (openStartElement) { if (openAttribute) @@ -380,16 +439,25 @@ namespace System.Xml WriteEndElementInternal (true); } - [MonoTODO] + private void CheckValidChars (string name, bool firstOnlyLetter) + { + foreach (char c in name) { + if (XmlConvert.IsInvalid (c, firstOnlyLetter)) + throw new ArgumentException ("There is an invalid character: '" + c + + "'", "name"); + } + } + public override void WriteName (string name) { - throw new NotImplementedException (); + CheckValidChars (name, true); + w.Write (name); } - [MonoTODO] public override void WriteNmToken (string name) { - throw new NotImplementedException (); + CheckValidChars (name, false); + w.Write (name); } public override void WriteProcessingInstruction (string name, string text) @@ -419,10 +487,9 @@ namespace System.Xml WriteStringInternal (data, false); } - [MonoTODO] public override void WriteRaw (char[] buffer, int index, int count) { - throw new NotImplementedException (); + WriteStringInternal (new string (buffer, index, count), false); } public override void WriteStartAttribute (string prefix, string localName, string ns) @@ -455,7 +522,8 @@ namespace System.Xml string existingPrefix = namespaceManager.LookupPrefix (ns); if (prefix == String.Empty) - prefix = existingPrefix; + prefix = (existingPrefix == null) ? + String.Empty : existingPrefix; } if (prefix != String.Empty) @@ -495,6 +563,11 @@ namespace System.Xml if (documentStarted == true) throw new InvalidOperationException("WriteStartDocument should be the first call."); + if (hasRoot) + throw new XmlException ("WriteStartDocument called twice."); + + hasRoot = true; + CheckState (); string encodingFormatting = ""; @@ -517,39 +590,23 @@ namespace System.Xml private void WriteStartElementInternal (string prefix, string localName, string ns) { - if (prefix == null) - prefix = String.Empty; - - if ((prefix != String.Empty) && ((ns == null) || (ns == String.Empty))) + if ((prefix != null && prefix != String.Empty) && ((ns == null) || (ns == String.Empty))) throw new ArgumentException ("Cannot use a prefix with an empty namespace."); CheckState (); CloseStartElement (); + if (prefix == null) + prefix = namespaceManager.LookupPrefix (ns); + if (prefix == null) + prefix = String.Empty; + string formatXmlns = ""; string formatPrefix = ""; - if(ns != null) - { - if (ns != String.Empty) - { - string existingPrefix = namespaceManager.LookupPrefix (ns); - - if (prefix == String.Empty) - prefix = existingPrefix; - - if (prefix != existingPrefix) - formatXmlns = String.Format (" xmlns:{0}={1}{2}{1}", prefix, quoteChar, ns); - else if (existingPrefix == String.Empty) - formatXmlns = String.Format (" xmlns={0}{1}{0}", quoteChar, ns); - } - else if ((prefix == String.Empty) && (namespaceManager.LookupNamespace(prefix) != String.Empty)) { - formatXmlns = String.Format (" xmlns={0}{0}", quoteChar); - } - - if (prefix != String.Empty) { + if(ns != null) { + if (prefix != String.Empty) formatPrefix = prefix + ":"; - } } w.Write ("{0}<{1}{2}{3}", indentFormatting, formatPrefix, localName, formatXmlns); @@ -558,12 +615,12 @@ namespace System.Xml openElements.Push (new XmlTextWriterOpenElement (formatPrefix + localName)); ws = WriteState.Element; openStartElement = true; + openElementNS = ns; + openElementPrefix = prefix; namespaceManager.PushScope (); - if(ns != null) - { - namespaceManager.AddNamespace (prefix, ns); - } +// if(ns != null) +// namespaceManager.AddNamespace (prefix, ns); indentLevel++; }