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 nameTable.Add (prefix);
70 currentScope.Namespaces [prefix] = nameTable.Add (uri);
73 public virtual IEnumerator GetEnumerator ()
75 if (currentScope.Namespaces == null)
76 currentScope.Namespaces = new Hashtable ();
78 return currentScope.Namespaces.Keys.GetEnumerator ();
81 public virtual bool HasNamespace (string prefix)
83 return currentScope != null && currentScope.Namespaces != null && currentScope.Namespaces.Contains (prefix);
86 public virtual string LookupNamespace (string prefix)
88 NamespaceScope scope = currentScope;
90 while (scope != null) {
91 if (scope.Namespaces != null && scope.Namespaces.Contains (prefix))
92 return scope.Namespaces[prefix] as string;
98 return nameTable.Get ("http://www.w3.org/2000/xmlns/");
100 return nameTable.Get ("http://www.w3.org/XML/1998/namespace");
102 return nameTable.Get (String.Empty);
108 public virtual string LookupPrefix (string uri)
113 NamespaceScope scope = currentScope;
115 while (scope != null)
117 if (scope.Namespaces != null && scope.Namespaces.ContainsValue (uri)) {
118 foreach (DictionaryEntry entry in scope.Namespaces) {
119 if (entry.Value.ToString() == uri)
120 return nameTable.Get (entry.Key as string) as string;
127 // ECMA specifies that this method returns String.Empty
128 // in case of no match. But actually MS.NET returns null.
129 // For more information,see
130 // http://lists.ximian.com/archives/public/mono-list/2003-January/005071.html
131 //return String.Empty;
135 public virtual bool PopScope ()
137 if (currentScope != null)
138 currentScope = currentScope.Next;
140 return currentScope != null;
143 public virtual void PushScope ()
145 NamespaceScope newScope = new NamespaceScope ();
146 newScope.Next = currentScope;
147 currentScope = newScope;
150 public virtual void RemoveNamespace (string prefix, string uri)
153 throw new ArgumentNullException ("prefix");
156 throw new ArgumentNullException ("uri");
158 if (currentScope == null || currentScope.Namespaces == null)
161 string p = nameTable.Get (prefix);
162 string u = nameTable.Get (uri);
163 if (p == null || u == null)
166 string storedUri = currentScope.Namespaces [p] as string;
167 if (storedUri == null || storedUri != u)
170 currentScope.Namespaces.Remove (p);
176 internal class NamespaceScope
178 internal NamespaceScope Next;
179 internal Hashtable Namespaces;