**** Merged from MCS ****
[mono-project.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaAll.cs
blobd4ccf49ee36e6af313efad8d3718c81a26f45e5c
1 //
2 // System.Xml.Schema.XmlSchemaAll.cs
3 //
4 // Author:
5 // Dwivedi, Ajay kumar Adwiv@Yahoo.com
6 // Atsushi Enomoto ginga@kit.hi-ho.ne.jp
7 //
9 //
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:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
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.
29 using System;
30 using System.Collections;
31 using System.Xml;
32 using System.Xml.Serialization;
34 namespace System.Xml.Schema
36 /// <summary>
37 /// Summary description for XmlSchemaAll.
38 /// </summary>
39 public class XmlSchemaAll : XmlSchemaGroupBase
41 private XmlSchema schema;
42 private XmlSchemaObjectCollection items;
43 const string xmlname = "all";
44 private bool emptiable;
46 public XmlSchemaAll()
48 items = new XmlSchemaObjectCollection();
51 [XmlElement("element",typeof(XmlSchemaElement),Namespace=XmlSchema.Namespace)]
52 public override XmlSchemaObjectCollection Items
54 get{ return items; }
57 internal bool Emptiable
59 get { return emptiable; }
63 /// <remarks>
64 /// 1. MaxOccurs must be one. (default is also one)
65 /// 2. MinOccurs must be zero or one.
66 /// </remarks>
67 internal override int Compile(ValidationEventHandler h, XmlSchema schema)
69 // If this is already compiled this time, simply skip.
70 if (this.IsComplied (schema.CompilationId))
71 return 0;
73 this.schema = schema;
75 if(MaxOccurs != Decimal.One)
76 error(h,"maxOccurs must be 1");
77 if(MinOccurs != Decimal.One && MinOccurs != Decimal.Zero)
78 error(h,"minOccurs must be 0 or 1");
80 XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
81 CompileOccurence (h, schema);
83 foreach(XmlSchemaObject obj in Items)
85 XmlSchemaElement elem = obj as XmlSchemaElement;
86 if(elem != null)
88 if(elem.ValidatedMaxOccurs != Decimal.One && elem.ValidatedMaxOccurs != Decimal.Zero)
90 elem.error (h,"The {max occurs} of all the elements of 'all' must be 0 or 1. ");
92 errorCount += elem.Compile(h, schema);
94 else
96 error(h,"XmlSchemaAll can only contain Items of type Element");
100 this.CompilationId = schema.CompilationId;
101 return errorCount;
104 internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)
106 if (OptimizedParticle != null)
107 return OptimizedParticle;
108 if (Items.Count == 0 || ValidatedMaxOccurs == 0) {
109 OptimizedParticle = XmlSchemaParticle.Empty;
110 return OptimizedParticle;
112 else if (Items.Count == 1) {
113 if (ValidatedMinOccurs == 1 && ValidatedMaxOccurs == 1) {
114 XmlSchemaSequence seq = new XmlSchemaSequence ();
115 this.CopyInfo (seq);
116 XmlSchemaParticle p = (XmlSchemaParticle) Items [0];
117 p = p.GetOptimizedParticle (false);
118 if (p == XmlSchemaParticle.Empty)
119 OptimizedParticle = p;
120 else {
121 seq.Items.Add (p);
122 seq.CompiledItems.Add (p);
123 seq.Compile (null, schema);
124 OptimizedParticle = seq;
126 return OptimizedParticle;
130 XmlSchemaAll all = new XmlSchemaAll ();
131 CopyInfo (all);
132 CopyOptimizedItems (all);
133 OptimizedParticle = all;
134 all.ComputeEmptiable ();
136 return OptimizedParticle;
139 internal override int Validate(ValidationEventHandler h, XmlSchema schema)
141 if (IsValidated (schema.CompilationId))
142 return errorCount;
144 // 3.8.6 All Group Limited :: 1.
145 // Beware that this section was corrected: E1-26 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
146 if (!this.parentIsGroupDefinition && ValidatedMaxOccurs != 1)
147 error (h, "-all- group is limited to be content of a model group, or that of a complex type with maxOccurs to be 1.");
149 CompiledItems.Clear ();
150 foreach (XmlSchemaParticle obj in Items) {
151 errorCount += obj.Validate (h, schema);
152 if (obj.ValidatedMaxOccurs != 0 &&
153 obj.ValidatedMaxOccurs != 1)
154 error (h, "MaxOccurs of a particle inside -all- compositor must be either 0 or 1.");
155 CompiledItems.Add (obj);
157 ComputeEmptiable ();
159 ValidationId = schema.ValidationId;
160 return errorCount;
163 private void ComputeEmptiable ()
165 emptiable = true;
166 for (int i = 0; i < Items.Count; i++) {
167 if (((XmlSchemaParticle) Items [i]).ValidatedMinOccurs > 0) {
168 emptiable = false;
169 break;
174 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
175 ValidationEventHandler h, XmlSchema schema, bool raiseError)
177 XmlSchemaAny any = baseParticle as XmlSchemaAny;
178 XmlSchemaAll derivedAll = baseParticle as XmlSchemaAll;
179 if (any != null) {
180 // NSRecurseCheckCardinality
181 return ValidateNSRecurseCheckCardinality (any, h, schema, raiseError);
182 } else if (derivedAll != null) {
183 // Recurse
184 if (!ValidateOccurenceRangeOK (derivedAll, h, schema, raiseError))
185 return false;
186 return ValidateRecurse (derivedAll, h, schema, raiseError);
188 else {
189 if (raiseError)
190 error (h, "Invalid -all- particle derivation was found.");
191 return false;
195 internal override decimal GetMinEffectiveTotalRange ()
197 return GetMinEffectiveTotalRangeAllAndSequence ();
200 internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
201 ValidationEventHandler h, XmlSchema schema)
203 foreach (XmlSchemaElement el in this.Items)
204 el.ValidateUniqueParticleAttribution (qnames, nsNames, h, schema);
207 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
208 ValidationEventHandler h, XmlSchema schema)
210 foreach (XmlSchemaElement el in this.Items)
211 el.ValidateUniqueTypeAttribution (labels, h, schema);
215 //<all
216 // id = ID
217 // maxOccurs = 1 : 1
218 // minOccurs = (0 | 1) : 1
219 // {any attributes with non-schema namespace . . .}>
220 // Content: (annotation?, element*)
221 //</all>
222 internal static XmlSchemaAll Read(XmlSchemaReader reader, ValidationEventHandler h)
224 XmlSchemaAll all = new XmlSchemaAll();
225 reader.MoveToElement();
227 if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
229 error(h,"Should not happen :1: XmlSchemaAll.Read, name="+reader.Name,null);
230 reader.SkipToEnd();
231 return null;
234 all.LineNumber = reader.LineNumber;
235 all.LinePosition = reader.LinePosition;
236 all.SourceUri = reader.BaseURI;
238 //Read Attributes
239 while(reader.MoveToNextAttribute())
241 if(reader.Name == "id")
243 all.Id = reader.Value;
245 else if(reader.Name == "maxOccurs")
249 all.MaxOccursString = reader.Value;
251 catch(Exception e)
253 error(h,reader.Value + " is an invalid value for maxOccurs",e);
256 else if(reader.Name == "minOccurs")
260 all.MinOccursString = reader.Value;
262 catch(Exception e)
264 error(h,reader.Value + " is an invalid value for minOccurs",e);
267 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
269 error(h,reader.Name + " is not a valid attribute for all",null);
271 else
273 XmlSchemaUtil.ReadUnhandledAttribute(reader,all);
277 reader.MoveToElement();
278 if(reader.IsEmptyElement)
279 return all;
281 //Content: (annotation?, element*)
282 int level = 1;
283 while(reader.ReadNextElement())
285 if(reader.NodeType == XmlNodeType.EndElement)
287 if(reader.LocalName != xmlname)
288 error(h,"Should not happen :2: XmlSchemaAll.Read, name="+reader.Name,null);
289 break;
291 if(level <= 1 && reader.LocalName == "annotation")
293 level = 2; //Only one annotation
294 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
295 if(annotation != null)
296 all.Annotation = annotation;
297 continue;
299 if(level <=2 && reader.LocalName == "element")
301 level = 2;
302 XmlSchemaElement element = XmlSchemaElement.Read(reader,h);
303 if(element != null)
304 all.items.Add(element);
305 continue;
307 reader.RaiseInvalidElementError();
309 return all;