//
-// System.Xml.XmlTextWriter
+// System.Xml.XmlWriter
//
-// Author:
+// Authors:
// Kral Ferch <kral_ferch@hotmail.com>
+// Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
//
// (C) 2002 Kral Ferch
+// (C) 2002-2003 Atsushi Enomoto
//
using System;
{
public abstract class XmlWriter
{
- #region Fields
-
- protected WriteState ws = WriteState.Start;
- protected XmlNamespaceManager namespaceManager = new XmlNamespaceManager (new NameTable ());
-
- #endregion
-
#region Constructors
protected XmlWriter () { }
public abstract string LookupPrefix (string ns);
- [MonoTODO("DTDs must be implemented to use 'defattr' parameter.")]
+ private void WriteAttribute (XmlReader reader, bool defattr)
+ {
+ if (!defattr && reader.IsDefault)
+ return;
+
+ WriteStartAttribute (reader.Prefix, reader.LocalName, reader.NamespaceURI);
+ while (reader.ReadAttributeValue ()) {
+ switch (reader.NodeType) {
+ case XmlNodeType.Text:
+ WriteString (reader.Value);
+ break;
+ case XmlNodeType.EntityReference:
+ WriteEntityRef (reader.Name);
+ break;
+ }
+ }
+ WriteEndAttribute ();
+ }
+
public virtual void WriteAttributes (XmlReader reader, bool defattr)
{
if(reader == null)
throw new ArgumentException("null XmlReader specified.", "reader");
- switch(reader.NodeType)
- {
- case XmlNodeType.XmlDeclaration:
- // this method doesn't write "<?xml " and "?>", at least MS .NET Framework as yet.
- XmlDeclaration decl = new XmlDeclaration("1.0", String.Empty, String.Empty, null);
- decl.Value = reader.Value;
- if(decl.Version != null && decl.Version != String.Empty) WriteAttributeString("version", decl.Version);
- if(decl.Encoding != null && decl.Encoding != String.Empty) WriteAttributeString("encoding", decl.Encoding);
- if(decl.Standalone != null && decl.Standalone != String.Empty) WriteAttributeString("standalone", decl.Standalone);
- break;
- case XmlNodeType.Element:
- while (reader.MoveToNextAttribute ())
- {
- WriteAttributeString(reader.Prefix, reader.LocalName, reader.NamespaceURI, reader.Value);
- }
- break;
- case XmlNodeType.Attribute:
- do
- {
- WriteAttributeString(reader.Prefix, reader.LocalName, reader.NamespaceURI, reader.Value);
- }
- while (reader.MoveToNextAttribute ()) ;
- break;
- default:
- throw new XmlException("NodeType is not one of Element, Attribute, nor XmlDeclaration.");
+ switch (reader.NodeType) {
+ case XmlNodeType.XmlDeclaration:
+ WriteAttributeString ("version", reader ["version"]);
+ if (reader ["encoding"] != null)
+ WriteAttributeString ("encoding", reader ["encoding"]);
+ if (reader ["standalone"] != null)
+ WriteAttributeString ("standalone", reader ["standalone"]);
+ break;
+ case XmlNodeType.Element:
+ if (reader.MoveToFirstAttribute ())
+ goto case XmlNodeType.Attribute;
+ break;
+ case XmlNodeType.Attribute:
+ do {
+ WriteAttribute (reader, defattr);
+ } while (reader.MoveToNextAttribute ());
+ break;
+ default:
+ throw new XmlException("NodeType is not one of Element, Attribute, nor XmlDeclaration.");
}
}
public void WriteAttributeString (string prefix, string localName, string ns, string value)
{
- if ((prefix == "xmlns") || (localName == "xmlns"))
- {
- ns = value;
-
- if (prefix == "xmlns" && namespaceManager.HasNamespace (localName))
- return;
-
- /* Users need to be able to re-declare the default namespace for subnodes
- else if (localName == "xmlns" && namespaceManager.HasNamespace (String.Empty))
- return;
- */
- }
-
+ // In MS.NET (1.0), this check is done *here*, not at WriteStartAttribute.
+ // (XmlTextWriter.WriteStartAttribute("xmlns", "anyname", null) throws an exception.
+ if ((prefix == "xmlns") || (prefix == "" && localName == "xmlns"))
+ if (ns == null)
+ ns = "http://www.w3.org/2000/xmlns/";
+
WriteStartAttribute (prefix, localName, ns);
WriteString (value);
WriteEndAttribute ();
-
- if ((prefix == "xmlns") || (localName == "xmlns"))
- {
- if (prefix == "xmlns")
- namespaceManager.AddNamespace (localName, ns);
- else
- namespaceManager.AddNamespace ("", ns);
- }
-
}
public abstract void WriteBase64 (byte[] buffer, int index, int count);
public abstract void WriteNmToken (string name);
- [MonoTODO("needs to test")]
public virtual void WriteNode (XmlReader reader, bool defattr)
{
if (reader == null)
throw new ArgumentException ();
if (reader.ReadState == ReadState.Initial) {
- while (reader.Read ())
+ reader.Read ();
+ do {
WriteNode (reader, defattr);
+ } while (!reader.EOF);
+ return;
}
- else {
- switch (reader.NodeType) {
- case XmlNodeType.Element:
- WriteStartElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
- WriteAttributes (reader, defattr);
- if (reader.IsEmptyElement)
- WriteEndElement ();
- break;
- case XmlNodeType.Attribute:
- break;
- case XmlNodeType.Text:
- WriteString (reader.Value);
- break;
- case XmlNodeType.CDATA:
- WriteCData (reader.Value);
- break;
- case XmlNodeType.EntityReference:
- WriteEntityRef (reader.Name);
- break;
- case XmlNodeType.ProcessingInstruction:
- WriteProcessingInstruction (reader.Name, reader.Value);
- break;
- case XmlNodeType.Comment:
- WriteComment (reader.Value);
- break;
- case XmlNodeType.DocumentType:
- WriteDocType (reader.Name,
- reader ["PUBLIC"], reader ["SYSTEM"], reader.Value);
- break;
- case XmlNodeType.SignificantWhitespace:
- goto case XmlNodeType.Whitespace;
- case XmlNodeType.Whitespace:
- WriteWhitespace (reader.Value);
- break;
- case XmlNodeType.EndElement:
- break;
- case XmlNodeType.EndEntity:
- break;
- case XmlNodeType.XmlDeclaration:
- WriteStartDocument (reader.GetAttribute ("standalone").ToLower () == "yes");
- break;
- default:
- throw new NotImplementedException ();
+
+ switch (reader.NodeType) {
+ case XmlNodeType.Element:
+ WriteStartElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
+ WriteAttributes (reader, defattr);
+ reader.MoveToElement ();
+ if (reader.IsEmptyElement)
+ WriteEndElement ();
+ else {
+ int depth = reader.Depth;
+ reader.Read ();
+ do {
+ WriteNode (reader, defattr);
+ } while (depth < reader.Depth);
+ WriteFullEndElement ();
}
+ break;
+ // In case of XmlAttribute, don't proceed reader.
+ case XmlNodeType.Attribute:
+ return;
+ case XmlNodeType.Text:
+ WriteString (reader.Value);
+ break;
+ case XmlNodeType.CDATA:
+ WriteCData (reader.Value);
+ break;
+ case XmlNodeType.EntityReference:
+ WriteEntityRef (reader.Name);
+ break;
+ case XmlNodeType.XmlDeclaration:
+ // LAMESPEC: It means that XmlWriter implementation _must not_ check
+ // whether PI name is "xml" (it is XML error) or not.
+ case XmlNodeType.ProcessingInstruction:
+ WriteProcessingInstruction (reader.Name, reader.Value);
+ break;
+ case XmlNodeType.Comment:
+ WriteComment (reader.Value);
+ break;
+ case XmlNodeType.DocumentType:
+ WriteDocType (reader.Name,
+ reader ["PUBLIC"], reader ["SYSTEM"], reader.Value);
+ break;
+ case XmlNodeType.SignificantWhitespace:
+ goto case XmlNodeType.Whitespace;
+ case XmlNodeType.Whitespace:
+ WriteWhitespace (reader.Value);
+ break;
+ case XmlNodeType.EndElement:
+ WriteFullEndElement ();
+ break;
+ case XmlNodeType.EndEntity:
+ break;
+ case XmlNodeType.None:
+ return; // Do nothing, nor reporting errors.
+ default:
+ throw new XmlException ("Unexpected node " + reader.Name + " of type " + reader.NodeType);
}
+ reader.Read ();
}
public abstract void WriteProcessingInstruction (string name, string text);
public void WriteStartAttribute (string localName, string ns)
{
- WriteStartAttribute ("", localName, ns);
+ WriteStartAttribute (null, localName, ns);
}
public abstract void WriteStartAttribute (string prefix, string localName, string ns);