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;
58 XmlSchemaCompilationSettings settings =
59 new XmlSchemaCompilationSettings ();
61 XmlSchemaCollection col;
62 ValidationEventHandler handler;
66 internal Guid CompilationId;
68 public XmlSchemaSet ()
69 : this (new NameTable ())
71 handler = new ValidationEventHandler (this.OnValidationError);
74 public XmlSchemaSet (XmlNameTable nameTable)
76 if (nameTable == null)
77 throw new ArgumentNullException ("nameTable");
79 this.nameTable = nameTable;
80 schemas = new ArrayList ();
81 CompilationId = Guid.NewGuid ();
84 public event ValidationEventHandler ValidationEventHandler;
87 get { return schemas.Count; }
90 public XmlSchemaObjectTable GlobalAttributes {
92 if (attributes == null)
93 attributes = new XmlSchemaObjectTable ();
98 public XmlSchemaObjectTable GlobalElements {
100 if (elements == null)
101 elements = new XmlSchemaObjectTable ();
106 public XmlSchemaObjectTable GlobalTypes {
109 types = new XmlSchemaObjectTable ();
114 public bool IsCompiled {
115 get { return isCompiled; }
118 public XmlNameTable NameTable {
119 get { return nameTable; }
122 public XmlSchemaCompilationSettings CompilationSettings {
123 get { return settings; }
124 set { settings = value; }
127 // This is mainly used for event delegating
128 internal XmlSchemaCollection SchemaCollection {
132 col = new XmlSchemaCollection ();
133 foreach (XmlSchema s in schemas)
141 public XmlResolver XmlResolver {
142 set { xmlResolver = value; }
144 internal get { return xmlResolver; }
148 public XmlSchema Add (string targetNamespace, string url)
150 targetNamespace = GetSafeNs (targetNamespace);
151 XmlTextReader r = null;
153 r = new XmlTextReader (url, nameTable);
154 return Add (targetNamespace, r);
161 [MonoTODO ("It has weird namespace duplication check that is different from Add(XmlSchema).")]
162 public XmlSchema Add (string targetNamespace, XmlReader reader)
164 XmlSchema schema = XmlSchema.Read (reader, handler);
165 if (targetNamespace != null
166 && targetNamespace.Length > 0)
167 schema.TargetNamespace = targetNamespace;
172 [MonoTODO ("Check the exact behavior when namespaces are in conflict (but it would be preferable to wait for 2.0 RTM).")]
173 public void Add (XmlSchemaSet schemaSet)
175 ArrayList al = new ArrayList ();
176 foreach (XmlSchema schema in schemaSet.schemas) {
177 if (!schemas.Contains (schema))
180 foreach (XmlSchema schema in al)
184 public XmlSchema Add (XmlSchema schema)
186 schemas.Add (schema);
191 [MonoTODO ("It should be the actual compilation engine.")]
192 public void Compile ()
194 ClearGlobalComponents ();
195 ArrayList al = new ArrayList ();
196 al.AddRange (schemas);
197 foreach (XmlSchema schema in al) {
198 if (!schema.IsCompiled)
199 schema.Compile (handler, this, xmlResolver);
200 AddGlobalComponents (schema);
205 private void ClearGlobalComponents ()
207 GlobalElements.Clear ();
208 GlobalAttributes.Clear ();
209 GlobalTypes.Clear ();
210 // GlobalAttributeGroups.Clear ();
211 // GlobalGroups.Clear ();
214 private void AddGlobalComponents (XmlSchema schema)
216 foreach (XmlSchemaElement el in schema.Elements.Values)
217 GlobalElements.Add (el.QualifiedName, el);
218 foreach (XmlSchemaAttribute a in schema.Attributes.Values)
219 GlobalAttributes.Add (a.QualifiedName, a);
220 foreach (XmlSchemaType t in schema.SchemaTypes.Values)
221 GlobalTypes.Add (t.QualifiedName, t);
224 public bool Contains (string targetNamespace)
226 targetNamespace = GetSafeNs (targetNamespace);
227 foreach (XmlSchema schema in schemas)
228 if (GetSafeNs (schema.TargetNamespace) == targetNamespace)
233 public bool Contains (XmlSchema targetNamespace)
235 foreach (XmlSchema schema in schemas)
236 if (schema == targetNamespace)
241 public void CopyTo (XmlSchema [] array, int index)
243 schemas.CopyTo (array, index);
246 internal void CopyTo (Array array, int index)
248 schemas.CopyTo (array, index);
251 string GetSafeNs (string ns)
253 return ns == null ? "" : ns;
256 internal void OnValidationError (object o, ValidationEventArgs e)
259 col.OnValidationError (o, e);
260 if (ValidationEventHandler != null)
261 ValidationEventHandler (o, e);
262 else if (e.Severity == XmlSeverityType.Error)
266 [MonoTODO ("Check exact behavior")]
267 public XmlSchema Remove (XmlSchema schema)
270 throw new ArgumentNullException ("schema");
271 ArrayList al = new ArrayList ();
272 al.AddRange (schemas);
273 if (!al.Contains (schema))
275 // FIXME: I have no idea why Remove() might throw
276 // XmlSchemaException, except for the case it compiles.
277 if (!schema.IsCompiled)
278 schema.Compile (handler, this, xmlResolver);
279 schemas.Remove (schema);
287 ClearGlobalComponents ();
290 public bool RemoveRecursive (XmlSchema schema)
293 throw new ArgumentNullException ("schema");
294 ArrayList al = new ArrayList ();
295 al.AddRange (schemas);
296 if (!al.Contains (schema))
299 schemas.Remove (schema);
304 ClearGlobalComponents ();
305 foreach (XmlSchema s in al) {
307 AddGlobalComponents (schema);
312 public XmlSchema Reprocess (XmlSchema schema)
315 throw new ArgumentNullException ("schema");
316 ArrayList al = new ArrayList ();
317 al.AddRange (schemas);
318 if (!al.Contains (schema))
319 throw new ArgumentException ("Target schema is not contained in the schema set.");
320 ClearGlobalComponents ();
321 foreach (XmlSchema s in al) {
323 schema.Compile (handler, this, xmlResolver);
325 AddGlobalComponents (schema);
327 return schema.IsCompiled ? schema : null;
330 public ICollection Schemas ()
336 public ICollection Schemas (string targetNamespace)
338 targetNamespace = GetSafeNs (targetNamespace);
339 ArrayList al = new ArrayList ();
340 foreach (XmlSchema schema in schemas)
341 if (GetSafeNs (schema.TargetNamespace) == targetNamespace)
346 internal bool MissedSubComponents (string targetNamespace)
348 foreach (XmlSchema s in Schemas (targetNamespace))
349 if (s.missedSubComponents)