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
== String
.Empty
? null : targetNamespace
; // this weirdness is due to bug #571660.
167 else if (targetNamespace
!= null && schema
.TargetNamespace
!= targetNamespace
)
168 throw new XmlSchemaException ("The actual targetNamespace in the schema does not match the parameter.");
174 // FIXME: Check the exact behavior when namespaces are in conflict (but it would be preferable to wait for 2.0 RTM)
175 public void Add (XmlSchemaSet schemaSet
)
177 ArrayList al
= new ArrayList ();
178 foreach (XmlSchema schema
in schemaSet
.schemas
) {
179 if (!schemas
.Contains (schema
))
182 foreach (XmlSchema schema
in al
)
186 public XmlSchema
Add (XmlSchema schema
)
188 schemas
.Add (schema
);
193 // FIXME: It should be the actual compilation engine.
194 public void Compile ()
196 ClearGlobalComponents ();
197 ArrayList al
= new ArrayList ();
198 al
.AddRange (schemas
);
199 IDCollection
.Clear ();
200 NamedIdentities
.Clear ();
202 Hashtable handledUris
= new Hashtable ();
203 foreach (XmlSchema schema
in al
)
204 if (!schema
.IsCompiled
)
205 schema
.CompileSubset (ValidationEventHandler
, this, xmlResolver
, handledUris
);
207 // Process substitutionGroup first, as this process
208 // involves both substituted and substituting elements
209 // and hence it needs to be done before actual
210 // validation (by current design of conformance checker).
211 foreach (XmlSchema schema
in al
)
212 foreach (XmlSchemaElement elem
in schema
.Elements
.Values
)
213 elem
.FillSubstitutionElementInfo ();
216 foreach (XmlSchema schema
in al
)
217 schema
.Validate (ValidationEventHandler
);
219 foreach (XmlSchema schema
in al
)
220 AddGlobalComponents (schema
);
225 private void ClearGlobalComponents ()
227 GlobalElements
.Clear ();
228 GlobalAttributes
.Clear ();
229 GlobalTypes
.Clear ();
230 // GlobalAttributeGroups.Clear ();
231 // GlobalGroups.Clear ();
234 private void AddGlobalComponents (XmlSchema schema
)
236 foreach (XmlSchemaElement el
in schema
.Elements
.Values
)
237 GlobalElements
.Add (el
.QualifiedName
, el
);
238 foreach (XmlSchemaAttribute a
in schema
.Attributes
.Values
)
239 GlobalAttributes
.Add (a
.QualifiedName
, a
);
240 foreach (XmlSchemaType t
in schema
.SchemaTypes
.Values
)
241 GlobalTypes
.Add (t
.QualifiedName
, t
);
244 public bool Contains (string targetNamespace
)
246 targetNamespace
= GetSafeNs (targetNamespace
);
247 foreach (XmlSchema schema
in schemas
)
248 if (GetSafeNs (schema
.TargetNamespace
) == targetNamespace
)
253 public bool Contains (XmlSchema targetNamespace
)
255 foreach (XmlSchema schema
in schemas
)
256 if (schema
== targetNamespace
)
261 public void CopyTo (XmlSchema
[] array
, int index
)
263 schemas
.CopyTo (array
, index
);
266 internal void CopyTo (Array array
, int index
)
268 schemas
.CopyTo (array
, index
);
271 string GetSafeNs (string ns
)
273 return ns
== null ? "" : ns
;
277 // FIXME: Check exact behavior
278 public XmlSchema
Remove (XmlSchema schema
)
281 throw new ArgumentNullException ("schema");
282 ArrayList al
= new ArrayList ();
283 al
.AddRange (schemas
);
284 if (!al
.Contains (schema
))
286 // FIXME: I have no idea why Remove() might throw
287 // XmlSchemaException, except for the case it compiles.
288 if (!schema
.IsCompiled
)
289 schema
.CompileSubset (ValidationEventHandler
, this, xmlResolver
);
290 schemas
.Remove (schema
);
298 ClearGlobalComponents ();
301 public bool RemoveRecursive (XmlSchema schema
)
304 throw new ArgumentNullException ("schema");
305 ArrayList al
= new ArrayList ();
306 al
.AddRange (schemas
);
307 if (!al
.Contains (schema
))
310 schemas
.Remove (schema
);
315 ClearGlobalComponents ();
316 foreach (XmlSchema s
in al
) {
318 AddGlobalComponents (schema
);
323 public XmlSchema
Reprocess (XmlSchema schema
)
326 throw new ArgumentNullException ("schema");
327 ArrayList al
= new ArrayList ();
328 al
.AddRange (schemas
);
329 if (!al
.Contains (schema
))
330 throw new ArgumentException ("Target schema is not contained in the schema set.");
331 ClearGlobalComponents ();
332 foreach (XmlSchema s
in al
) {
334 schema
.CompileSubset (ValidationEventHandler
, this, xmlResolver
);
336 AddGlobalComponents (schema
);
338 return schema
.IsCompiled
? schema
: null;
341 public ICollection
Schemas ()
346 public ICollection
Schemas (string targetNamespace
)
348 targetNamespace
= GetSafeNs (targetNamespace
);
349 ArrayList al
= new ArrayList ();
350 foreach (XmlSchema schema
in schemas
)
351 if (GetSafeNs (schema
.TargetNamespace
) == targetNamespace
)
356 internal bool MissedSubComponents (string targetNamespace
)
358 foreach (XmlSchema s
in Schemas (targetNamespace
))
359 if (s
.missedSubComponents
)