5 // Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
7 // (C)2003 Atsushi Enomoto
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.Collections.Specialized;
34 using System.ComponentModel;
36 using System.Security.Policy;
37 using System.Xml.Schema;
38 using System.Xml.XPath;
40 namespace System.Xml.Schema
43 public class XmlSchemaSet
45 internal sealed class XmlSchemaSet
48 XmlNameTable nameTable;
49 XmlResolver xmlResolver = new XmlUrlResolver ();
52 XmlSchemaObjectTable attributes;
53 XmlSchemaObjectTable elements;
54 XmlSchemaObjectTable types;
55 // XmlSchemaObjectTable attributeGroups;
56 // XmlSchemaObjectTable groups;
57 Hashtable idCollection;
58 XmlSchemaObjectTable namedIdentities;
60 XmlSchemaCompilationSettings settings =
61 new XmlSchemaCompilationSettings ();
65 internal Guid CompilationId;
67 public XmlSchemaSet ()
68 : this (new NameTable ())
72 public XmlSchemaSet (XmlNameTable nameTable)
74 if (nameTable == null)
75 throw new ArgumentNullException ("nameTable");
77 this.nameTable = nameTable;
78 schemas = new ArrayList ();
79 CompilationId = Guid.NewGuid ();
82 public event ValidationEventHandler ValidationEventHandler;
85 get { return schemas.Count; }
88 public XmlSchemaObjectTable GlobalAttributes {
90 if (attributes == null)
91 attributes = new XmlSchemaObjectTable ();
96 public XmlSchemaObjectTable GlobalElements {
99 elements = new XmlSchemaObjectTable ();
104 public XmlSchemaObjectTable GlobalTypes {
107 types = new XmlSchemaObjectTable ();
112 public bool IsCompiled {
113 get { return isCompiled; }
116 public XmlNameTable NameTable {
117 get { return nameTable; }
120 public XmlSchemaCompilationSettings CompilationSettings {
121 get { return settings; }
122 set { settings = value; }
125 public XmlResolver XmlResolver {
126 set { xmlResolver = value; }
128 internal get { return xmlResolver; }
130 get { return xmlResolver; }
134 internal Hashtable IDCollection {
136 if (idCollection == null)
137 idCollection = new Hashtable ();
142 internal XmlSchemaObjectTable NamedIdentities {
144 if (namedIdentities == null)
145 namedIdentities = new XmlSchemaObjectTable();
146 return namedIdentities;
150 public XmlSchema Add (string targetNamespace, string url)
152 XmlTextReader r = null;
154 r = new XmlTextReader (url, nameTable);
155 return Add (targetNamespace, r);
162 public XmlSchema Add (string targetNamespace, XmlReader reader)
164 XmlSchema schema = XmlSchema.Read (reader, ValidationEventHandler);
165 if (schema.TargetNamespace == null)
166 schema.TargetNamespace = targetNamespace;
167 else if (targetNamespace != null && schema.TargetNamespace != targetNamespace)
168 throw new XmlSchemaException ("The actual targetNamespace in the schema does not match the parameter.");
173 [MonoTODO ("Check the exact behavior when namespaces are in conflict (but it would be preferable to wait for 2.0 RTM).")]
174 public void Add (XmlSchemaSet schemaSet)
176 ArrayList al = new ArrayList ();
177 foreach (XmlSchema schema in schemaSet.schemas) {
178 if (!schemas.Contains (schema))
181 foreach (XmlSchema schema in al)
185 public XmlSchema Add (XmlSchema schema)
187 schemas.Add (schema);
192 [MonoTODO ("It should be the actual compilation engine.")]
193 public void Compile ()
195 ClearGlobalComponents ();
196 ArrayList al = new ArrayList ();
197 al.AddRange (schemas);
198 IDCollection.Clear ();
199 NamedIdentities.Clear ();
201 foreach (XmlSchema schema in al)
202 if (!schema.IsCompiled)
203 schema.CompileSubset (ValidationEventHandler, this, xmlResolver);
204 foreach (XmlSchema schema in al)
205 schema.Validate (ValidationEventHandler);
207 foreach (XmlSchema schema in al)
208 AddGlobalComponents (schema);
213 private void ClearGlobalComponents ()
215 GlobalElements.Clear ();
216 GlobalAttributes.Clear ();
217 GlobalTypes.Clear ();
218 // GlobalAttributeGroups.Clear ();
219 // GlobalGroups.Clear ();
222 private void AddGlobalComponents (XmlSchema schema)
224 foreach (XmlSchemaElement el in schema.Elements.Values)
225 GlobalElements.Add (el.QualifiedName, el);
226 foreach (XmlSchemaAttribute a in schema.Attributes.Values)
227 GlobalAttributes.Add (a.QualifiedName, a);
228 foreach (XmlSchemaType t in schema.SchemaTypes.Values)
229 GlobalTypes.Add (t.QualifiedName, t);
232 public bool Contains (string targetNamespace)
234 targetNamespace = GetSafeNs (targetNamespace);
235 foreach (XmlSchema schema in schemas)
236 if (GetSafeNs (schema.TargetNamespace) == targetNamespace)
241 public bool Contains (XmlSchema targetNamespace)
243 foreach (XmlSchema schema in schemas)
244 if (schema == targetNamespace)
249 public void CopyTo (XmlSchema [] array, int index)
251 schemas.CopyTo (array, index);
254 internal void CopyTo (Array array, int index)
256 schemas.CopyTo (array, index);
259 string GetSafeNs (string ns)
261 return ns == null ? "" : ns;
264 [MonoTODO ("Check exact behavior")]
265 public XmlSchema Remove (XmlSchema schema)
268 throw new ArgumentNullException ("schema");
269 ArrayList al = new ArrayList ();
270 al.AddRange (schemas);
271 if (!al.Contains (schema))
273 // FIXME: I have no idea why Remove() might throw
274 // XmlSchemaException, except for the case it compiles.
275 if (!schema.IsCompiled)
276 schema.CompileSubset (ValidationEventHandler, this, xmlResolver);
277 schemas.Remove (schema);
285 ClearGlobalComponents ();
288 public bool RemoveRecursive (XmlSchema schema)
291 throw new ArgumentNullException ("schema");
292 ArrayList al = new ArrayList ();
293 al.AddRange (schemas);
294 if (!al.Contains (schema))
297 schemas.Remove (schema);
302 ClearGlobalComponents ();
303 foreach (XmlSchema s in al) {
305 AddGlobalComponents (schema);
310 public XmlSchema Reprocess (XmlSchema schema)
313 throw new ArgumentNullException ("schema");
314 ArrayList al = new ArrayList ();
315 al.AddRange (schemas);
316 if (!al.Contains (schema))
317 throw new ArgumentException ("Target schema is not contained in the schema set.");
318 ClearGlobalComponents ();
319 foreach (XmlSchema s in al) {
321 schema.CompileSubset (ValidationEventHandler, this, xmlResolver);
323 AddGlobalComponents (schema);
325 return schema.IsCompiled ? schema : null;
328 public ICollection Schemas ()
334 public ICollection Schemas (string targetNamespace)
336 targetNamespace = GetSafeNs (targetNamespace);
337 ArrayList al = new ArrayList ();
338 foreach (XmlSchema schema in schemas)
339 if (GetSafeNs (schema.TargetNamespace) == targetNamespace)
344 internal bool MissedSubComponents (string targetNamespace)
346 foreach (XmlSchema s in Schemas (targetNamespace))
347 if (s.missedSubComponents)