private void PushNamespaceImplicit(string prefix, string ns)
{
NamespaceKind kind;
// See if the prefix is already defined
int existingNsIndex = LookupNamespaceIndex(prefix);
// Prefix is already defined
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 });
}
// No additional work needed
return;
}
// The prefix is defined but in a different scope
else
{
// existing declaration is special one (xml, xmlns) -> validate that the new one is the same and can be declared
if (_nsStack[existingNsIndex].kind == NamespaceKind.Special)
{
if (prefix == "xml")
{
if (ns != _nsStack[existingNsIndex].namespaceUri)
{
throw new ArgumentException(SR.Xml_XmlPrefix);
}
else
{
kind = NamespaceKind.Implied;
}
}
else
{
Debug.Assert(prefix == "xmlns");
throw new ArgumentException(SR.Xml_XmlnsPrefix);
}
}
// regular namespace declaration -> compare the namespace Uris to decide if the prefix is redefined
else
{
kind = (_nsStack[existingNsIndex].namespaceUri == ns) ? NamespaceKind.Implied : NamespaceKind.NeedToWrite;
}
}
}
// No existing declaration found in the namespace stack
else
{
// 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));
}
// 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
kind = (definedNs == ns) ? NamespaceKind.Implied : NamespaceKind.NeedToWrite;
}
else
{
// Namespace not declared anywhere yet, we need to write it out
kind = NamespaceKind.NeedToWrite;
}
}
AddNamespace(prefix, ns, kind);
}