protected void WriteStartElement(string name, string ns, object o, bool writePrefixed, XmlSerializerNamespaces xmlns)
{
if (o != null && _objectsInUse != null)
{
if (_objectsInUse.ContainsKey(o)) throw new InvalidOperationException(SR.Format(SR.XmlCircularReference, o.GetType().FullName));
_objectsInUse.Add(o, o);
}
string prefix = null;
bool needEmptyDefaultNamespace = false;
if (_namespaces != null)
{
foreach (string alias in _namespaces.Namespaces.Keys)
{
string aliasNs = (string)_namespaces.Namespaces[alias];
if (alias.Length > 0 && aliasNs == ns)
prefix = alias;
if (alias.Length == 0)
{
if (aliasNs == null || aliasNs.Length == 0)
needEmptyDefaultNamespace = true;
if (ns != aliasNs)
writePrefixed = true;
}
}
_usedPrefixes = ListUsedPrefixes(_namespaces.Namespaces, _aliasBase);
}
if (writePrefixed && prefix == null && ns != null && ns.Length > 0)
{
prefix = _w.LookupPrefix(ns);
if (prefix == null || prefix.Length == 0)
{
prefix = NextPrefix();
}
}
if (prefix == null && xmlns != null)
{
prefix = xmlns.LookupPrefix(ns);
}
if (needEmptyDefaultNamespace && prefix == null && ns != null && ns.Length != 0)
prefix = NextPrefix();
_w.WriteStartElement(prefix, name, ns);
if (_namespaces != null)
{
foreach (string alias in _namespaces.Namespaces.Keys)
{
string aliasNs = (string)_namespaces.Namespaces[alias];
if (alias.Length == 0 && (aliasNs == null || aliasNs.Length == 0))
continue;
if (aliasNs == null || aliasNs.Length == 0)
{
if (alias.Length > 0)
throw new InvalidOperationException(SR.Format(SR.XmlInvalidXmlns, alias));
WriteAttribute(nameof(xmlns), alias, null, aliasNs);
}
else
{
if (_w.LookupPrefix(aliasNs) == null)
{
// write the default namespace declaration only if we have not written it already, over wise we just ignore one provided by the user
if (prefix == null && alias.Length == 0)
break;
WriteAttribute(nameof(xmlns), alias, null, aliasNs);
}
}
}
}
WriteNamespaceDeclarations(xmlns);
}