2 // XmlNamespaceManager.cs
5 // Jason Diamond (jason@injektilo.org)
7 // (C) 2001 Jason Diamond http://injektilo.org/
10 using System.Collections;
14 public class XmlNamespaceManager : IEnumerable
18 private XmlNameTable nameTable;
19 private NamespaceScope currentScope;
25 public XmlNamespaceManager (XmlNameTable nameTable)
27 this.nameTable = nameTable;
29 nameTable.Add ("xmlns");
30 nameTable.Add ("xml");
31 nameTable.Add (String.Empty);
32 nameTable.Add ("http://www.w3.org/2000/xmlns/");
33 nameTable.Add ("http://www.w3.org/XML/1998/namespace");
42 public virtual string DefaultNamespace {
43 get { return LookupNamespace (String.Empty); }
46 public XmlNameTable NameTable {
47 get { return nameTable; }
54 public virtual void AddNamespace (string prefix, string uri)
57 throw new ArgumentNullException ("prefix", "Value cannot be null.");
60 throw new ArgumentNullException ("uri", "Value cannot be null.");
62 if (prefix.Length > 2 && prefix.Substring (0, 3).ToLower () == "xml")
63 throw new ArgumentException ( "Prefixes beginning with \"xml\" (regardless " + "of whether the characters are uppercase, lowercase, or some combination thereof) are reserved for use by XML.", "prefix");
65 if (currentScope.Namespaces == null)
66 currentScope.Namespaces = new Hashtable ();
68 if (prefix == String.Empty)
69 currentScope.Namespaces [prefix] = nameTable.Add (uri);
71 currentScope.Namespaces.Add (nameTable.Add (prefix), nameTable.Add (uri));
74 public virtual IEnumerator GetEnumerator ()
76 if (currentScope.Namespaces == null)
77 currentScope.Namespaces = new Hashtable ();
79 return currentScope.Namespaces.Keys.GetEnumerator ();
82 public virtual bool HasNamespace (string prefix)
84 return currentScope != null && currentScope.Namespaces != null && currentScope.Namespaces.Contains (prefix);
87 public virtual string LookupNamespace (string prefix)
89 NamespaceScope scope = currentScope;
91 while (scope != null) {
92 if (scope.Namespaces != null && scope.Namespaces.Contains (prefix))
93 return scope.Namespaces[prefix] as string;
99 return nameTable.Get ("http://www.w3.org/2000/xmlns/");
101 return nameTable.Get ("http://www.w3.org/XML/1998/namespace");
103 return nameTable.Get (String.Empty);
109 public virtual string LookupPrefix (string uri)
114 NamespaceScope scope = currentScope;
116 while (scope != null)
118 if (scope.Namespaces != null && scope.Namespaces.ContainsValue (uri)) {
119 foreach (DictionaryEntry entry in scope.Namespaces) {
120 if (entry.Value.ToString() == uri)
121 return nameTable.Get (entry.Key as string) as string;
128 // ECMA specifies that this method returns String.Empty
129 // in case of no match. But actually MS.NET returns null.
130 // For more information,see
131 // http://lists.ximian.com/archives/public/mono-list/2003-January/005071.html
132 //return String.Empty;
136 public virtual bool PopScope ()
138 if (currentScope != null)
139 currentScope = currentScope.Next;
141 return currentScope != null;
144 public virtual void PushScope ()
146 NamespaceScope newScope = new NamespaceScope ();
147 newScope.Next = currentScope;
148 currentScope = newScope;
151 public virtual void RemoveNamespace (string prefix, string uri)
154 throw new ArgumentNullException ("prefix");
157 throw new ArgumentNullException ("uri");
159 if (currentScope == null || currentScope.Namespaces == null)
162 string p = nameTable.Get (prefix);
163 string u = nameTable.Get (uri);
164 if (p == null || u == null)
167 string storedUri = currentScope.Namespaces [p] as string;
168 if (storedUri == null || storedUri != u)
171 currentScope.Namespaces.Remove (p);
177 internal class NamespaceScope
179 internal NamespaceScope Next;
180 internal Hashtable Namespaces;