1 // Author: Dwivedi, Ajay kumar
\r
4 using System.Collections;
\r
6 using System.Text.RegularExpressions;
\r
8 using System.Xml.Serialization;
\r
9 using Mono.Xml.Schema;
\r
10 using System.Globalization;
\r
12 namespace System.Xml.Schema
\r
15 /// Summary description for XmlSchemaSimpleTypeRestriction.
\r
17 public class XmlSchemaSimpleTypeRestriction : XmlSchemaSimpleTypeContent
\r
19 private XmlSchemaSimpleType baseType;
\r
20 private XmlQualifiedName baseTypeName;
\r
21 private XmlSchemaObjectCollection facets;
\r
22 const string xmlname = "restriction";
\r
23 private string [] enumarationFacetValues;
\r
24 private string [] patternFacetValues;
\r
25 private Regex [] rexPatterns;
\r
26 private decimal lengthFacet;
\r
27 private decimal maxLengthFacet;
\r
28 private decimal minLengthFacet;
\r
29 private decimal fractionDigitsFacet;
\r
30 private decimal totalDigitsFacet;
\r
31 private object maxInclusiveFacet ;
\r
32 private object maxExclusiveFacet ;
\r
33 private object minInclusiveFacet ;
\r
34 private object minExclusiveFacet ;
\r
35 private XmlSchemaFacet.Facet fixedFacets = XmlSchemaFacet.Facet.None;
\r
36 private static NumberStyles lengthStyle = NumberStyles.Integer;
\r
39 public XmlSchemaSimpleTypeRestriction()
\r
41 baseTypeName = XmlQualifiedName.Empty;
\r
42 facets = new XmlSchemaObjectCollection();
\r
45 [System.Xml.Serialization.XmlAttribute("base")]
\r
46 public XmlQualifiedName BaseTypeName
\r
48 get{ return baseTypeName; }
\r
49 set{ baseTypeName = value; }
\r
52 [XmlElement("simpleType",Namespace=XmlSchema.Namespace)]
\r
53 public XmlSchemaSimpleType BaseType
\r
55 get{ return baseType; }
\r
56 set{ baseType = value; }
\r
59 [XmlElement("minExclusive",typeof(XmlSchemaMinExclusiveFacet),Namespace=XmlSchema.Namespace)]
\r
60 [XmlElement("minInclusive",typeof(XmlSchemaMinInclusiveFacet),Namespace=XmlSchema.Namespace)]
\r
61 [XmlElement("maxExclusive",typeof(XmlSchemaMaxExclusiveFacet),Namespace=XmlSchema.Namespace)]
\r
62 [XmlElement("maxInclusive",typeof(XmlSchemaMaxInclusiveFacet),Namespace=XmlSchema.Namespace)]
\r
63 [XmlElement("totalDigits",typeof(XmlSchemaTotalDigitsFacet),Namespace=XmlSchema.Namespace)]
\r
64 [XmlElement("fractionDigits",typeof(XmlSchemaFractionDigitsFacet),Namespace=XmlSchema.Namespace)]
\r
65 [XmlElement("length",typeof(XmlSchemaLengthFacet),Namespace=XmlSchema.Namespace)]
\r
66 [XmlElement("minLength",typeof(XmlSchemaMinLengthFacet),Namespace=XmlSchema.Namespace)]
\r
67 [XmlElement("maxLength",typeof(XmlSchemaMaxLengthFacet),Namespace=XmlSchema.Namespace)]
\r
68 [XmlElement("enumeration",typeof(XmlSchemaEnumerationFacet),Namespace=XmlSchema.Namespace)]
\r
69 [XmlElement("whiteSpace",typeof(XmlSchemaWhiteSpaceFacet),Namespace=XmlSchema.Namespace)]
\r
70 [XmlElement("pattern",typeof(XmlSchemaPatternFacet),Namespace=XmlSchema.Namespace)]
\r
71 public XmlSchemaObjectCollection Facets
\r
73 get{ return facets; }
\r
77 /// 1. One of base or simpletype must be present but not both
\r
78 /// 2. id must be a valid ID
\r
79 /// 3. base must be a valid QName *NO CHECK REQUIRED*
\r
82 internal override int Compile(ValidationEventHandler h, XmlSchema schema)
\r
84 // If this is already compiled this time, simply skip.
\r
85 if (this.IsComplied (schema.CompilationId))
\r
90 if(this.baseType != null && !this.BaseTypeName.IsEmpty)
\r
91 error(h, "both base and simpletype can't be set");
\r
92 if(this.baseType == null && this.BaseTypeName.IsEmpty)
\r
93 error(h, "one of basetype or simpletype must be present");
\r
94 if(this.baseType != null)
\r
96 errorCount += this.baseType.Compile(h,schema);
\r
98 if(!XmlSchemaUtil.CheckQName(BaseTypeName))
\r
99 error(h,"BaseTypeName must be a XmlQualifiedName");
\r
101 XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);
\r
103 this.CompilationId = schema.CompilationId;
\r
107 /** Checks if this facet is valid on this restriction. Does not check that it has
\r
108 * not been fixed in the baseType. That is done elsewhere.
\r
111 private const XmlSchemaFacet.Facet listFacets =
\r
112 XmlSchemaFacet.Facet.length | XmlSchemaFacet.Facet.minLength |
\r
113 XmlSchemaFacet.Facet.maxLength | XmlSchemaFacet.Facet.pattern |
\r
114 XmlSchemaFacet.Facet.enumeration | XmlSchemaFacet.Facet.whiteSpace;
\r
117 private bool IsAllowedFacet(XmlSchemaFacet xsf) {
\r
118 /* Must be called after this.ValidateActualType, as it uses actualBaseSchemaType */
\r
120 XsdAnySimpleType ast = ActualBaseSchemaType as XsdAnySimpleType;
\r
122 // Based directly on an xsd type
\r
123 return ast.AllowsFacet(xsf);
\r
126 XmlSchemaSimpleTypeContent st = ((XmlSchemaSimpleType)ActualBaseSchemaType).Content as XmlSchemaSimpleTypeContent;
\r
128 XmlSchemaSimpleTypeRestriction str = st as XmlSchemaSimpleTypeRestriction;
\r
129 if (str != null && str != this) {
\r
130 return str.IsAllowedFacet(xsf);
\r
132 XmlSchemaSimpleTypeList stl = st as XmlSchemaSimpleTypeList;
\r
134 return ((xsf.ThisFacet & listFacets) != 0);
\r
137 XmlSchemaSimpleTypeUnion stu = st as XmlSchemaSimpleTypeUnion;
\r
139 return (xsf is XmlSchemaPatternFacet ||
\r
140 xsf is XmlSchemaEnumerationFacet);
\r
145 // TODO: Should this be either a XmlSchemaSimpleType or XmlSchemaDatatype ?
\r
146 // If so report error
\r
149 // Not sure it could ever get here
\r
156 internal override int Validate(ValidationEventHandler h, XmlSchema schema)
\r
159 if (IsValidated (schema.ValidationId))
\r
162 this.ValidateActualType (h, schema);
\r
165 lengthFacet = maxLengthFacet = minLengthFacet = fractionDigitsFacet = totalDigitsFacet = -1;
\r
167 XmlSchemaSimpleTypeRestriction baseSTR = null;
\r
169 if (ActualBaseSchemaType is XmlSchemaSimpleType) {
\r
170 XmlSchemaSimpleTypeContent st = ((XmlSchemaSimpleType)ActualBaseSchemaType).Content as XmlSchemaSimpleTypeContent;
\r
171 baseSTR = st as XmlSchemaSimpleTypeRestriction;
\r
175 if (baseSTR != null) {
\r
176 fixedFacets = baseSTR.fixedFacets;
\r
177 lengthFacet = baseSTR.lengthFacet;
\r
178 maxLengthFacet = baseSTR.maxLengthFacet;
\r
179 minLengthFacet = baseSTR.minLengthFacet;
\r
180 fractionDigitsFacet = baseSTR.fractionDigitsFacet;
\r
181 totalDigitsFacet = baseSTR.totalDigitsFacet;
\r
182 maxInclusiveFacet = baseSTR.maxInclusiveFacet;
\r
183 maxExclusiveFacet = baseSTR.maxExclusiveFacet;
\r
184 minInclusiveFacet = baseSTR.minInclusiveFacet;
\r
185 minExclusiveFacet = baseSTR.minExclusiveFacet;
\r
188 enumarationFacetValues = patternFacetValues = null;
\r
189 rexPatterns = null;
\r
191 XmlSchemaFacet.Facet facetsDefined = XmlSchemaFacet.Facet.None;
\r
193 ArrayList enums = null;
\r
194 ArrayList patterns = null;
\r
195 for (int i = 0; i < facets.Count; i++) {
\r
197 XmlSchemaFacet facet = facets[i] as XmlSchemaFacet;
\r
198 if (facet != null) {
\r
199 if (!IsAllowedFacet(facet)) {
\r
200 facet.error(h, facet.ThisFacet +" is not a valid facet for this type");
\r
205 // FIXME: Not an XmlSchemaFacet, should we complain here?
\r
206 // Definately not worth seeing what sort of facet it is, as
\r
207 // it isn't any of them.
\r
212 XmlSchemaEnumerationFacet ef = facets [i] as XmlSchemaEnumerationFacet;
\r
215 enums = new ArrayList ();
\r
216 enums.Add (ef.Value);
\r
219 XmlSchemaPatternFacet pf = facets [i] as XmlSchemaPatternFacet;
\r
221 if (patterns == null)
\r
222 patterns = new ArrayList ();
\r
223 patterns.Add (pf.Value);
\r
227 // Put this test here, as pattern and enumeration
\r
228 // can occur multiple times.
\r
229 if ( (facetsDefined & facet.ThisFacet) !=0) {
\r
230 facet.error (h, "This is a duplicate '" + facet.ThisFacet + "' facet.");
\r
234 facetsDefined |= facet.ThisFacet;
\r
241 if (facet is XmlSchemaLengthFacet) {
\r
242 checkLengthFacet((XmlSchemaLengthFacet)facet, facetsDefined, h);
\r
244 else if (facet is XmlSchemaMaxLengthFacet) {
\r
245 checkMaxLengthFacet((XmlSchemaMaxLengthFacet)facet, facetsDefined, h);
\r
247 else if (facet is XmlSchemaMinLengthFacet) {
\r
248 checkMinLengthFacet((XmlSchemaMinLengthFacet)facet, facetsDefined, h);
\r
251 else if (facet is XmlSchemaMinInclusiveFacet) {
\r
252 checkMinMaxFacet((XmlSchemaMinInclusiveFacet)facet, ref minInclusiveFacet, h);
\r
254 else if (facet is XmlSchemaMaxInclusiveFacet) {
\r
255 checkMinMaxFacet((XmlSchemaMaxInclusiveFacet)facet, ref maxInclusiveFacet, h);
\r
257 else if (facet is XmlSchemaMinExclusiveFacet) {
\r
258 checkMinMaxFacet((XmlSchemaMinExclusiveFacet)facet, ref minExclusiveFacet, h);
\r
260 else if (facet is XmlSchemaMaxExclusiveFacet) {
\r
261 checkMinMaxFacet((XmlSchemaMaxExclusiveFacet)facet, ref maxExclusiveFacet, h);
\r
263 else if (facet is XmlSchemaFractionDigitsFacet) {
\r
264 checkFractionDigitsFacet((XmlSchemaFractionDigitsFacet)facet, h);
\r
266 else if (facet is XmlSchemaTotalDigitsFacet) {
\r
267 checkTotalDigitsFacet((XmlSchemaTotalDigitsFacet)facet, h);
\r
270 if (facet.IsFixed) {
\r
271 fixedFacets |= facet.ThisFacet;
\r
277 this.enumarationFacetValues = enums.ToArray (typeof (string)) as string [];
\r
278 if (patterns != null) {
\r
279 this.patternFacetValues = patterns.ToArray (typeof (string)) as string [];
\r
280 this.rexPatterns = new Regex [patterns.Count];
\r
281 for (int i = 0; i < patternFacetValues.Length; i++) {
\r
283 string src = patternFacetValues [i];
\r
284 StringBuilder sb = null;
\r
286 for (int c = 0; c < src.Length; c++) {
\r
287 if (src [c] == '\\' && src.Length > i + 1) {
\r
288 string subst = null;
\r
289 switch (src [c + 1]) {
\r
291 subst = "[\\p{L}_]";
\r
294 subst = "[^\\p{L}_]";
\r
297 subst = "[\\p{L}\\p{N}_\\.\\-:]";
\r
300 subst = "[^\\p{L}\\p{N}_\\.\\-:]";
\r
303 if (subst != null) {
\r
305 sb = new StringBuilder ();
\r
306 sb.Append (src, start, c - start);
\r
313 sb.Append (src, start, src.Length - start);
\r
314 src = sb.ToString ();
\r
316 // src = src.Replace ("\\i", "[\\p{L}_]").Replace ("\\I", "[^\\p{L}_]").Replace ("\\c", "[\\p{L}\\p{N}_\\.\\-:]").Replace ("\\C", "[^\\p{L}\\p{N}_\\.\\-:]");
\r
317 Regex rex = new Regex ("^" + src + "$");
\r
318 rexPatterns [i] = rex;
\r
319 } catch (Exception ex) {
\r
320 error (h, "Invalid regular expression pattern was specified.", ex);
\r
328 ValidationId = schema.ValidationId;
\r
330 Console.WriteLine("Facets:\n defined\t{10}\n fixed\t{0}\n length\t{1}\n maxLen\t{2}\n minLen\t{3}\n " +
\r
331 "frac\t{4}\n tot\t{5}\n maxI\t{6}\n maxE\t{7}\n minI\t{8}\n minE\t{9}\n",
\r
336 fractionDigitsFacet ,
\r
338 maxInclusiveFacet ,
\r
339 maxExclusiveFacet ,
\r
340 minInclusiveFacet ,
\r
341 minExclusiveFacet ,
\r
348 internal void ValidateActualType (ValidationEventHandler h, XmlSchema schema)
\r
350 GetActualType (h, schema, true);
\r
353 internal object GetActualType (ValidationEventHandler h, XmlSchema schema, bool validate)
\r
355 object actualBaseSchemaType = null;
\r
357 XmlSchemaSimpleType type = baseType;
\r
359 type = schema.SchemaTypes [baseTypeName] as XmlSchemaSimpleType;
\r
360 if (type != null) {
\r
362 errorCount += type.Validate (h, schema);
\r
363 actualBaseSchemaType = type;
\r
364 } else if (baseTypeName == XmlSchemaComplexType.AnyTypeName) {
\r
365 actualBaseSchemaType = XmlSchemaSimpleType.AnySimpleType;
366 } else if (baseTypeName.Namespace == XmlSchema.Namespace) {
\r
367 actualBaseSchemaType = XmlSchemaDatatype.FromName (baseTypeName);
\r
368 if (actualBaseSchemaType == null)
\r
370 error (h, "Invalid schema type name was specified: " + baseTypeName);
\r
372 // otherwise, it might be missing sub components.
\r
373 else if (!schema.IsNamespaceAbsent (baseTypeName.Namespace))
\r
375 error (h, "Referenced base schema type " + baseTypeName + " was not found in the corresponding schema.");
\r
377 return actualBaseSchemaType;
\r
381 private void checkTotalDigitsFacet (XmlSchemaTotalDigitsFacet totf,
\r
382 ValidationEventHandler h) {
\r
383 if (totf != null) {
\r
384 /* totalDigits is the maximum number of digits in values of datatypes
\r
385 * ·derived· from decimal. The value of totalDigits ·must· be a
\r
386 * positiveInteger. */
\r
388 decimal newTotalDigits = decimal.Parse (totf.Value.Trim (), lengthStyle);
\r
389 if (newTotalDigits <= 0)
\r
390 totf.error(h, String.Format("The value '{0}' is an invalid totalDigits value", newTotalDigits));
\r
391 // Valid restriction
\r
392 if ((totalDigitsFacet > 0) && (newTotalDigits > totalDigitsFacet)) {
\r
393 totf.error(h, String.Format("The value '{0}' is not a valid restriction of the base totalDigits facet '{1}'", newTotalDigits, totalDigitsFacet));
\r
395 totalDigitsFacet = newTotalDigits;
\r
397 catch (FormatException ) {
\r
398 totf.error(h, String.Format("The value '{0}' is an invalid totalDigits facet specification", totf.Value.Trim () ));
\r
404 private void checkFractionDigitsFacet (XmlSchemaFractionDigitsFacet fracf,
\r
405 ValidationEventHandler h) {
\r
407 if (fracf != null) {
\r
409 decimal newFractionDigits = decimal.Parse (fracf.Value.Trim (), lengthStyle);
\r
410 if (newFractionDigits< 0)
\r
411 fracf.error(h, String.Format("The value '{0}' is an invalid fractionDigits value", newFractionDigits));
\r
413 if ((fractionDigitsFacet >= 0) && (newFractionDigits > fractionDigitsFacet)) {
\r
414 fracf.error(h, String.Format("The value '{0}' is not a valid restriction of the base fractionDigits facet '{1}'", newFractionDigits, fractionDigitsFacet));
\r
416 fractionDigitsFacet = newFractionDigits;
\r
418 catch (FormatException ) {
\r
419 fracf.error(h, String.Format("The value '{0}' is an invalid fractionDigits facet specification", fracf.Value.Trim () ));
\r
426 private void checkMinMaxFacet(XmlSchemaFacet facet,
\r
427 ref object baseFacet,
\r
428 ValidationEventHandler h) {
\r
429 // Is it a valid instance of the base type.
\r
430 object newValue = ValidateValueWithDatatype(facet.Value);
\r
431 if (newValue != null) {
\r
432 // Is the base fixed - if so is it the same
\r
433 if (((fixedFacets & facet.ThisFacet) != 0) && (baseFacet != null)){
\r
434 XsdAnySimpleType dt = getDatatype();
\r
435 if (dt.Compare (newValue, baseFacet) != XsdOrdering.Equal) {
\r
437 String.Format("{0} is not the same as fixed parent {1} facet.",
\r
438 facet.Value, facet.ThisFacet));
\r
441 baseFacet = newValue;
\r
445 String.Format("The value '{0}' is not valid against the base type.", facet.Value));
\r
451 private void checkLengthFacet(XmlSchemaLengthFacet lf,
\r
452 XmlSchemaFacet.Facet facetsDefined,
\r
453 ValidationEventHandler h) {
\r
456 if ((facetsDefined & (XmlSchemaFacet.Facet.minLength | XmlSchemaFacet.Facet.maxLength)) != 0)
\r
457 lf.error(h, "It is an error for both length and minLength or maxLength to be present.");
\r
459 lengthFacet = decimal.Parse (lf.Value.Trim (), lengthStyle);
\r
460 /* TODO: Check that it is between inherited max/min lengths */
\r
461 if (lengthFacet < 0)
\r
462 lf.error(h, "The value '" + lengthFacet + "' is an invalid length");
\r
464 } catch (FormatException) { // FIXME: better catch ;-(
\r
465 lf.error (h, "The value '" + lf.Value + "' is an invalid length facet specification");
\r
470 private void checkMaxLengthFacet(XmlSchemaMaxLengthFacet maxlf,
\r
471 XmlSchemaFacet.Facet facetsDefined,
\r
472 ValidationEventHandler h) {
\r
473 if (maxlf != null) {
\r
475 if ((facetsDefined & XmlSchemaFacet.Facet.length) != 0)
\r
476 maxlf.error(h, "It is an error for both length and minLength or maxLength to be present.");
\r
478 decimal newMaxLengthFacet = decimal.Parse (maxlf.Value.Trim (), lengthStyle);
\r
480 if (((fixedFacets & XmlSchemaFacet.Facet.maxLength)!=0) && (newMaxLengthFacet != maxLengthFacet))
\r
481 maxlf.error(h, String.Format("The value '{0}' is not the same as the fixed value '{1}' on the base type", maxlf.Value.Trim (), maxLengthFacet));
\r
482 if ((maxLengthFacet >0) && (newMaxLengthFacet > maxLengthFacet))
\r
483 maxlf.error(h, String.Format("The value '{0}' is not a valid restriction of the value '{1}' on the base maxLength facet", maxlf.Value.Trim (), maxLengthFacet));
\r
485 maxLengthFacet = newMaxLengthFacet;
\r
486 if (maxLengthFacet < 0)
\r
487 maxlf.error(h, "The value '" + maxLengthFacet + "' is an invalid maxLength");
\r
488 if (minLengthFacet >=0 && minLengthFacet > maxLengthFacet)
\r
489 maxlf.error(h, "minLength is greater than maxLength.");
\r
492 } catch (FormatException) {
\r
493 maxlf.error (h, "The value '" + maxlf.Value+ "' is an invalid maxLength facet specification");
\r
498 private void checkMinLengthFacet(XmlSchemaMinLengthFacet minlf,
\r
499 XmlSchemaFacet.Facet facetsDefined,
\r
500 ValidationEventHandler h) {
\r
501 if (minlf != null) {
\r
503 if (lengthFacet >=0)
\r
504 minlf.error(h, "It is an error for both length and minLength or maxLength to be present.");
\r
506 decimal newMinLengthFacet = decimal.Parse (minlf.Value.Trim (), lengthStyle);
\r
508 if (((fixedFacets & XmlSchemaFacet.Facet.minLength)!=0) && (newMinLengthFacet != minLengthFacet))
\r
509 minlf.error(h, String.Format("The value '{0}' is not the same as the fixed value '{1}' on the base type", minlf.Value.Trim (), minLengthFacet));
\r
510 if (newMinLengthFacet < minLengthFacet)
\r
511 minlf.error(h, String.Format("The value '{0}' is not a valid restriction of the value '{1}' on the base minLength facet", minlf.Value.Trim (), minLengthFacet));
\r
513 minLengthFacet = newMinLengthFacet;
\r
514 if (minLengthFacet < 0)
\r
515 minlf.error(h, "The value '" + minLengthFacet + "' is an invalid minLength");
\r
516 if (maxLengthFacet >=0 && minLengthFacet > maxLengthFacet)
\r
517 minlf.error(h, "minLength is greater than maxLength.");
\r
519 } catch (FormatException) {
\r
520 minlf.error (h, "The value '" + minlf.Value + "' is an invalid minLength facet specification");
\r
526 private XsdAnySimpleType getDatatype() {
\r
527 XsdAnySimpleType ast = ActualBaseSchemaType as XsdAnySimpleType;
\r
529 // Based directly on an xsd type
\r
532 XmlSchemaSimpleTypeContent st = ((XmlSchemaSimpleType)ActualBaseSchemaType).Content as XmlSchemaSimpleTypeContent;
\r
534 if (st is XmlSchemaSimpleTypeRestriction) {
\r
535 return ((XmlSchemaSimpleTypeRestriction)st).getDatatype();
\r
537 else if ((st is XmlSchemaSimpleTypeList) ||
\r
538 (st is XmlSchemaSimpleTypeUnion)) {
\r
545 private object ValidateValueWithDatatype(string value) {
\r
546 XsdAnySimpleType dt = getDatatype();
\r
548 // Console.WriteLine("DT: " + dt);
\r
551 /* I think we can parse null here, as the types
\r
552 * that use the nametable and nsmgr are ones that
\r
553 * we don't need to parse here.
\r
555 ret = dt.ParseValue (value, null, null);
\r
556 // Console.WriteLine("Ret: " + ret);
\r
557 // If we are based on something with facets, check that we are valid
\r
558 if (ActualBaseSchemaType is XmlSchemaSimpleType) {
\r
559 XmlSchemaSimpleTypeContent st = ((XmlSchemaSimpleType) ActualBaseSchemaType).Content as XmlSchemaSimpleTypeContent;
\r
560 if (st is XmlSchemaSimpleTypeRestriction) {
\r
561 if (((XmlSchemaSimpleTypeRestriction)st).ValidateValueWithFacets(value, null)) {
\r
569 }catch (Exception e) {
\r
576 internal bool ValidateValueWithFacets (string value, XmlNameTable nt)
\r
579 * FIXME: Shouldn't this be recursing more? What if this is a
\r
580 * restriction of a restriction of a list type?
\r
582 XmlSchemaSimpleType baseST = this.ActualBaseSchemaType as XmlSchemaSimpleType;
\r
583 XmlSchemaSimpleTypeList listType = baseST != null ? baseST.Content as XmlSchemaSimpleTypeList : null;
\r
586 if (listType != null)
\r
587 return ValidateListValueWithFacets (value, nt);
\r
589 return ValidateNonListValueWithFacets (value, nt);
\r
592 private bool ValidateListValueWithFacets (string value, XmlNameTable nt)
\r
594 string [] list = ((XsdAnySimpleType) XmlSchemaDatatype.FromName ("anySimpleType")).ParseListValue (value, nt);
\r
597 if (this.patternFacetValues != null) {
\r
598 for (int l = 0; l < list.Length; l++) {
\r
599 for (int i = 0; i < this.patternFacetValues.Length; i++)
\r
600 if (rexPatterns [i] != null && !rexPatterns [i].IsMatch (list [l]))
\r
605 if (this.enumarationFacetValues != null) {
\r
606 for (int l = 0; l < list.Length; l++) {
\r
607 bool matched = false;
\r
608 for (int i = 0; i < this.enumarationFacetValues.Length; i++) {
\r
609 if (list [l] == this.enumarationFacetValues [i]) {
\r
621 if (lengthFacet >= 0 && list.Length != lengthFacet)
\r
624 if (maxLengthFacet >= 0 && list.Length > maxLengthFacet)
\r
627 if (minLengthFacet >= 0 && list.Length < minLengthFacet)
\r
633 private bool ValidateNonListValueWithFacets (string value, XmlNameTable nt)
\r
636 // Patterns are the only facets that need to be checked on this
\r
637 // type and its base types. We should probably separate them, then
\r
638 // do base-type pattern validation.
\r
639 if (this.patternFacetValues != null) {
\r
640 bool matched = false;
\r
641 for (int i = 0; i < this.patternFacetValues.Length; i++)
\r
642 if (rexPatterns [i] != null && rexPatterns [i].IsMatch (value)) {
\r
650 if (this.enumarationFacetValues != null) {
\r
651 bool matched = false;
\r
652 for (int i = 0; i < this.enumarationFacetValues.Length; i++) {
\r
653 if (value == this.enumarationFacetValues [i]) {
\r
661 XsdAnySimpleType dt = getDatatype ();
\r
663 // Need to skip length tests for
\r
664 // types derived from QName or NOTATION
\r
665 // see errata: E2-36 Clarification
\r
667 if (! ( (dt is XsdQName) || (dt is XsdNotation))) {
\r
668 // Length potentially slower now, so only calculate if needed
\r
669 if (! (lengthFacet == -1) && (maxLengthFacet == -1) && (minLengthFacet == -1)) {
\r
674 int length = dt.Length(value);
\r
676 if (lengthFacet >= 0 && length != lengthFacet)
\r
679 if (maxLengthFacet >= 0 && length > maxLengthFacet)
\r
682 if (minLengthFacet >= 0 && length < minLengthFacet)
\r
688 if ((totalDigitsFacet >=0) || (fractionDigitsFacet >=0)) {
\r
689 String newValue = value.Trim(new Char [] { '+', '-', '0', '.' });
\r
690 int fractionDigits = 0;
\r
691 int totalDigits = newValue.Length;
\r
692 int point = newValue.IndexOf(".");
\r
695 fractionDigits = newValue.Length - point -1;
\r
697 if ((totalDigitsFacet >=0) && (totalDigits > totalDigitsFacet))
\r
699 if ((fractionDigitsFacet >=0) && (fractionDigits > fractionDigitsFacet))
\r
703 if ((maxInclusiveFacet != null) ||
\r
704 (maxExclusiveFacet != null) ||
\r
705 (minInclusiveFacet != null) ||
\r
706 (minExclusiveFacet != null)) {
\r
710 parsed = dt.ParseValue (value, nt, null);
\r
711 } catch (OverflowException ) {
\r
712 /* This appears to be what .NET does */
\r
714 } catch (FormatException ) {
\r
715 /* This appears to be what .NET does */
\r
719 if (maxInclusiveFacet != null) {
\r
720 XsdOrdering result = dt.Compare (parsed, maxInclusiveFacet);
\r
721 if ((result != XsdOrdering.LessThan) &&
\r
722 (result != XsdOrdering.Equal))
\r
725 if (maxExclusiveFacet != null) {
\r
727 XsdOrdering result = dt.Compare (parsed, maxExclusiveFacet);
\r
728 if (result != XsdOrdering.LessThan)
\r
731 if (minInclusiveFacet != null) {
\r
732 XsdOrdering result = dt.Compare (parsed, minInclusiveFacet);
\r
733 if ((result != XsdOrdering.GreaterThan) &&
\r
734 (result != XsdOrdering.Equal))
\r
737 if (minExclusiveFacet != null) {
\r
738 XsdOrdering result = dt.Compare (parsed, minExclusiveFacet);
\r
739 if (result != XsdOrdering.GreaterThan)
\r
753 // {any attributes with non-schema namespace . . .}>
\r
754 // Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*))
\r
756 internal static XmlSchemaSimpleTypeRestriction Read(XmlSchemaReader reader, ValidationEventHandler h)
\r
758 XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction();
\r
759 reader.MoveToElement();
\r
761 if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
\r
763 error(h,"Should not happen :1: XmlSchemaSimpleTypeRestriction.Read, name="+reader.Name,null);
\r
768 restriction.LineNumber = reader.LineNumber;
\r
769 restriction.LinePosition = reader.LinePosition;
\r
770 restriction.SourceUri = reader.BaseURI;
\r
772 while(reader.MoveToNextAttribute())
\r
774 if(reader.Name == "id")
\r
776 restriction.Id = reader.Value;
\r
778 else if(reader.Name == "base")
\r
781 restriction.baseTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
\r
782 if(innerex != null)
\r
783 error(h, reader.Value + " is not a valid value for base attribute",innerex);
\r
785 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
\r
787 error(h,reader.Name + " is not a valid attribute for restriction",null);
\r
791 XmlSchemaUtil.ReadUnhandledAttribute(reader,restriction);
\r
795 reader.MoveToElement();
\r
796 if(reader.IsEmptyElement)
\r
797 return restriction;
\r
799 // Content: annotation?, simpleType?, (minExclusive |. .. | pattern)*
\r
801 while(reader.ReadNextElement())
\r
803 if(reader.NodeType == XmlNodeType.EndElement)
\r
805 if(reader.LocalName != xmlname)
\r
806 error(h,"Should not happen :2: XmlSchemaSimpleTypeRestriction.Read, name="+reader.Name,null);
\r
809 if(level <= 1 && reader.LocalName == "annotation")
\r
811 level = 2; //Only one annotation
\r
812 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
\r
813 if(annotation != null)
\r
814 restriction.Annotation = annotation;
\r
817 if(level <= 2 && reader.LocalName == "simpleType")
\r
820 XmlSchemaSimpleType stype = XmlSchemaSimpleType.Read(reader,h);
\r
822 restriction.baseType = stype;
\r
827 if(reader.LocalName == "minExclusive")
\r
830 XmlSchemaMinExclusiveFacet minex = XmlSchemaMinExclusiveFacet.Read(reader,h);
\r
832 restriction.facets.Add(minex);
\r
835 else if(reader.LocalName == "minInclusive")
\r
838 XmlSchemaMinInclusiveFacet mini = XmlSchemaMinInclusiveFacet.Read(reader,h);
\r
840 restriction.facets.Add(mini);
\r
843 else if(reader.LocalName == "maxExclusive")
\r
846 XmlSchemaMaxExclusiveFacet maxex = XmlSchemaMaxExclusiveFacet.Read(reader,h);
\r
848 restriction.facets.Add(maxex);
\r
851 else if(reader.LocalName == "maxInclusive")
\r
854 XmlSchemaMaxInclusiveFacet maxi = XmlSchemaMaxInclusiveFacet.Read(reader,h);
\r
856 restriction.facets.Add(maxi);
\r
859 else if(reader.LocalName == "totalDigits")
\r
862 XmlSchemaTotalDigitsFacet total = XmlSchemaTotalDigitsFacet.Read(reader,h);
\r
864 restriction.facets.Add(total);
\r
867 else if(reader.LocalName == "fractionDigits")
\r
870 XmlSchemaFractionDigitsFacet fraction = XmlSchemaFractionDigitsFacet.Read(reader,h);
\r
871 if(fraction != null)
\r
872 restriction.facets.Add(fraction);
\r
875 else if(reader.LocalName == "length")
\r
878 XmlSchemaLengthFacet length = XmlSchemaLengthFacet.Read(reader,h);
\r
880 restriction.facets.Add(length);
\r
883 else if(reader.LocalName == "minLength")
\r
886 XmlSchemaMinLengthFacet minlen = XmlSchemaMinLengthFacet.Read(reader,h);
\r
888 restriction.facets.Add(minlen);
\r
891 else if(reader.LocalName == "maxLength")
\r
894 XmlSchemaMaxLengthFacet maxlen = XmlSchemaMaxLengthFacet.Read(reader,h);
\r
896 restriction.facets.Add(maxlen);
\r
899 else if(reader.LocalName == "enumeration")
\r
902 XmlSchemaEnumerationFacet enumeration = XmlSchemaEnumerationFacet.Read(reader,h);
\r
903 if(enumeration != null)
\r
904 restriction.facets.Add(enumeration);
\r
907 else if(reader.LocalName == "whiteSpace")
\r
910 XmlSchemaWhiteSpaceFacet ws = XmlSchemaWhiteSpaceFacet.Read(reader,h);
\r
912 restriction.facets.Add(ws);
\r
915 else if(reader.LocalName == "pattern")
\r
918 XmlSchemaPatternFacet pattern = XmlSchemaPatternFacet.Read(reader,h);
\r
919 if(pattern != null)
\r
920 restriction.facets.Add(pattern);
\r
924 reader.RaiseInvalidElementError();
\r
926 return restriction;
\r