private bool PushNamespaceExplicit(string prefix, string ns)
{
bool writeItOut = true;
// See if the prefix is already defined
int existingNsIndex = LookupNamespaceIndex(prefix);
// Existing declaration in the current scope
if (existingNsIndex != -1)
{
// It is defined in the current scope
if (existingNsIndex > _elemScopeStack[_elemTop].prevNSTop)
{
// The new namespace Uri needs to be the same as the one that is already declared
if (_nsStack[existingNsIndex].namespaceUri != ns)
{
throw new XmlException(SR.Xml_RedefinePrefix, new string[] { prefix, _nsStack[existingNsIndex].namespaceUri, ns });
}
// Check for duplicate declarations
NamespaceKind existingNsKind = _nsStack[existingNsIndex].kind;
if (existingNsKind == NamespaceKind.Written)
{
throw DupAttrException((prefix.Length == 0) ? string.Empty : "xmlns", (prefix.Length == 0) ? "xmlns" : prefix);
}
// Check if it can be omitted
if (_omitDuplNamespaces && existingNsKind != NamespaceKind.NeedToWrite)
{
writeItOut = false;
}
_nsStack[existingNsIndex].kind = NamespaceKind.Written;
// No additional work needed
return writeItOut;
}
// The prefix is defined but in a different scope
else
{
// check if is the same and can be omitted
if (_nsStack[existingNsIndex].namespaceUri == ns && _omitDuplNamespaces)
{
writeItOut = false;
}
}
}
// No existing declaration found in the namespace stack
else
{
// check if it can be found in the predefinedNamespaces (which are provided by the user)
if (_predefinedNamespaces != null)
{
string definedNs = _predefinedNamespaces.LookupNamespace(prefix);
// compare the namespace Uri to decide if the prefix is redefined
if (definedNs == ns && _omitDuplNamespaces)
{
writeItOut = false;
}
}
}
// validate special declaration (xml, xmlns)
if ((ns == XmlReservedNs.NsXml && prefix != "xml") ||
(ns == XmlReservedNs.NsXmlNs && prefix != "xmlns"))
{
throw new ArgumentException(SR.Format(SR.Xml_NamespaceDeclXmlXmlns, prefix));
}
if (prefix.Length > 0 && prefix[0] == 'x')
{
if (prefix == "xml")
{
if (ns != XmlReservedNs.NsXml)
{
throw new ArgumentException(SR.Xml_XmlPrefix);
}
}
else if (prefix == "xmlns")
{
throw new ArgumentException(SR.Xml_XmlnsPrefix);
}
}
AddNamespace(prefix, ns, NamespaceKind.Written);
return writeItOut;
}