// Authors:
// Jason Diamond (jason@injektilo.org)
// Ben Maurer (bmaurer@users.sourceforge.net)
+// Atsushi Enomoto (atsushi@ximian.com)
//
// (C) 2001 Jason Diamond http://injektilo.org/
// (C) 2003 Ben Maurer
+// (C) 2004 Novell Inc.
//
//
//
using System.Collections;
+#if NET_2_0
+using System.Collections.Generic;
+#endif
using System.Collections.Specialized;
namespace System.Xml
{
- public class XmlNamespaceManager : IEnumerable
+ public class XmlNamespaceManager : IXmlNamespaceResolver, IEnumerable
{
#region Data
struct NsDecl {
get { return defaultNamespace == null ? string.Empty : defaultNamespace; }
}
+#if NET_2_0
+ public virtual XmlNameTable NameTable {
+#else
public XmlNameTable NameTable {
+#endif
get { return nameTable; }
}
AddNamespace (prefix, uri, false);
}
-#if NET_2_0
- public virtual void AddNamespace (string prefix, string uri, bool atomizedNames)
-#else
internal virtual void AddNamespace (string prefix, string uri, bool atomizedNames)
-#endif
{
if (prefix == null)
throw new ArgumentNullException ("prefix", "Value cannot be null.");
decls [declPos].Uri = uri;
}
- internal static string IsValidDeclaration (string prefix, string uri, bool throwException)
+ static string IsValidDeclaration (string prefix, string uri, bool throwException)
{
string message = null;
+ // It is funky, but it does not check whether prefix
+ // is equivalent to "xml" in case-insensitive means.
if (prefix == PrefixXml && uri != XmlnsXml)
- message = String.Format ("Prefix \"xml\" is only allowed to the fixed uri \"{0}\"", XmlnsXml);
- else if (uri == XmlnsXml)
- message = String.Format ("Namespace URI \"{0}\" is reserved to be mapped to \"xml\" and cannot be declared.", XmlnsXml);
- if (message == null && prefix == "xmlns")
+ message = String.Format ("Prefix \"xml\" can only be bound to the fixed namespace URI \"{0}\". \"{1}\" is invalid.", XmlnsXml, uri);
+ else if (message == null && prefix == "xmlns")
message = "Declaring prefix named \"xmlns\" is not allowed to any namespace.";
- if (message == null && uri == XmlnsXmlns)
+ else if (message == null && uri == XmlnsXmlns)
message = String.Format ("Namespace URI \"{0}\" cannot be declared with any namespace.", XmlnsXmlns);
if (message != null && throwException)
throw new ArgumentException (message);
return ht.Keys.GetEnumerator ();
}
+
#if NET_2_0
- [MonoTODO]
- public virtual StringDictionary GetNamespacesInScope (XmlNamespaceScope scope)
+ public virtual IDictionary<string, string> GetNamespacesInScope (XmlNamespaceScope scope)
{
- throw new NotImplementedException ();
+ IDictionary namespaceTable = GetNamespacesInScopeImpl (scope);
+ IDictionary<string, string> namespaces = new Dictionary<string, string>(namespaceTable.Count);
+
+ foreach (DictionaryEntry entry in namespaceTable) {
+ namespaces[(string) entry.Key] = (string) entry.Value;
+ }
+ return namespaces;
+ }
+#else
+ IDictionary IXmlNamespaceResolver.GetNamespacesInScope (XmlNamespaceScope scope)
+ {
+ return GetNamespacesInScopeImpl (scope);
}
#endif
+ internal virtual IDictionary GetNamespacesInScopeImpl (XmlNamespaceScope scope)
+ {
+ Hashtable table = new Hashtable ();
+
+ if (scope == XmlNamespaceScope.Local) {
+ for (int i = 0; i < count; i++)
+ if (decls [declPos - i].Prefix == String.Empty && decls [declPos - i].Uri == String.Empty) {
+ if (table.Contains (String.Empty))
+ table.Remove (String.Empty);
+ }
+ else if (decls [declPos - i].Uri != null)
+ table.Add (decls [declPos - i].Prefix, decls [declPos - i].Uri);
+ return table;
+ } else {
+ for (int i = 0; i <= declPos; i++) {
+ if (decls [i].Prefix == String.Empty && decls [i].Uri == String.Empty) {
+ // removal of default namespace
+ if (table.Contains (String.Empty))
+ table.Remove (String.Empty);
+ }
+ else if (decls [i].Uri != null)
+ table [decls [i].Prefix] = decls [i].Uri;
+ }
+
+ if (scope == XmlNamespaceScope.All)
+ table.Add ("xml", XmlNamespaceManager.XmlnsXml);
+ return table;
+ }
+ }
+
public virtual bool HasNamespace (string prefix)
+ {
+ return HasNamespace (prefix, false);
+ }
+
+ internal virtual bool HasNamespace (string prefix, bool atomizedNames)
{
if (prefix == null || count == 0)
return false;
public virtual string LookupNamespace (string prefix)
{
- return LookupNamespace (prefix, true);
- }
-
#if NET_2_0
- public virtual string LookupNamespace (string prefix, bool atomizedName)
+ return LookupNamespace (prefix, false);
#else
- internal virtual string LookupNamespace (string prefix, bool atomizedName)
+ return LookupNamespace (prefix, true);
#endif
+ }
+
+ internal virtual string LookupNamespace (string prefix, bool atomizedNames)
{
switch (prefix) {
case PrefixXmlns:
}
for (int i = declPos; i >= 0; i--) {
- if (CompareString (decls [i].Prefix, prefix, atomizedName) && decls [i].Uri != null /* null == flag for removed */)
+ if (CompareString (decls [i].Prefix, prefix, atomizedNames) && decls [i].Uri != null /* null == flag for removed */)
return decls [i].Uri;
}
public virtual string LookupPrefix (string uri)
{
+#if NET_2_0
+ return LookupPrefix (uri, false);
+#else
return LookupPrefix (uri, true);
+#endif
}
private bool CompareString (string s1, string s2, bool atomizedNames)
return s1 == s2;
}
-#if NET_2_0
- public string LookupPrefix (string uri, bool atomizedName)
-#else
internal string LookupPrefix (string uri, bool atomizedName)
-#endif
+ {
+ return LookupPrefixCore (uri, atomizedName, false);
+ }
+
+ internal string LookupPrefixExclusive (string uri, bool atomizedName)
+ {
+ return LookupPrefixCore (uri, atomizedName, true);
+ }
+
+ string LookupPrefixCore (string uri, bool atomizedName, bool excludeOverriden)
{
if (uri == null)
return null;
for (int i = declPos; i >= 0; i--) {
if (CompareString (decls [i].Uri, uri, atomizedName) && decls [i].Prefix.Length > 0) // we already looked for ""
- return decls [i].Prefix;
+ if (!excludeOverriden || !IsOverriden (i))
+ return decls [i].Prefix;
}
// ECMA specifies that this method returns String.Empty
return null;
}
+ bool IsOverriden (int idx)
+ {
+ if (idx == declPos)
+ return false;
+ string prefix = decls [idx + 1].Prefix;
+ for (int i = idx + 1; i <= declPos; i++)
+ if ((object) decls [idx].Prefix == prefix)
+ return true;
+ return false;
+ }
+
public virtual bool PopScope ()
{
if (scopePos == -1)
RemoveNamespace (prefix, uri, false);
}
-#if NET_2_0
- public virtual void RemoveNamespace (string prefix, string uri, bool atomizedNames)
-#else
internal virtual void RemoveNamespace (string prefix, string uri, bool atomizedNames)
-#endif
{
if (prefix == null)
throw new ArgumentNullException ("prefix");