private void StartAttribute(ref string prefix, string localName, string ns, XmlDictionaryString xNs)
{
if (IsClosed)
ThrowClosed();
if (_writeState == WriteState.Attribute)
WriteEndAttribute();
if (localName == null || (localName.Length == 0 && prefix != "xmlns"))
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(localName)));
if (_writeState != WriteState.Element)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.XmlInvalidWriteState, "WriteStartAttribute", WriteState.ToString())));
if (prefix == null)
{
if (ns == xmlnsNamespace && localName != "xmlns")
prefix = "xmlns";
else if (ns == xmlNamespace)
prefix = "xml";
else
prefix = string.Empty;
}
// Normalize a (prefix,localName) of (null, "xmlns") to ("xmlns", string.Empty).
if (prefix.Length == 0 && localName == "xmlns")
{
prefix = "xmlns";
localName = string.Empty;
}
_isXmlnsAttribute = false;
_isXmlAttribute = false;
if (prefix == "xml")
{
if (ns != null && ns != xmlNamespace)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.XmlPrefixBoundToNamespace, "xml", xmlNamespace, ns), nameof(ns)));
_isXmlAttribute = true;
_attributeValue = string.Empty;
_attributeLocalName = localName;
}
else if (prefix == "xmlns")
{
if (ns != null && ns != xmlnsNamespace)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.XmlPrefixBoundToNamespace, "xmlns", xmlnsNamespace, ns), nameof(ns)));
_isXmlnsAttribute = true;
_attributeValue = string.Empty;
_attributeLocalName = localName;
}
else if (ns == null)
{
// A null namespace means the namespace of the given prefix.
if (prefix.Length == 0)
{
// An empty prefix on an attribute means no namespace (not the default namespace)
ns = string.Empty;
}
else
{
ns = _nsMgr.LookupNamespace(prefix);
if (ns == null)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.XmlUndefinedPrefix, prefix), nameof(prefix)));
}
}
else if (ns.Length == 0)
{
// An empty namespace means no namespace; prefix must be empty
if (prefix.Length != 0)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.XmlEmptyNamespaceRequiresNullPrefix), nameof(prefix)));
}
else if (prefix.Length == 0)
{
// No prefix specified - try to find a prefix corresponding to the given namespace
prefix = _nsMgr.LookupAttributePrefix(ns);
// If we didn't find anything with the right namespace, generate one.
if (prefix == null)
{
// Watch for special values
if (ns.Length == xmlnsNamespace.Length && ns == xmlnsNamespace)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.XmlSpecificBindingNamespace, "xmlns", ns)));
if (ns.Length == xmlNamespace.Length && ns == xmlNamespace)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.XmlSpecificBindingNamespace, "xml", ns)));
prefix = GeneratePrefix(ns, xNs);
}
}
else
{
_nsMgr.AddNamespaceIfNotDeclared(prefix, ns, xNs);
}
_writeState = WriteState.Attribute;
}