2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.XML / System.Xml.Schema / XmlSchemaAll.cs
bloba64b45992810e9d6eea4f4f60927ac2b5bb71e94
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))]
52 public override XmlSchemaObjectCollection Items
54 get{ return items; }
57 internal bool Emptiable
59 get { return emptiable; }
62 internal override void SetParent (XmlSchemaObject parent)
64 base.SetParent (parent);
66 foreach (XmlSchemaObject obj in Items)
67 obj.SetParent (this);
70 /// <remarks>
71 /// 1. MaxOccurs must be one. (default is also one)
72 /// 2. MinOccurs must be zero or one.
73 /// </remarks>
74 internal override int Compile(ValidationEventHandler h, XmlSchema schema)
76 // If this is already compiled this time, simply skip.
77 if (CompilationId == schema.CompilationId)
78 return 0;
80 this.schema = schema;
82 if(MaxOccurs != Decimal.One)
83 error(h,"maxOccurs must be 1");
84 if(MinOccurs != Decimal.One && MinOccurs != Decimal.Zero)
85 error(h,"minOccurs must be 0 or 1");
87 XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
88 CompileOccurence (h, schema);
90 foreach(XmlSchemaObject obj in Items)
93 XmlSchemaElement elem = obj as XmlSchemaElement;
94 if(elem != null)
96 if(elem.ValidatedMaxOccurs != Decimal.One && elem.ValidatedMaxOccurs != Decimal.Zero)
98 elem.error (h,"The {max occurs} of all the elements of 'all' must be 0 or 1. ");
100 errorCount += elem.Compile(h, schema);
102 else
104 error(h,"XmlSchemaAll can only contain Items of type Element");
108 this.CompilationId = schema.CompilationId;
109 return errorCount;
112 internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)
114 if (OptimizedParticle != null)
115 return OptimizedParticle;
116 if (Items.Count == 0 || ValidatedMaxOccurs == 0) {
117 OptimizedParticle = XmlSchemaParticle.Empty;
118 return OptimizedParticle;
120 else if (Items.Count == 1) {
121 if (ValidatedMinOccurs == 1 && ValidatedMaxOccurs == 1) {
122 XmlSchemaSequence seq = new XmlSchemaSequence ();
123 this.CopyInfo (seq);
124 XmlSchemaParticle p = (XmlSchemaParticle) Items [0];
125 p = p.GetOptimizedParticle (false);
126 if (p == XmlSchemaParticle.Empty)
127 OptimizedParticle = p;
128 else {
129 seq.Items.Add (p);
130 seq.CompiledItems.Add (p);
131 seq.Compile (null, schema);
132 OptimizedParticle = seq;
134 return OptimizedParticle;
138 XmlSchemaAll all = new XmlSchemaAll ();
139 CopyInfo (all);
140 CopyOptimizedItems (all);
141 OptimizedParticle = all;
142 all.ComputeEmptiable ();
144 return OptimizedParticle;
147 internal override int Validate(ValidationEventHandler h, XmlSchema schema)
149 if (IsValidated (schema.CompilationId))
150 return errorCount;
152 // 3.8.6 All Group Limited :: 1.
153 // Beware that this section was corrected: E1-26 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
154 if (!this.parentIsGroupDefinition && ValidatedMaxOccurs != 1)
155 error (h, "-all- group is limited to be content of a model group, or that of a complex type with maxOccurs to be 1.");
157 CompiledItems.Clear ();
158 foreach (XmlSchemaParticle obj in Items) {
159 errorCount += obj.Validate (h, schema);
160 if (obj.ValidatedMaxOccurs != 0 &&
161 obj.ValidatedMaxOccurs != 1)
162 error (h, "MaxOccurs of a particle inside -all- compositor must be either 0 or 1.");
163 CompiledItems.Add (obj);
165 ComputeEmptiable ();
167 ValidationId = schema.ValidationId;
168 return errorCount;
171 private void ComputeEmptiable ()
173 emptiable = true;
174 for (int i = 0; i < Items.Count; i++) {
175 if (((XmlSchemaParticle) Items [i]).ValidatedMinOccurs > 0) {
176 emptiable = false;
177 break;
182 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
183 ValidationEventHandler h, XmlSchema schema, bool raiseError)
185 XmlSchemaAny any = baseParticle as XmlSchemaAny;
186 XmlSchemaAll derivedAll = baseParticle as XmlSchemaAll;
187 if (any != null) {
188 // NSRecurseCheckCardinality
189 return ValidateNSRecurseCheckCardinality (any, h, schema, raiseError);
190 } else if (derivedAll != null) {
191 // Recurse
192 if (!ValidateOccurenceRangeOK (derivedAll, h, schema, raiseError))
193 return false;
194 return ValidateRecurse (derivedAll, h, schema, raiseError);
196 else {
197 if (raiseError)
198 error (h, "Invalid -all- particle derivation was found.");
199 return false;
203 internal override decimal GetMinEffectiveTotalRange ()
205 return GetMinEffectiveTotalRangeAllAndSequence ();
208 internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
209 ValidationEventHandler h, XmlSchema schema)
211 foreach (XmlSchemaElement el in this.Items)
212 el.ValidateUniqueParticleAttribution (qnames, nsNames, h, schema);
215 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
216 ValidationEventHandler h, XmlSchema schema)
218 foreach (XmlSchemaElement el in this.Items)
219 el.ValidateUniqueTypeAttribution (labels, h, schema);
223 //<all
224 // id = ID
225 // maxOccurs = 1 : 1
226 // minOccurs = (0 | 1) : 1
227 // {any attributes with non-schema namespace . . .}>
228 // Content: (annotation?, element*)
229 //</all>
230 internal static XmlSchemaAll Read(XmlSchemaReader reader, ValidationEventHandler h)
232 XmlSchemaAll all = new XmlSchemaAll();
233 reader.MoveToElement();
235 if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
237 error(h,"Should not happen :1: XmlSchemaAll.Read, name="+reader.Name,null);
238 reader.SkipToEnd();
239 return null;
242 all.LineNumber = reader.LineNumber;
243 all.LinePosition = reader.LinePosition;
244 all.SourceUri = reader.BaseURI;
246 //Read Attributes
247 while(reader.MoveToNextAttribute())
249 if(reader.Name == "id")
251 all.Id = reader.Value;
253 else if(reader.Name == "maxOccurs")
257 all.MaxOccursString = reader.Value;
259 catch(Exception e)
261 error(h,reader.Value + " is an invalid value for maxOccurs",e);
264 else if(reader.Name == "minOccurs")
268 all.MinOccursString = reader.Value;
270 catch(Exception e)
272 error(h,reader.Value + " is an invalid value for minOccurs",e);
275 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
277 error(h,reader.Name + " is not a valid attribute for all",null);
279 else
281 XmlSchemaUtil.ReadUnhandledAttribute(reader,all);
285 reader.MoveToElement();
286 if(reader.IsEmptyElement)
287 return all;
289 //Content: (annotation?, element*)
290 int level = 1;
291 while(reader.ReadNextElement())
293 if(reader.NodeType == XmlNodeType.EndElement)
295 if(reader.LocalName != xmlname)
296 error(h,"Should not happen :2: XmlSchemaAll.Read, name="+reader.Name,null);
297 break;
299 if(level <= 1 && reader.LocalName == "annotation")
301 level = 2; //Only one annotation
302 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
303 if(annotation != null)
304 all.Annotation = annotation;
305 continue;
307 if(level <=2 && reader.LocalName == "element")
309 level = 2;
310 XmlSchemaElement element = XmlSchemaElement.Read(reader,h);
311 if(element != null)
312 all.items.Add(element);
313 continue;
315 reader.RaiseInvalidElementError();
317 return all;