public override void WriteStartElement (
string prefix, string localName, string namespaceUri)
{
#if NET_2_0
if (state == WriteState.Error || state == WriteState.Closed)
#else
if (state == WriteState.Closed)
#endif
throw StateError ("StartTag");
node_state = XmlNodeType.Element;
bool anonPrefix = (prefix == null);
if (prefix == null)
prefix = String.Empty;
// Crazy namespace check goes here.
//
// 1. if Namespaces is false, then any significant
// namespace indication is not allowed.
// 2. if Prefix is non-empty and NamespaceURI is
// empty, it is an error in 1.x, or it is reset to
// an empty string in 2.0.
// 3. null NamespaceURI indicates that namespace is
// not considered.
// 4. prefix must not be equivalent to "XML" in
// case-insensitive comparison.
if (!namespaces && namespaceUri != null && namespaceUri.Length > 0)
throw ArgumentError ("Namespace is disabled in this XmlTextWriter.");
if (!namespaces && prefix.Length > 0)
throw ArgumentError ("Namespace prefix is disabled in this XmlTextWriter.");
// If namespace URI is empty, then either prefix
// must be empty as well, or there is an
// existing namespace mapping for the prefix.
if (prefix.Length > 0 && namespaceUri == null) {
namespaceUri = nsmanager.LookupNamespace (prefix, false);
if (namespaceUri == null || namespaceUri.Length == 0)
throw ArgumentError ("Namespace URI must not be null when prefix is not an empty string.");
}
// Considering the fact that WriteStartAttribute()
// automatically changes argument namespaceURI, this
// is kind of silly implementation. See bug #77094.
if (namespaces &&
prefix != null && prefix.Length == 3 &&
namespaceUri != XmlNamespace &&
(prefix [0] == 'x' || prefix [0] == 'X') &&
(prefix [1] == 'm' || prefix [1] == 'M') &&
(prefix [2] == 'l' || prefix [2] == 'L'))
throw new ArgumentException ("A prefix cannot be equivalent to \"xml\" in case-insensitive match.");
if (xmldecl_state == XmlDeclState.Auto)
OutputAutoStartDocument ();
if (state == WriteState.Element)
CloseStartElement ();
if (open_count > 0)
elements [open_count - 1].HasElements = true;
nsmanager.PushScope ();
if (namespaces && namespaceUri != null) {
// If namespace URI is empty, then prefix must
// be empty as well.
if (anonPrefix && namespaceUri.Length > 0)
prefix = LookupPrefix (namespaceUri);
if (prefix == null || namespaceUri.Length == 0)
prefix = String.Empty;
}
WriteIndent ();
writer.Write ("<");
if (prefix.Length > 0) {
writer.Write (prefix);
writer.Write (':');
}
writer.Write (localName);
if (elements.Length == open_count) {
XmlNodeInfo [] tmp = new XmlNodeInfo [open_count << 1];
Array.Copy (elements, tmp, open_count);
elements = tmp;
}
if (elements [open_count] == null)
elements [open_count] =
new XmlNodeInfo ();
XmlNodeInfo info = elements [open_count];
info.Prefix = prefix;
info.LocalName = localName;
info.NS = namespaceUri;
info.HasSimple = false;
info.HasElements = false;
info.XmlLang = XmlLang;
info.XmlSpace = XmlSpace;
open_count++;
if (namespaces && namespaceUri != null) {
string oldns = nsmanager.LookupNamespace (prefix, false);
if (oldns != namespaceUri) {
nsmanager.AddNamespace (prefix, namespaceUri);
new_local_namespaces.Push (prefix);
}
}
state = WriteState.Element;
}