2 // System.Xml.Schema.XmlSchema.cs
\r
5 // Dwivedi, Ajay kumar Adwiv@Yahoo.com
\r
6 // Atsushi Enomoto ginga@kit.hi-ho.ne.jp
\r
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections;
\r
33 using System.Xml.Serialization;
\r
34 using System.ComponentModel;
\r
36 namespace System.Xml.Schema
\r
39 /// Summary description for XmlSchema.
\r
41 [XmlRoot("schema",Namespace=XmlSchema.Namespace)]
\r
42 public class XmlSchema : XmlSchemaObject
\r
45 public const string Namespace = "http://www.w3.org/2001/XMLSchema";
\r
46 public const string InstanceNamespace = "http://www.w3.org/2001/XMLSchema-instance";
\r
47 internal const string XdtNamespace = "http://www.w3.org/2003/11/xpath-datatypes";
\r
50 private XmlSchemaForm attributeFormDefault ;
\r
51 private XmlSchemaObjectTable attributeGroups ;
\r
52 private XmlSchemaObjectTable attributes ;
\r
53 private XmlSchemaDerivationMethod blockDefault ;
\r
54 private XmlSchemaForm elementFormDefault ;
\r
55 private XmlSchemaObjectTable elements ;
\r
56 private XmlSchemaDerivationMethod finalDefault ;
\r
57 private XmlSchemaObjectTable groups ;
\r
59 private XmlSchemaObjectCollection includes ;
\r
60 private XmlSchemaObjectCollection items ;
\r
61 private XmlSchemaObjectTable notations ;
\r
62 private XmlSchemaObjectTable schemaTypes ;
\r
63 private string targetNamespace ;
\r
64 private XmlAttribute[] unhandledAttributes ;
\r
65 private string version;
\r
66 private string language;
\r
68 // other post schema compilation infoset
\r
69 private Hashtable idCollection;
\r
70 private XmlSchemaObjectTable namedIdentities;
\r
71 private XmlSchemaCollection schemas;
\r
73 private XmlNameTable nameTable;
\r
75 internal bool missedSubComponents;
\r
77 // Only compilation-time use
\r
78 private XmlSchemaObjectCollection compilationItems;
\r
79 private Hashtable handledUris;
\r
81 // Compiler specific things
\r
82 const string xmlname = "schema";
\r
86 attributeFormDefault= XmlSchemaForm.None;
\r
87 blockDefault = XmlSchemaDerivationMethod.None;
\r
88 elementFormDefault = XmlSchemaForm.None;
\r
89 finalDefault = XmlSchemaDerivationMethod.None;
\r
90 includes = new XmlSchemaObjectCollection();
\r
92 items = new XmlSchemaObjectCollection();
\r
93 attributeGroups = new XmlSchemaObjectTable();
\r
94 attributes = new XmlSchemaObjectTable();
\r
95 elements = new XmlSchemaObjectTable();
\r
96 groups = new XmlSchemaObjectTable();
\r
97 notations = new XmlSchemaObjectTable();
\r
98 schemaTypes = new XmlSchemaObjectTable();
\r
99 idCollection = new Hashtable ();
\r
100 namedIdentities = new XmlSchemaObjectTable();
\r
105 [DefaultValue(XmlSchemaForm.None)]
\r
106 [System.Xml.Serialization.XmlAttribute("attributeFormDefault")]
\r
107 public XmlSchemaForm AttributeFormDefault
\r
109 get{ return attributeFormDefault; }
\r
110 set{ this.attributeFormDefault = value;}
\r
113 [DefaultValue(XmlSchemaDerivationMethod.None)]
\r
114 [System.Xml.Serialization.XmlAttribute("blockDefault")]
\r
115 public XmlSchemaDerivationMethod BlockDefault
\r
117 get{ return blockDefault;}
\r
118 set{ blockDefault = value;}
\r
121 [DefaultValue(XmlSchemaDerivationMethod.None)]
\r
122 [System.Xml.Serialization.XmlAttribute("finalDefault")]
\r
123 public XmlSchemaDerivationMethod FinalDefault
\r
125 get{ return finalDefault;}
\r
126 set{ finalDefault = value;}
\r
129 [DefaultValue(XmlSchemaForm.None)]
\r
130 [System.Xml.Serialization.XmlAttribute("elementFormDefault")]
\r
131 public XmlSchemaForm ElementFormDefault
\r
133 get{ return elementFormDefault;}
\r
134 set{ elementFormDefault = value;}
\r
137 [System.Xml.Serialization.XmlAttribute("targetNamespace")]
\r
138 public string TargetNamespace
\r
140 get{ return targetNamespace;}
\r
141 set{ targetNamespace = value;}
\r
144 [System.Xml.Serialization.XmlAttribute("version")]
\r
145 public string Version
\r
147 get{ return version;}
\r
148 set{ version = value;}
\r
151 [XmlElement("include",typeof(XmlSchemaInclude),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
152 [XmlElement("import",typeof(XmlSchemaImport),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
153 [XmlElement("redefine",typeof(XmlSchemaRedefine),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
154 public XmlSchemaObjectCollection Includes
\r
156 get{ return includes;}
\r
159 [XmlElement("simpleType",typeof(XmlSchemaSimpleType),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
160 [XmlElement("complexType",typeof(XmlSchemaComplexType),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
161 [XmlElement("group",typeof(XmlSchemaGroup),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
162 //Only Schema's attributeGroup has type XmlSchemaAttributeGroup.
\r
163 //Others (complextype, restrictions etc) must have XmlSchemaAttributeGroupRef
\r
164 [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroup),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
165 [XmlElement("element",typeof(XmlSchemaElement),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
166 [XmlElement("attribute",typeof(XmlSchemaAttribute),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
167 [XmlElement("notation",typeof(XmlSchemaNotation),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
168 [XmlElement("annotation",typeof(XmlSchemaAnnotation),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
169 public XmlSchemaObjectCollection Items
\r
171 get{ return items;}
\r
175 public bool IsCompiled
\r
177 get{ return this.CompilationId != Guid.Empty;}
\r
181 public XmlSchemaObjectTable Attributes
\r
183 get{ return attributes;}
\r
187 public XmlSchemaObjectTable AttributeGroups
\r
189 get{ return attributeGroups; }
\r
193 public XmlSchemaObjectTable SchemaTypes
\r
195 get{ return schemaTypes; }
\r
199 public XmlSchemaObjectTable Elements
\r
201 get{ return elements;}
\r
204 [System.Xml.Serialization.XmlAttribute("id")]
\r
212 public XmlAttribute[] UnhandledAttributes
\r
216 if(unhandledAttributeList != null)
\r
218 unhandledAttributes = (XmlAttribute[]) unhandledAttributeList.ToArray(typeof(XmlAttribute));
\r
219 unhandledAttributeList = null;
\r
221 return unhandledAttributes;
\r
225 unhandledAttributes = value;
\r
226 unhandledAttributeList = null;
\r
231 public XmlSchemaObjectTable Groups
\r
233 get{ return groups;}
\r
237 public XmlSchemaObjectTable Notations
\r
239 get{ return notations;}
\r
242 internal Hashtable IDCollection
\r
244 get { return idCollection; }
\r
247 internal XmlSchemaObjectTable NamedIdentities
\r
249 get { return namedIdentities; }
\r
252 internal XmlSchemaCollection Schemas
\r
254 get { return schemas; }
\r
262 /// This compile method does two things:
\r
263 /// 1. It compiles and fills the PSVI dataset
\r
264 /// 2. Validates the schema by calling Validate method.
\r
265 /// Every XmlSchemaObject has a Compile Method which gets called.
\r
268 /// 1. blockDefault must be one of #all | List of (extension | restriction | substitution)
\r
269 /// 2. finalDefault must be one of (#all | List of (extension | restriction| union| list))
\r
270 /// 3. id must be of type ID
\r
271 /// 4. targetNamespace should be any uri
\r
272 /// 5. version should be a normalizedString
\r
273 /// 6. xml:lang should be a language
\r
275 public void Compile (ValidationEventHandler handler)
\r
277 Compile (handler, new XmlUrlResolver ());
\r
281 internal void Compile (ValidationEventHandler handler, XmlResolver resolver)
\r
283 public void Compile (ValidationEventHandler handler, XmlResolver resolver)
\r
286 Compile (handler, new Stack (), this, null, resolver);
\r
290 internal void Compile (ValidationEventHandler handler, XmlSchemaCollection col, XmlResolver resolver)
\r
292 Compile (handler, new Stack (), this, col, resolver);
\r
295 private void Compile (ValidationEventHandler handler, Stack schemaLocationStack, XmlSchema rootSchema, XmlSchemaCollection col, XmlResolver resolver)
\r
297 if (rootSchema != this) {
\r
298 CompilationId = rootSchema.CompilationId;
\r
299 schemas = rootSchema.schemas;
\r
303 if (schemas == null) {
\r
304 schemas = new XmlSchemaCollection ();
\r
305 schemas.SchemaSet.CompilationId = Guid.NewGuid ();
\r
307 CompilationId = schemas.SchemaSet.CompilationId;
\r
308 this.idCollection.Clear ();
\r
310 schemas.Add (this);
\r
312 attributeGroups.Clear ();
\r
313 attributes.Clear ();
\r
316 notations.Clear ();
\r
317 schemaTypes.Clear ();
\r
319 //1. Union and List are not allowed in block default
\r
320 if(BlockDefault != XmlSchemaDerivationMethod.All)
\r
322 if((BlockDefault & XmlSchemaDerivationMethod.List)!=0 )
\r
323 error(handler, "list is not allowed in blockDefault attribute");
\r
324 if((BlockDefault & XmlSchemaDerivationMethod.Union)!=0 )
\r
325 error(handler, "union is not allowed in blockDefault attribute");
\r
328 //2. Substitution is not allowed in finaldefault.
\r
329 if(FinalDefault != XmlSchemaDerivationMethod.All)
\r
331 if((FinalDefault & XmlSchemaDerivationMethod.Substitution)!=0 )
\r
332 error(handler, "substitution is not allowed in finalDefault attribute");
\r
335 //3. id must be of type ID
\r
336 XmlSchemaUtil.CompileID(Id, this, this.IDCollection, handler);
\r
338 //4. targetNamespace should be of type anyURI or absent
\r
339 if(TargetNamespace != null)
\r
341 if(!XmlSchemaUtil.CheckAnyUri(TargetNamespace))
\r
342 error(handler, TargetNamespace+" is not a valid value for targetNamespace attribute of schema");
\r
345 //5. version should be of type normalizedString
\r
346 if(!XmlSchemaUtil.CheckNormalizedString(Version))
\r
347 error(handler, Version + "is not a valid value for version attribute of schema");
\r
349 //6. xml:lang must be a language
\r
350 // if(!XmlSchemaUtil.CheckLanguage(Language))
\r
351 // error(handler, Language + " is not a valid language");
\r
353 // Compile the content of this schema
\r
355 compilationItems = new XmlSchemaObjectCollection ();
\r
356 for (int i = 0; i < Items.Count; i++)
\r
357 compilationItems.Add (Items [i]);
\r
358 if (this == rootSchema)
\r
359 handledUris = new Hashtable ();
\r
361 // First, we run into inclusion schemas to collect
\r
362 // compilation target items into compiledItems.
\r
363 for (int i = 0; i < Includes.Count; i++) {
\r
364 XmlSchemaExternal ext = Includes [i] as XmlSchemaExternal;
\r
366 if (ext.SchemaLocation == null)
\r
368 Stream stream = null;
\r
370 if (resolver != null) {
\r
371 url = GetResolvedUri (resolver, ext.SchemaLocation);
\r
372 if (schemaLocationStack.Contains (url)) {
\r
373 error(handler, "Nested inclusion was found: " + url);
\r
374 // must skip this inclusion
\r
377 if (rootSchema.handledUris.Contains (url))
\r
378 // This schema is already handled, so simply skip (otherwise, duplicate definition errrors occur.
\r
380 rootSchema.handledUris.Add (url, url);
\r
382 stream = resolver.GetEntity (new Uri (url), null, typeof (Stream)) as Stream;
\r
383 } catch (Exception) {
\r
384 // LAMESPEC: This is not good way to handle errors, but since we cannot know what kind of XmlResolver will come, so there are no mean to avoid this ugly catch.
\r
385 warn (handler, "Could not resolve schema location URI: " + url);
\r
390 // Process redefinition children in advance.
\r
391 XmlSchemaRedefine redefine = Includes [i] as XmlSchemaRedefine;
\r
392 if (redefine != null) {
\r
393 for (int j = 0; j < redefine.Items.Count; j++) {
\r
394 XmlSchemaObject redefinedObj = redefine.Items [j];
\r
395 redefinedObj.isRedefinedComponent = true;
\r
396 redefinedObj.isRedefineChild = true;
\r
397 if (redefinedObj is XmlSchemaType ||
\r
398 redefinedObj is XmlSchemaGroup ||
\r
399 redefinedObj is XmlSchemaAttributeGroup)
\r
400 compilationItems.Add (redefinedObj);
\r
402 error (handler, "Redefinition is only allowed to simpleType, complexType, group and attributeGroup.");
\r
406 XmlSchema includedSchema = null;
\r
407 if (stream == null) {
\r
408 // It is missing schema components.
\r
409 missedSubComponents = true;
\r
412 schemaLocationStack.Push (url);
\r
413 XmlTextReader xtr = null;
\r
415 xtr = new XmlTextReader (url, stream, nameTable);
\r
416 includedSchema = XmlSchema.Read (xtr, handler);
\r
421 includedSchema.schemas = schemas;
\r
424 // Set - actual - target namespace for the included schema * before compilation*.
\r
425 XmlSchemaImport import = ext as XmlSchemaImport;
\r
426 if (import != null) {
\r
427 if (TargetNamespace == includedSchema.TargetNamespace) {
\r
428 error (handler, "Target namespace must be different from that of included schema.");
\r
430 } else if (includedSchema.TargetNamespace != import.Namespace) {
\r
431 error (handler, "Attribute namespace and its importing schema's target namespace must be the same.");
\r
435 if (TargetNamespace == null &&
\r
436 includedSchema.TargetNamespace != null) {
\r
437 error (handler, "Target namespace is required to include a schema which has its own target namespace");
\r
440 else if (TargetNamespace != null &&
\r
441 includedSchema.TargetNamespace == null)
\r
442 includedSchema.TargetNamespace = TargetNamespace;
\r
445 // Compile included schema.
\r
446 includedSchema.idCollection = this.IDCollection;
\r
447 includedSchema.Compile (handler, schemaLocationStack, rootSchema, col, resolver);
\r
448 schemaLocationStack.Pop ();
\r
450 if (import != null)
\r
451 rootSchema.schemas.Add (includedSchema);
\r
453 // Note that we use compiled items. Items
\r
454 // may not exist in Items, since included
\r
455 // schema also includes another schemas.
\r
456 foreach (DictionaryEntry entry in includedSchema.Attributes)
\r
457 compilationItems.Add ((XmlSchemaObject) entry.Value);
\r
458 foreach (DictionaryEntry entry in includedSchema.Elements)
\r
459 compilationItems.Add ((XmlSchemaObject) entry.Value);
\r
460 foreach (DictionaryEntry entry in includedSchema.SchemaTypes)
\r
461 compilationItems.Add ((XmlSchemaObject) entry.Value);
\r
462 foreach (DictionaryEntry entry in includedSchema.AttributeGroups)
\r
463 compilationItems.Add ((XmlSchemaObject) entry.Value);
\r
464 foreach (DictionaryEntry entry in includedSchema.Groups)
\r
465 compilationItems.Add ((XmlSchemaObject) entry.Value);
\r
466 foreach (DictionaryEntry entry in includedSchema.Notations)
\r
467 compilationItems.Add ((XmlSchemaObject) entry.Value);
\r
471 error(handler,"Object of Type "+Includes [i].GetType().Name+" is not valid in Includes Property of XmlSchema");
\r
475 // Compilation phase.
\r
476 // At least each Compile() must gives unique (qualified) name for each component.
\r
477 // It also checks self-resolvable properties correct.
\r
478 // Post compilation schema information contribution is not required here.
\r
479 // It should be done by Validate().
\r
480 for (int i = 0; i < compilationItems.Count; i++) {
\r
481 XmlSchemaObject obj = compilationItems [i];
\r
482 if(obj is XmlSchemaAnnotation)
\r
484 int numerr = ((XmlSchemaAnnotation)obj).Compile(handler, this);
\r
485 errorCount += numerr;
\r
487 else if(obj is XmlSchemaAttribute)
\r
489 XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
\r
490 attr.ParentIsSchema = true;
\r
491 int numerr = attr.Compile(handler, this);
\r
492 errorCount += numerr;
\r
495 // if (!attr.IsComplied (this.CompilationId))
\r
496 // schemas.SchemaSet.GlobalAttributes.Add (attr.QualifiedName, attr);
\r
497 XmlSchemaUtil.AddToTable (Attributes, attr, attr.QualifiedName, handler);
\r
500 else if(obj is XmlSchemaAttributeGroup)
\r
502 XmlSchemaAttributeGroup attrgrp = (XmlSchemaAttributeGroup) obj;
\r
503 int numerr = attrgrp.Compile(handler, this);
\r
504 errorCount += numerr;
\r
507 XmlSchemaUtil.AddToTable (AttributeGroups, attrgrp, attrgrp.QualifiedName, handler);
\r
510 else if(obj is XmlSchemaComplexType)
\r
512 XmlSchemaComplexType ctype = (XmlSchemaComplexType) obj;
\r
513 ctype.ParentIsSchema = true;
\r
514 int numerr = ctype.Compile(handler, this);
\r
515 errorCount += numerr;
\r
518 // if (!ctype.IsComplied (this.CompilationId))
\r
519 // schemas.SchemaSet.GlobalTypes.Add (ctype.QualifiedName, ctype);
\r
520 XmlSchemaUtil.AddToTable (schemaTypes, ctype, ctype.QualifiedName, handler);
\r
523 else if(obj is XmlSchemaSimpleType)
\r
525 XmlSchemaSimpleType stype = (XmlSchemaSimpleType) obj;
\r
526 stype.islocal = false; //This simple type is toplevel
\r
527 int numerr = stype.Compile(handler, this);
\r
528 errorCount += numerr;
\r
531 // if (!stype.IsComplied (this.CompilationId))
\r
532 // schemas.SchemaSet.GlobalTypes.Add (stype.QualifiedName, stype);
\r
533 XmlSchemaUtil.AddToTable (SchemaTypes, stype, stype.QualifiedName, handler);
\r
536 else if(obj is XmlSchemaElement)
\r
538 XmlSchemaElement elem = (XmlSchemaElement) obj;
\r
539 elem.parentIsSchema = true;
\r
540 int numerr = elem.Compile(handler, this);
\r
541 errorCount += numerr;
\r
544 // if (!elem.IsComplied (this.CompilationId))
\r
545 // schemas.SchemaSet.GlobalElements.Add (elem.QualifiedName, elem);
\r
546 XmlSchemaUtil.AddToTable (Elements, elem, elem.QualifiedName, handler);
\r
549 else if(obj is XmlSchemaGroup)
\r
551 XmlSchemaGroup grp = (XmlSchemaGroup) obj;
\r
552 int numerr = grp.Compile(handler, this);
\r
553 errorCount += numerr;
\r
556 XmlSchemaUtil.AddToTable (Groups, grp, grp.QualifiedName, handler);
\r
559 else if(obj is XmlSchemaNotation)
\r
561 XmlSchemaNotation ntn = (XmlSchemaNotation) obj;
\r
562 int numerr = ntn.Compile(handler, this);
\r
563 errorCount += numerr;
\r
566 XmlSchemaUtil.AddToTable (Notations, ntn, ntn.QualifiedName, handler);
\r
571 ValidationHandler.RaiseValidationEvent (
\r
573 "Object of Type "+obj.GetType().Name+" is not valid in Item Property of Schema",
\r
574 null, this, null, XmlSeverityType.Error);
\r
578 if (rootSchema == this)
\r
582 private string GetResolvedUri (XmlResolver resolver, string relativeUri)
\r
584 Uri baseUri = null;
\r
585 if (this.SourceUri != null && this.SourceUri != String.Empty)
\r
586 baseUri = new Uri (this.SourceUri);
\r
587 return resolver.ResolveUri (baseUri, relativeUri).ToString ();
\r
590 internal bool IsNamespaceAbsent (string ns)
\r
592 return this.schemas [ns] == null;
\r
597 private void Validate(ValidationEventHandler handler)
\r
599 ValidationId = CompilationId;
\r
601 // Firstly Element needs to be filled their substitution group info
\r
602 foreach(XmlSchemaElement elem in Elements.Values)
\r
603 elem.FillSubstitutionElementInfo ();
\r
606 foreach(XmlSchemaAttribute attr in Attributes.Values)
\r
608 errorCount += attr.Validate(handler, this);
\r
610 foreach(XmlSchemaAttributeGroup attrgrp in AttributeGroups.Values)
\r
612 errorCount += attrgrp.Validate(handler, this);
\r
614 foreach(XmlSchemaType type in SchemaTypes.Values)
\r
616 errorCount += type.Validate(handler, this);
\r
618 foreach(XmlSchemaElement elem in Elements.Values)
\r
620 errorCount += elem.Validate(handler, this);
\r
622 foreach(XmlSchemaGroup grp in Groups.Values)
\r
624 errorCount += grp.Validate(handler, this);
\r
626 foreach(XmlSchemaNotation ntn in Notations.Values)
\r
628 errorCount += ntn.Validate(handler, this);
\r
634 // We cannot use xml deserialization, since it does not provide line info, qname context, and so on.
\r
635 public static XmlSchema Read (TextReader reader, ValidationEventHandler validationEventHandler)
\r
637 return Read (new XmlTextReader (reader),validationEventHandler);
\r
639 public static XmlSchema Read (Stream stream, ValidationEventHandler validationEventHandler)
\r
641 return Read (new XmlTextReader (stream),validationEventHandler);
\r
644 public static XmlSchema Read (XmlReader rdr, ValidationEventHandler validationEventHandler)
\r
646 XmlSchemaReader reader = new XmlSchemaReader (rdr, validationEventHandler);
\r
648 if (reader.ReadState == ReadState.Initial)
\r
649 reader.ReadNextElement ();
\r
651 int startDepth = reader.Depth;
\r
655 switch(reader.NodeType)
\r
657 case XmlNodeType.Element:
\r
658 if(reader.LocalName == "schema")
\r
660 XmlSchema schema = new XmlSchema ();
\r
661 schema.nameTable = rdr.NameTable;
\r
663 schema.LineNumber = reader.LineNumber;
\r
664 schema.LinePosition = reader.LinePosition;
\r
665 schema.SourceUri = reader.BaseURI;
\r
667 ReadAttributes(schema, reader, validationEventHandler);
\r
668 //IsEmptyElement does not behave properly if reader is
\r
669 //positioned at an attribute.
\r
670 reader.MoveToElement();
\r
671 if(!reader.IsEmptyElement)
\r
673 ReadContent(schema, reader, validationEventHandler);
\r
678 if (rdr.NodeType == XmlNodeType.EndElement)
\r
683 //Schema can't be generated. Throw an exception
\r
684 error (validationEventHandler, "The root element must be schema", null);
\r
687 error(validationEventHandler, "This should never happen. XmlSchema.Read 1 ",null);
\r
690 } while(reader.Depth > startDepth && reader.ReadNextElement());
\r
692 // This is thrown regardless of ValidationEventHandler existence.
\r
693 throw new XmlSchemaException ("The top level schema must have namespace " + XmlSchema.Namespace, null);
\r
696 private static void ReadAttributes(XmlSchema schema, XmlSchemaReader reader, ValidationEventHandler h)
\r
700 reader.MoveToElement();
\r
701 while(reader.MoveToNextAttribute())
\r
703 switch(reader.Name)
\r
705 case "attributeFormDefault" :
\r
706 schema.attributeFormDefault = XmlSchemaUtil.ReadFormAttribute(reader,out ex);
\r
708 error(h, reader.Value + " is not a valid value for attributeFormDefault.", ex);
\r
710 case "blockDefault" :
\r
711 schema.blockDefault = XmlSchemaUtil.ReadDerivationAttribute(reader,out ex, "blockDefault",
\r
712 XmlSchemaUtil.ElementBlockAllowed);
\r
714 error (h, ex.Message, ex);
\r
716 case "elementFormDefault":
\r
717 schema.elementFormDefault = XmlSchemaUtil.ReadFormAttribute(reader, out ex);
\r
719 error(h, reader.Value + " is not a valid value for elementFormDefault.", ex);
\r
721 case "finalDefault":
\r
722 schema.finalDefault = XmlSchemaUtil.ReadDerivationAttribute(reader, out ex, "finalDefault",
\r
723 XmlSchemaUtil.FinalAllowed);
\r
725 error (h, ex.Message , ex);
\r
728 schema.id = reader.Value;
\r
730 case "targetNamespace":
\r
731 schema.targetNamespace = reader.Value;
\r
734 schema.version = reader.Value;
\r
737 schema.language = reader.Value;
\r
740 if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
\r
741 error(h, reader.Name + " attribute is not allowed in schema element",null);
\r
744 XmlSchemaUtil.ReadUnhandledAttribute(reader,schema);
\r
751 private static void ReadContent(XmlSchema schema, XmlSchemaReader reader, ValidationEventHandler h)
\r
753 reader.MoveToElement();
\r
754 if(reader.LocalName != "schema" && reader.NamespaceURI != XmlSchema.Namespace && reader.NodeType != XmlNodeType.Element)
\r
755 error(h, "UNREACHABLE CODE REACHED: Method: Schema.ReadContent, " + reader.LocalName + ", " + reader.NamespaceURI,null);
\r
757 //(include | import | redefine | annotation)*,
\r
758 //((simpleType | complexType | group | attributeGroup | element | attribute | notation | annotation)*
\r
760 while(reader.ReadNextElement())
\r
762 if(reader.NodeType == XmlNodeType.EndElement)
\r
764 if(reader.LocalName != xmlname)
\r
765 error(h,"Should not happen :2: XmlSchema.Read, name="+reader.Name,null);
\r
770 if(reader.LocalName == "include")
\r
772 XmlSchemaInclude include = XmlSchemaInclude.Read(reader,h);
\r
773 if(include != null)
\r
774 schema.includes.Add(include);
\r
777 if(reader.LocalName == "import")
\r
779 XmlSchemaImport import = XmlSchemaImport.Read(reader,h);
\r
781 schema.includes.Add(import);
\r
784 if(reader.LocalName == "redefine")
\r
786 XmlSchemaRedefine redefine = XmlSchemaRedefine.Read(reader,h);
\r
787 if(redefine != null)
\r
788 schema.includes.Add(redefine);
\r
791 if(reader.LocalName == "annotation")
\r
793 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
\r
794 if(annotation != null)
\r
795 schema.items.Add(annotation);
\r
802 if(reader.LocalName == "simpleType")
\r
804 XmlSchemaSimpleType stype = XmlSchemaSimpleType.Read(reader,h);
\r
806 schema.items.Add(stype);
\r
809 if(reader.LocalName == "complexType")
\r
811 XmlSchemaComplexType ctype = XmlSchemaComplexType.Read(reader,h);
\r
813 schema.items.Add(ctype);
\r
816 if(reader.LocalName == "group")
\r
818 XmlSchemaGroup group = XmlSchemaGroup.Read(reader,h);
\r
820 schema.items.Add(group);
\r
823 if(reader.LocalName == "attributeGroup")
\r
825 XmlSchemaAttributeGroup attributeGroup = XmlSchemaAttributeGroup.Read(reader,h);
\r
826 if(attributeGroup != null)
\r
827 schema.items.Add(attributeGroup);
\r
830 if(reader.LocalName == "element")
\r
832 XmlSchemaElement element = XmlSchemaElement.Read(reader,h);
\r
833 if(element != null)
\r
834 schema.items.Add(element);
\r
837 if(reader.LocalName == "attribute")
\r
839 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);
\r
841 schema.items.Add(attr);
\r
844 if(reader.LocalName == "notation")
\r
846 XmlSchemaNotation notation = XmlSchemaNotation.Read(reader,h);
\r
847 if(notation != null)
\r
848 schema.items.Add(notation);
\r
851 if(reader.LocalName == "annotation")
\r
853 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
\r
854 if(annotation != null)
\r
855 schema.items.Add(annotation);
\r
859 reader.RaiseInvalidElementError();
\r
866 public void Write(System.IO.Stream stream)
\r
868 Write(stream,null);
\r
870 public void Write(System.IO.TextWriter writer)
\r
872 Write(writer,null);
\r
874 public void Write(System.Xml.XmlWriter writer)
\r
876 Write(writer,null);
\r
878 public void Write(System.IO.Stream stream, System.Xml.XmlNamespaceManager namespaceManager)
\r
880 Write(new XmlTextWriter(stream,null),namespaceManager);
\r
882 public void Write(System.IO.TextWriter writer, System.Xml.XmlNamespaceManager namespaceManager)
\r
884 XmlTextWriter xwriter = new XmlTextWriter(writer);
\r
885 xwriter.Formatting = Formatting.Indented;
\r
886 Write(xwriter,namespaceManager);
\r
889 public void Write (System.Xml.XmlWriter writer, System.Xml.XmlNamespaceManager namespaceManager)
\r
891 XmlSerializerNamespaces nss = new XmlSerializerNamespaces ();
\r
893 if (namespaceManager != null) {
\r
895 nss = new XmlSerializerNamespaces ();
\r
896 foreach (string name in namespaceManager) {
\r
897 //xml and xmlns namespaces are added by default in namespaceManager.
\r
898 //So we should ignore them
\r
899 if (name !="xml" && name != "xmlns")
\r
900 nss.Add (name, namespaceManager.LookupNamespace (name));
\r
904 if (Namespaces != null && Namespaces.Count > 0) {
\r
905 nss.Add (String.Empty, XmlSchema.Namespace);
\r
906 foreach (XmlQualifiedName qn in Namespaces.ToArray ()) {
\r
907 nss.Add (qn.Name, qn.Namespace);
\r
911 if (nss.Count == 0) {
\r
912 // Add the xml schema namespace. (It is done
\r
913 // only when no entry exists in Namespaces).
\r
914 nss.Add ("xs", XmlSchema.Namespace);
\r
915 if (TargetNamespace != null)
\r
916 nss.Add ("tns", TargetNamespace);
\r
919 // XmlSerializer xser = new XmlSerializer (typeof (XmlSchema));
\r
920 // xser.Serialize (writer, this, nss);
\r
921 XmlSchemaSerializer xser = new XmlSchemaSerializer ();
\r
922 xser.Serialize (writer, this, nss);
\r
928 class XmlSchemaSerializer : XmlSerializer
\r
930 protected override void Serialize (object o, XmlSerializationWriter writer)
\r
932 XmlSchemaSerializationWriter w = writer as XmlSchemaSerializationWriter;
\r
933 w.WriteRoot_XmlSchema ((XmlSchema) o);
\r
936 protected override XmlSerializationWriter CreateWriter ()
\r
938 return new XmlSchemaSerializationWriter ();
\r