//
// (C) 2002 Kral Ferch
// (C) 2002-2003 Atsushi Enomoto
+// (C) 2004-2007 Novell, Inc.
//
//
//
using System;
+using System.Collections;
using System.IO;
using System.Text;
-#if NET_2_0
+#if !MOONLIGHT
using System.Xml.XPath;
#endif
namespace System.Xml
{
-#if NET_2_0
public abstract class XmlWriter : IDisposable
-#else
- public abstract class XmlWriter
-#endif
{
#if NET_2_0
XmlWriterSettings settings;
#if NET_2_0
public virtual XmlWriterSettings Settings {
- get {
- if (settings == null)
- settings = new XmlWriterSettings ();
- return settings;
- }
+ get { return settings; }
}
#endif
public static XmlWriter Create (string file, XmlWriterSettings settings)
{
Encoding enc = settings != null ? settings.Encoding : Encoding.UTF8;
- return Create (new StreamWriter (file, false, enc), settings);
+ return CreateTextWriter (new StreamWriter (file, false, enc), settings, true);
}
public static XmlWriter Create (StringBuilder builder, XmlWriterSettings settings)
public static XmlWriter Create (TextWriter writer, XmlWriterSettings settings)
{
- return CreateTextWriter (writer, settings);
+ if (settings == null)
+ settings = new XmlWriterSettings ();
+ return CreateTextWriter (writer, settings, settings.CloseOutput);
}
public static XmlWriter Create (XmlWriter writer, XmlWriterSettings settings)
{
if (settings == null)
settings = new XmlWriterSettings ();
- writer.settings = settings;
+ else
+ settings = settings.Clone ();
+
+ var src = writer.Settings;
+ if (src == null) {
+ settings.ConformanceLevel = ConformanceLevel.Document; // Huh? Why??
+ writer = new DefaultXmlWriter (writer);
+ writer.settings = settings;
+ } else {
+ ConformanceLevel dst = src.ConformanceLevel;
+ switch (src.ConformanceLevel) {
+ case ConformanceLevel.Auto:
+ dst = settings.ConformanceLevel;
+ break;
+ case ConformanceLevel.Document:
+ case ConformanceLevel.Fragment:
+ if (settings.ConformanceLevel != ConformanceLevel.Auto)
+ dst = settings.ConformanceLevel;
+ break;
+ }
+
+ settings.MergeFrom (src);
+
+ // It returns a new XmlWriter instance if 1) Settings is null, or 2) Settings ConformanceLevel (or might be other members as well) give significant difference.
+ if (src.ConformanceLevel != dst) {
+ writer = new DefaultXmlWriter (writer, false);
+ writer.settings = settings;
+ }
+ }
+
return writer;
}
- private static XmlWriter CreateTextWriter (TextWriter writer, XmlWriterSettings settings)
+ private static XmlWriter CreateTextWriter (TextWriter writer, XmlWriterSettings settings, bool closeOutput)
{
if (settings == null)
settings = new XmlWriterSettings ();
- XmlTextWriter xtw = new XmlTextWriter (writer);
- // Indent, IndentChars
- if (settings.Indent) {
- xtw.Formatting = Formatting.Indented;
- xtw.IndentChars = settings.IndentChars;
- xtw.NewLineOnAttributes = settings.NewLineOnAttributes;
- }
- // NewLineChars
- xtw.NewLineChars = settings.NewLineChars;
- // CloseOutput
- xtw.CloseOutput = settings.CloseOutput;
- // ConformanceLevel
- xtw.ConformanceLevel = settings.ConformanceLevel;
- // OmitXmlDeclaration
- xtw.OmitXmlDeclaration = settings.OmitXmlDeclaration;
- // CheckCharacters
- xtw.CheckCharacters = settings.CheckCharacters;
+ XmlTextWriter xtw = new XmlTextWriter (writer, settings, closeOutput);
return Create (xtw, settings);
}
return;
WriteStartAttribute (reader.Prefix, reader.LocalName, reader.NamespaceURI);
+#if MOONLIGHT
+ // no ReadAttributeValue() in 2.1 profile.
+ WriteString (reader.Value);
+#else
while (reader.ReadAttributeValue ()) {
switch (reader.NodeType) {
case XmlNodeType.Text:
break;
}
}
+#endif
WriteEndAttribute ();
}
WriteString (localName);
}
-#if NET_2_0
- [MonoTODO ("test defattr handling")]
+#if !MOONLIGHT
public virtual void WriteNode (XPathNavigator navigator, bool defattr)
{
if (navigator == null)
throw new ArgumentNullException ("navigator");
switch (navigator.NodeType) {
case XPathNodeType.Attribute:
+ // no operation
+ break;
case XPathNodeType.Namespace:
- if (defattr || navigator.SchemaInfo == null ||
- !navigator.SchemaInfo.IsDefault)
- WriteAttributeString (navigator.Prefix,
- navigator.LocalName,
- navigator.NamespaceURI,
- navigator.Value);
+ // no operation
break;
case XPathNodeType.Text:
WriteString (navigator.Value);
WriteStartElement (navigator.Prefix, navigator.LocalName, navigator.NamespaceURI);
if (navigator.MoveToFirstNamespace (XPathNamespaceScope.Local)) {
do {
- WriteNode (navigator, defattr);
+ if (defattr || navigator.SchemaInfo == null || navigator.SchemaInfo.IsDefault)
+ WriteAttributeString (navigator.Prefix,
+ navigator.LocalName == String.Empty ? "xmlns" : navigator.LocalName,
+ "http://www.w3.org/2000/xmlns/",
+ navigator.Value);
} while (navigator.MoveToNextNamespace (XPathNamespaceScope.Local));
navigator.MoveToParent ();
}
if (navigator.MoveToFirstAttribute ()) {
do {
- WriteNode (navigator, defattr);
+ if (defattr || navigator.SchemaInfo == null || navigator.SchemaInfo.IsDefault)
+ WriteAttributeString (navigator.Prefix, navigator.LocalName, navigator.NamespaceURI, navigator.Value);
+
} while (navigator.MoveToNextAttribute ());
navigator.MoveToParent ();
}
public abstract void WriteWhitespace (string ws);
#if NET_2_0
- [MonoTODO]
public virtual void WriteValue (bool value)
{
WriteString (XQueryConvert.BooleanToString (value));
}
- [MonoTODO]
public virtual void WriteValue (DateTime value)
{
WriteString (XmlConvert.ToString (value));
}
- [MonoTODO]
public virtual void WriteValue (decimal value)
{
WriteString (XQueryConvert.DecimalToString (value));
}
- [MonoTODO]
public virtual void WriteValue (double value)
{
WriteString (XQueryConvert.DoubleToString (value));
}
- [MonoTODO]
public virtual void WriteValue (int value)
{
WriteString (XQueryConvert.IntToString (value));
}
- [MonoTODO]
public virtual void WriteValue (long value)
{
WriteString (XQueryConvert.IntegerToString (value));
}
- [MonoTODO]
public virtual void WriteValue (object value)
{
+ if (value == null)
+ throw new ArgumentNullException ("value");
+
if (value is string)
WriteString ((string) value);
else if (value is bool)
WriteValue ((bool) value);
+ else if (value is byte)
+ WriteValue ((int) value);
+ else if (value is byte [])
+ WriteBase64 ((byte []) value, 0, ((byte []) value).Length);
+ else if (value is char [])
+ WriteChars ((char []) value, 0, ((char []) value).Length);
else if (value is DateTime)
WriteValue ((DateTime) value);
else if (value is decimal)
WriteValue ((decimal) value);
else if (value is double)
WriteValue ((double) value);
+ else if (value is short)
+ WriteValue ((int) value);
else if (value is int)
WriteValue ((int) value);
else if (value is long)
WriteValue ((long) value);
+ else if (value is float)
+ WriteValue ((float) value);
+ else if (value is TimeSpan) // undocumented
+ WriteString (XmlConvert.ToString ((TimeSpan) value));
else if (value is XmlQualifiedName) {
XmlQualifiedName qname = (XmlQualifiedName) value;
- WriteQualifiedName (qname.Name, qname.Namespace);
+ if (!qname.Equals (XmlQualifiedName.Empty)) {
+ if (qname.Namespace.Length > 0 && LookupPrefix (qname.Namespace) == null)
+ throw new InvalidCastException (String.Format ("The QName '{0}' cannot be written. No corresponding prefix is declared", qname));
+ WriteQualifiedName (qname.Name, qname.Namespace);
+ }
+ else
+ WriteString (String.Empty);
+ }
+ else if (value is IEnumerable) {
+ bool follow = false;
+ foreach (object obj in (IEnumerable) value) {
+ if (follow)
+ WriteString (" ");
+ else
+ follow = true;
+ WriteValue (obj);
+ }
}
else
- throw new NotImplementedException ("Argument value is " + value);
+ throw new InvalidCastException (String.Format ("Type '{0}' cannot be cast to string", value.GetType ()));
}
- [MonoTODO]
public virtual void WriteValue (float value)
{
WriteString (XQueryConvert.FloatToString (value));
}
- [MonoTODO]
public virtual void WriteValue (string value)
{
WriteString (value);