|
|
@@ -6,6 +6,7 @@
|
|
|
// Enomoto, Atsushi [email protected]
|
|
|
//
|
|
|
using System;
|
|
|
+using System.Collections;
|
|
|
using System.Xml;
|
|
|
using System.ComponentModel;
|
|
|
using System.Xml.Serialization;
|
|
|
@@ -28,8 +29,11 @@ namespace System.Xml.Schema
|
|
|
private bool isAbstract;
|
|
|
private bool isMixed;
|
|
|
private XmlSchemaParticle particle;
|
|
|
-
|
|
|
- internal bool istoplevel = false;
|
|
|
+ private XmlSchemaContentType resolvedContentType;
|
|
|
+
|
|
|
+ internal bool ValidatedIsAbstract;
|
|
|
+ internal bool ParentIsSchema = false;
|
|
|
+
|
|
|
private static string xmlname = "complexType";
|
|
|
|
|
|
private static XmlSchemaComplexType anyType;
|
|
|
@@ -38,14 +42,19 @@ namespace System.Xml.Schema
|
|
|
get {
|
|
|
if (anyType == null) {
|
|
|
anyType = new XmlSchemaComplexType ();
|
|
|
- anyType.Name = "";
|
|
|
- anyType.QNameInternal = XmlQualifiedName.Empty;
|
|
|
- anyType.contentTypeParticle = XmlSchemaParticle.Empty;
|
|
|
+ anyType.Name = ""; // In MS.NET, it is not "anyType"
|
|
|
+ anyType.QNameInternal = XmlQualifiedName.Empty; // Not xs:anyType as well.
|
|
|
+ anyType.contentTypeParticle = XmlSchemaAny.AnyTypeContent;
|
|
|
+// anyType.baseSchemaTypeInternal = anyType;
|
|
|
+ anyType.datatypeInternal = XmlSchemaSimpleType.AnySimpleType;
|
|
|
+ anyType.isMixed = true;
|
|
|
}
|
|
|
return anyType;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ internal static readonly XmlQualifiedName AnyTypeName = new XmlQualifiedName ("anyType", XmlSchema.Namespace);
|
|
|
+
|
|
|
public XmlSchemaComplexType()
|
|
|
{
|
|
|
attributes = new XmlSchemaObjectCollection();
|
|
|
@@ -113,29 +122,16 @@ namespace System.Xml.Schema
|
|
|
get{ return anyAttribute; }
|
|
|
set{ anyAttribute = value; }
|
|
|
}
|
|
|
-
|
|
|
#endregion
|
|
|
|
|
|
#region XmlIgnore
|
|
|
[XmlIgnore]
|
|
|
public XmlSchemaContentType ContentType
|
|
|
{
|
|
|
- get{
|
|
|
- XmlSchemaComplexContent xcc =
|
|
|
- ContentModel as XmlSchemaComplexContent;
|
|
|
- if (xcc != null && xcc.IsMixed)
|
|
|
- return XmlSchemaContentType.Mixed;
|
|
|
-
|
|
|
- XmlSchemaSimpleContent xsc = ContentModel as XmlSchemaSimpleContent;
|
|
|
- if (xsc != null)
|
|
|
- return XmlSchemaContentType.TextOnly;
|
|
|
-
|
|
|
- return ContentTypeParticle != null ?
|
|
|
- XmlSchemaContentType.ElementOnly :
|
|
|
- XmlSchemaContentType.Empty;
|
|
|
- }
|
|
|
+ get{ return resolvedContentType; }
|
|
|
}
|
|
|
[XmlIgnore]
|
|
|
+ [MonoTODO ("Derivation is not supported yet.")]
|
|
|
public XmlSchemaParticle ContentTypeParticle
|
|
|
{
|
|
|
get{ return contentTypeParticle; }
|
|
|
@@ -172,14 +168,29 @@ namespace System.Xml.Schema
|
|
|
///
|
|
|
/// </remarks>
|
|
|
[MonoTODO]
|
|
|
- internal int Compile(ValidationEventHandler h, XmlSchema schema)
|
|
|
+ internal override int Compile(ValidationEventHandler h, XmlSchema schema)
|
|
|
{
|
|
|
// If this is already compiled this time, simply skip.
|
|
|
if (this.IsComplied (schema.CompilationId))
|
|
|
- return 0;
|
|
|
+ return errorCount;
|
|
|
+
|
|
|
+ ValidatedIsAbstract = isAbstract;
|
|
|
+
|
|
|
+ if (isRedefinedComponent) {
|
|
|
+ if (Annotation != null)
|
|
|
+ Annotation.isRedefinedComponent = true;
|
|
|
+ if (AnyAttribute != null)
|
|
|
+ AnyAttribute.isRedefinedComponent = true;
|
|
|
+ foreach (XmlSchemaObject obj in Attributes)
|
|
|
+ obj.isRedefinedComponent = true;
|
|
|
+ if (ContentModel != null)
|
|
|
+ ContentModel.isRedefinedComponent = true;
|
|
|
+ if (Particle != null)
|
|
|
+ Particle.isRedefinedComponent = true;
|
|
|
+ }
|
|
|
|
|
|
// block/final resolution
|
|
|
- if(istoplevel)
|
|
|
+ if(ParentIsSchema || isRedefineChild)
|
|
|
{
|
|
|
if(this.Name == null || this.Name == string.Empty)
|
|
|
error(h,"name must be present in a top level complex type");
|
|
|
@@ -197,7 +208,9 @@ namespace System.Xml.Schema
|
|
|
else
|
|
|
{
|
|
|
//TODO: Check what all is not allowed
|
|
|
- blockResolved = Block & (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
|
|
|
+ if ((Block & XmlSchemaUtil.ComplexTypeBlockAllowed) != Block)
|
|
|
+ error (h, "Invalid block specification.");
|
|
|
+ blockResolved = Block & XmlSchemaUtil.ComplexTypeBlockAllowed;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
@@ -207,24 +220,22 @@ namespace System.Xml.Schema
|
|
|
blockResolved = XmlSchemaDerivationMethod.All;
|
|
|
break;
|
|
|
case XmlSchemaDerivationMethod.None:
|
|
|
- blockResolved = XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction;
|
|
|
+ blockResolved = XmlSchemaDerivationMethod.Empty;
|
|
|
break;
|
|
|
default:
|
|
|
- blockResolved = schema.BlockDefault & (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
|
|
|
+ blockResolved = schema.BlockDefault & XmlSchemaUtil.ComplexTypeBlockAllowed;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
if(Final != XmlSchemaDerivationMethod.None)
|
|
|
{
|
|
|
if(Final == XmlSchemaDerivationMethod.All)
|
|
|
- {
|
|
|
finalResolved = XmlSchemaDerivationMethod.All;
|
|
|
- }
|
|
|
+ else if ((Final & XmlSchemaUtil.FinalAllowed) != Final)
|
|
|
+ error (h, "Invalid final specification.");
|
|
|
else
|
|
|
- {
|
|
|
- //TODO: Check what all is not allowed
|
|
|
- finalResolved = Final & (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
|
|
|
- }
|
|
|
+ finalResolved = Final;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -233,10 +244,10 @@ namespace System.Xml.Schema
|
|
|
finalResolved = XmlSchemaDerivationMethod.All;
|
|
|
break;
|
|
|
case XmlSchemaDerivationMethod.None:
|
|
|
- finalResolved = XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction;
|
|
|
+ finalResolved = XmlSchemaDerivationMethod.Empty;
|
|
|
break;
|
|
|
default:
|
|
|
- finalResolved = schema.FinalDefault & (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
|
|
|
+ finalResolved = schema.FinalDefault & XmlSchemaUtil.FinalAllowed;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
@@ -254,56 +265,45 @@ namespace System.Xml.Schema
|
|
|
}
|
|
|
|
|
|
// Process contents and BaseSchemaType
|
|
|
- if(ContentModel != null)
|
|
|
+ if(contentModel != null)
|
|
|
{
|
|
|
if(anyAttribute != null || Attributes.Count != 0 || Particle != null)
|
|
|
error(h,"attributes, particles or anyattribute is not allowed if ContentModel is present");
|
|
|
+ errorCount += contentModel.Compile (h, schema);
|
|
|
|
|
|
XmlQualifiedName baseTypeName = null;
|
|
|
- if(ContentModel is XmlSchemaSimpleContent)
|
|
|
+ XmlSchemaSimpleContent smodel = ContentModel as XmlSchemaSimpleContent;
|
|
|
+ if(smodel != null)
|
|
|
{
|
|
|
- XmlSchemaSimpleContent smodel = (XmlSchemaSimpleContent)ContentModel;
|
|
|
- errorCount += smodel.Compile(h,schema);
|
|
|
-
|
|
|
XmlSchemaSimpleContentExtension sscx = smodel.Content as XmlSchemaSimpleContentExtension;
|
|
|
if (sscx != null)
|
|
|
baseTypeName = sscx.BaseTypeName;
|
|
|
else {
|
|
|
XmlSchemaSimpleContentRestriction sscr = smodel.Content as XmlSchemaSimpleContentRestriction;
|
|
|
- baseTypeName = sscr.BaseTypeName;
|
|
|
- if (sscr.BaseType != null) {
|
|
|
- sscr.BaseType.Compile (h, schema);
|
|
|
- BaseSchemaTypeInternal = sscr.BaseType;
|
|
|
+ if (sscr != null) {
|
|
|
+ baseTypeName = sscr.BaseTypeName;
|
|
|
+ if (sscr.BaseType != null) {
|
|
|
+ sscr.BaseType.Compile (h, schema);
|
|
|
+ baseSchemaTypeInternal = sscr.BaseType;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ contentTypeParticle = XmlSchemaParticle.Empty;
|
|
|
}
|
|
|
- else if(ContentModel is XmlSchemaComplexContent)
|
|
|
+ else
|
|
|
{
|
|
|
- XmlSchemaComplexContent cmodel = (XmlSchemaComplexContent)ContentModel;
|
|
|
- errorCount += cmodel.Compile(h,schema);
|
|
|
-
|
|
|
+ XmlSchemaComplexContent cmodel = (XmlSchemaComplexContent) ContentModel;
|
|
|
XmlSchemaComplexContentExtension sccx = cmodel.Content as XmlSchemaComplexContentExtension;
|
|
|
if (sccx != null) {
|
|
|
contentTypeParticle = sccx.Particle;
|
|
|
baseTypeName = sccx.BaseTypeName;
|
|
|
}
|
|
|
else {
|
|
|
- XmlSchemaComplexContentRestriction sccr = cmodel.Content as XmlSchemaComplexContentRestriction;
|
|
|
- contentTypeParticle = sccr.Particle;
|
|
|
- baseTypeName = sccr.BaseTypeName;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // fill base schema type
|
|
|
- if (BaseSchemaTypeInternal == null && baseTypeName != null) { // simple content restriction may have type itself.
|
|
|
- if (baseTypeName.Namespace == XmlSchema.Namespace)
|
|
|
- BaseSchemaTypeInternal = XmlSchemaDatatype.FromName (baseTypeName);
|
|
|
- else {
|
|
|
- XmlSchema targetSchema = schema.Schemas [baseTypeName.Namespace];
|
|
|
- if (targetSchema != null)
|
|
|
- BaseSchemaTypeInternal = schema.SchemaTypes [baseTypeName];
|
|
|
- if (BaseSchemaTypeInternal == null)
|
|
|
- schema.MissingBaseSchemaTypeRefs.Add (this, baseTypeName);
|
|
|
+ XmlSchemaComplexContentRestriction sccr = (XmlSchemaComplexContentRestriction) cmodel.Content;
|
|
|
+ if (sccr != null) {
|
|
|
+ contentTypeParticle = sccr.Particle;
|
|
|
+ baseTypeName = sccr.BaseTypeName;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -356,13 +356,499 @@ namespace System.Xml.Schema
|
|
|
this.CompilationId = schema.CompilationId;
|
|
|
return errorCount;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
[MonoTODO]
|
|
|
- internal int Validate(ValidationEventHandler h)
|
|
|
+ internal override int Validate(ValidationEventHandler h, XmlSchema schema)
|
|
|
{
|
|
|
+ if (IsValidated (schema.ValidationId))
|
|
|
+ return errorCount;
|
|
|
+ // FIXME: omitting it causes StackOverflowException
|
|
|
+ // among the compilation of element and types, but
|
|
|
+ // it may result in insufficient results.
|
|
|
+ ValidationId = schema.ValidationId;
|
|
|
+
|
|
|
+ // Term. 1 of 3.4.6 = 3.4.1 : Complex Type Definitions Properties Correct
|
|
|
+ // Term. 2 and 3 goes ValidateContentModel().
|
|
|
+ // Term. 4 and 5 follows in this method.
|
|
|
+ //
|
|
|
+ // Schema component to CLR type property mapping:
|
|
|
+ // {derivation method} => resolvedDerivedBy
|
|
|
+ // {annotations} are as is.
|
|
|
+ // {name}, {namespace} => QualifiedName
|
|
|
+ // {final} and {prohibited substitutions} are Compile()d.
|
|
|
+ // {abstract} => ValidatedIsAbstract
|
|
|
+
|
|
|
+ // Below are different properties depending on simpleContent | complexContent.
|
|
|
+ // {base type definition} => BaseSchemaType (later)
|
|
|
+ // {attribute uses} => AttributeUses (later)
|
|
|
+ // {content type} => ContentType and ContentTypeParticle (later)
|
|
|
+
|
|
|
+ // TODO: Beware of E1-27 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
|
|
|
+ if (contentModel != null)
|
|
|
+ ValidateContentModel (h, schema);
|
|
|
+ else {
|
|
|
+ if (particle != null)
|
|
|
+ ValidateParticle (h, schema);
|
|
|
+ // contentModel never has them.
|
|
|
+ ValidateImmediateAttributes (h, schema);
|
|
|
+ }
|
|
|
+ // Additional support for 3.8.6 All Group Limited
|
|
|
+ if (contentTypeParticle != null) {
|
|
|
+ XmlSchemaAll termAll = contentTypeParticle.ActualParticle as XmlSchemaAll;
|
|
|
+ if (termAll != null && contentTypeParticle.ValidatedMaxOccurs != 1)
|
|
|
+ error (h, "Particle whose term is -all- and consists of complex type content particle must have maxOccurs = 1.");
|
|
|
+ }
|
|
|
+
|
|
|
+ // {content type} is going to be finished.
|
|
|
+ if (contentTypeParticle == null)
|
|
|
+ contentTypeParticle = XmlSchemaParticle.Empty;
|
|
|
+ contentTypeParticle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),
|
|
|
+ new ArrayList (), h, schema);
|
|
|
+ contentTypeParticle.ValidateUniqueTypeAttribution (
|
|
|
+ new XmlSchemaObjectTable (), h, schema);
|
|
|
+ resolvedContentType = GetContentType ();
|
|
|
+
|
|
|
+ // 3.4.6 Properties Correct :: 5 (Two distinct ID attributes)
|
|
|
+ XmlSchemaAttribute idAttr = null;
|
|
|
+ foreach (XmlSchemaAttribute attr in attributeUses) {
|
|
|
+ XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;
|
|
|
+ if (dt != null && dt.TokenizedType != XmlTokenizedType.ID)
|
|
|
+ continue;
|
|
|
+ if (dt == null)
|
|
|
+ dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;
|
|
|
+ if (dt != null && dt.TokenizedType == XmlTokenizedType.ID) {
|
|
|
+ if (idAttr != null)
|
|
|
+ error (h, "Two or more ID typed attribute declarations in a complex type are found.");
|
|
|
+ else
|
|
|
+ idAttr = attr;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ValidationId = schema.ValidationId;
|
|
|
return errorCount;
|
|
|
}
|
|
|
|
|
|
+ private void ValidateParticle (ValidationEventHandler h, XmlSchema schema)
|
|
|
+ {
|
|
|
+ // {content type} as a particle.
|
|
|
+ errorCount += particle.Validate (h, schema);
|
|
|
+ contentTypeParticle = Particle;
|
|
|
+ XmlSchemaGroupRef pgrp = Particle as XmlSchemaGroupRef;
|
|
|
+ if (pgrp != null) {
|
|
|
+ if (pgrp.TargetGroup != null)
|
|
|
+ errorCount += pgrp.TargetGroup.Validate (h,schema);
|
|
|
+ // otherwise, it might be missing sub components.
|
|
|
+ else if (!schema.missedSubComponents)// && schema.Schemas [pgrp.RefName.Namespace] != null)
|
|
|
+ error (h, "Referenced group " + pgrp.RefName + " was not found in the corresponding schema.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ValidateImmediateAttributes (ValidationEventHandler h, XmlSchema schema)
|
|
|
+ {
|
|
|
+ // {attribute uses}
|
|
|
+ // also checks 3.4.6 Properties Correct :: 4 (Distinct attributes)
|
|
|
+ attributeUses = new XmlSchemaObjectTable ();
|
|
|
+ XmlSchemaUtil.ValidateAttributesResolved (attributeUses,
|
|
|
+ h, schema, attributes, anyAttribute, ref attributeWildcard, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ValidateContentModel (ValidationEventHandler h, XmlSchema schema)
|
|
|
+ {
|
|
|
+ // Here we check 3.4.6 Properties Correct :: 2. and 3.
|
|
|
+ errorCount += contentModel.Validate (h, schema);
|
|
|
+ XmlSchemaComplexContentExtension cce = contentModel.Content as XmlSchemaComplexContentExtension;
|
|
|
+ XmlSchemaComplexContentRestriction ccr = contentModel.Content as XmlSchemaComplexContentRestriction;
|
|
|
+ XmlSchemaSimpleContentExtension sce = contentModel.Content as XmlSchemaSimpleContentExtension;
|
|
|
+ XmlSchemaSimpleContentRestriction scr = contentModel.Content as XmlSchemaSimpleContentRestriction;
|
|
|
+
|
|
|
+ XmlSchemaAnyAttribute localAnyAttribute = null;
|
|
|
+ XmlSchemaAnyAttribute baseAnyAttribute = null;
|
|
|
+
|
|
|
+ XmlQualifiedName baseTypeName = null;
|
|
|
+ if (cce != null)
|
|
|
+ baseTypeName = cce.BaseTypeName;
|
|
|
+ else if (ccr != null)
|
|
|
+ baseTypeName = ccr.BaseTypeName;
|
|
|
+ else if (sce != null)
|
|
|
+ baseTypeName = sce.BaseTypeName;
|
|
|
+ else
|
|
|
+ baseTypeName = scr.BaseTypeName;
|
|
|
+
|
|
|
+ XmlSchemaType baseType = schema.SchemaTypes [baseTypeName] as XmlSchemaType;
|
|
|
+ // Resolve redefine.
|
|
|
+ if (this.isRedefineChild && baseType != null && this.QualifiedName == baseTypeName) {
|
|
|
+ baseType = (XmlSchemaType) redefinedObject;
|
|
|
+ if (baseType == null)
|
|
|
+ error (h, "Redefinition base type was not found.");
|
|
|
+ baseType.Validate (h, schema);
|
|
|
+ }
|
|
|
+ // 3.4.6 Properties Correct :: 3. Circular definition prohibited.
|
|
|
+ if (ValidateRecursionCheck ())
|
|
|
+ error (h, "Circular definition of schema types was found.");
|
|
|
+ if (baseType != null) {
|
|
|
+ baseType.Validate (h, schema);
|
|
|
+ // Fill "Datatype" property.
|
|
|
+ this.datatypeInternal = baseType.Datatype;
|
|
|
+ } else if (baseTypeName == XmlSchemaComplexType.AnyTypeName)
|
|
|
+ datatypeInternal = XmlSchemaSimpleType.AnySimpleType;
|
|
|
+ else if (baseTypeName.Namespace == XmlSchema.Namespace) {
|
|
|
+ datatypeInternal = XmlSchemaDatatype.FromName (baseTypeName);
|
|
|
+ }
|
|
|
+
|
|
|
+ // {derivation method}
|
|
|
+ XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;
|
|
|
+ XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;
|
|
|
+ if (cce != null || sce != null)
|
|
|
+ resolvedDerivedBy = XmlSchemaDerivationMethod.Extension;
|
|
|
+ else
|
|
|
+ resolvedDerivedBy = XmlSchemaDerivationMethod.Restriction;
|
|
|
+
|
|
|
+ // 3.4.6 Derivation Valid (common to Extension and Restriction, Complex) :: 1.
|
|
|
+ if (baseType != null && (baseType.FinalResolved & resolvedDerivedBy) != 0)
|
|
|
+ error (h, "Specified derivation is specified as final by derived schema type.");
|
|
|
+
|
|
|
+ // 3.4.6 Properties Correct :: 2.
|
|
|
+ // Simple {base type definition} and restriction {derivation method} not allowed.
|
|
|
+ if (baseSimpleType != null && resolvedDerivedBy == XmlSchemaDerivationMethod.Restriction)
|
|
|
+ error (h, "If the base schema type is a simple type, then this type must be extension.");
|
|
|
+
|
|
|
+ // Common to complexContent
|
|
|
+ if (cce != null || ccr != null) {
|
|
|
+ // 3.4.3 Complex Type Definition Representation OK :: 1.
|
|
|
+ // base
|
|
|
+ if (baseTypeName == XmlSchemaComplexType.AnyTypeName)
|
|
|
+ baseComplexType = XmlSchemaComplexType.AnyType;
|
|
|
+ else if (baseComplexType == null && !schema.missedSubComponents)
|
|
|
+ error (h, "Referenced base schema type " + baseTypeName + " was not complex type or not found in the corresponding schema.");
|
|
|
+ }
|
|
|
+ // Common to simpleContent
|
|
|
+ else {
|
|
|
+ // 3.4.3 Complex Type Definition Representation OK :: 1.
|
|
|
+ // base
|
|
|
+ if (baseTypeName == XmlSchemaComplexType.AnyTypeName)
|
|
|
+ baseComplexType = XmlSchemaComplexType.AnyType;
|
|
|
+
|
|
|
+ if (baseComplexType != null && baseComplexType.ContentType != XmlSchemaContentType.TextOnly) {
|
|
|
+ error (h, "Base schema complex type of a simple content must be simple content type. Base type is " + baseTypeName);
|
|
|
+ } else if (sce == null && (baseSimpleType != null && baseTypeName.Namespace != XmlSchema.Namespace)) {
|
|
|
+ error (h, "If a simple content is not an extension, base schema type must be complex type. Base type is " + baseTypeName);
|
|
|
+ } else if (baseTypeName.Namespace == XmlSchema.Namespace) {
|
|
|
+ if (XmlSchemaDatatype.FromName (baseTypeName) == null)
|
|
|
+ error (h, "Invalid schema data type was specified: " + baseTypeName);
|
|
|
+ // do nothing for particle.
|
|
|
+ }
|
|
|
+ // otherwise, it might be missing sub components.
|
|
|
+ else if (baseType == null && !schema.missedSubComponents)// && schema.Schemas [baseTypeName.Namespace] != null)
|
|
|
+ error (h, "Referenced base schema type " + baseTypeName + " was not found in the corresponding schema.");
|
|
|
+ }
|
|
|
+
|
|
|
+ // complexType/complexContent/extension
|
|
|
+ if (cce != null) {
|
|
|
+ // ContentTypeParticle
|
|
|
+ if (baseComplexType == null) {
|
|
|
+ // Basically it is an error. Considering ValidationEventHandler.
|
|
|
+ }
|
|
|
+ else if (baseComplexType.ContentTypeParticle == XmlSchemaParticle.Empty
|
|
|
+ || baseComplexType == XmlSchemaComplexType.AnyType)
|
|
|
+ contentTypeParticle = cce.Particle;
|
|
|
+ else if (cce.Particle == null || cce.Particle == XmlSchemaParticle.Empty)
|
|
|
+ contentTypeParticle = baseComplexType.ContentTypeParticle;
|
|
|
+ else {
|
|
|
+ // create a new sequences that merges both contents.
|
|
|
+ XmlSchemaSequence seq = new XmlSchemaSequence ();
|
|
|
+ seq.Items.Add (baseComplexType.ContentTypeParticle);
|
|
|
+ seq.Items.Add (cce.Particle);
|
|
|
+ seq.Compile (h, schema);
|
|
|
+ seq.Validate (h, schema);
|
|
|
+ contentTypeParticle = seq;
|
|
|
+ }
|
|
|
+
|
|
|
+ // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
|
|
|
+ // is constraining anything here, since 3.4.2 {attribute uses}
|
|
|
+ // defines as to include base type's attribute uses.
|
|
|
+ localAnyAttribute = cce.AnyAttribute;
|
|
|
+ if (baseComplexType != null) {
|
|
|
+ foreach (XmlSchemaAttribute attr in baseComplexType.AttributeUses)
|
|
|
+ XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
|
|
|
+ baseAnyAttribute = baseComplexType.AttributeWildcard;
|
|
|
+ }
|
|
|
+ // attributes
|
|
|
+ errorCount += XmlSchemaUtil.ValidateAttributesResolved (
|
|
|
+ this.attributeUses, h, schema, cce.Attributes,
|
|
|
+ cce.AnyAttribute , ref attributeWildcard, null);
|
|
|
+
|
|
|
+ // After adding them, test extension validity.
|
|
|
+ if (baseComplexType != null)
|
|
|
+ this.ValidateComplexBaseDerivationValidExtension (baseComplexType, h, schema);
|
|
|
+ else if (baseSimpleType != null)
|
|
|
+ this.ValidateSimpleBaseDerivationValidExtension (baseSimpleType, h, schema);
|
|
|
+ }
|
|
|
+ // complexType/complexContent/restriction
|
|
|
+ if (ccr != null) {
|
|
|
+ // For ValidationEventHandler.
|
|
|
+ if (baseComplexType == null)
|
|
|
+ baseComplexType = XmlSchemaComplexType.AnyType;
|
|
|
+
|
|
|
+ // ContentTypeParticles (It must contain base type's particle).
|
|
|
+ if (ccr.Particle != null) {
|
|
|
+ ccr.Particle.Validate (h, schema);
|
|
|
+ contentTypeParticle = ccr.Particle;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ contentTypeParticle = XmlSchemaParticle.Empty;
|
|
|
+
|
|
|
+ localAnyAttribute = ccr.AnyAttribute;
|
|
|
+ this.attributeWildcard = localAnyAttribute;
|
|
|
+ if (baseComplexType != null)
|
|
|
+ baseAnyAttribute = baseComplexType.AttributeWildcard;
|
|
|
+ if (baseAnyAttribute != null && localAnyAttribute != null)
|
|
|
+ // 1.3 attribute wildcard subset. (=> 3.10.6)
|
|
|
+ baseAnyAttribute.ValidateWildcardSubset (localAnyAttribute, h, schema);
|
|
|
+
|
|
|
+ // FIXME: Check 3.4.2 Complex Type Definition with complex content Schema Component
|
|
|
+ // and its {attribute uses} and {attribute wildcard}
|
|
|
+ errorCount += XmlSchemaUtil.ValidateAttributesResolved (
|
|
|
+ this.attributeUses, h, schema, ccr.Attributes,
|
|
|
+ ccr.AnyAttribute, ref attributeWildcard, null);
|
|
|
+ foreach (XmlSchemaAttribute attr in baseComplexType.AttributeUses) {
|
|
|
+ if (attributeUses [attr.QualifiedName] == null)
|
|
|
+ XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Derivation Valid (Restriction, Complex) :: 5.
|
|
|
+ // Also see E1-15 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
|
|
|
+ // 5.1 shouled be in scr (XmlSchemaSimpleContentRestriction)
|
|
|
+ this.ValidateDerivationValidRestriction (baseComplexType, h, schema);
|
|
|
+ }
|
|
|
+ // complexType/simpleContent/extension
|
|
|
+ if (sce != null) {
|
|
|
+ errorCount += XmlSchemaUtil.ValidateAttributesResolved (
|
|
|
+ this.attributeUses, h, schema, sce.Attributes,
|
|
|
+ sce.AnyAttribute, ref attributeWildcard, null);
|
|
|
+
|
|
|
+ // Attributes
|
|
|
+ // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
|
|
|
+ // is constraining anything here, since 3.4.2 {attribute uses}
|
|
|
+ // defines as to include base type's attribute uses.
|
|
|
+ localAnyAttribute = sce.AnyAttribute;
|
|
|
+
|
|
|
+ if (baseComplexType != null) {
|
|
|
+ baseAnyAttribute = baseComplexType.AttributeWildcard;
|
|
|
+
|
|
|
+ foreach (XmlSchemaAttribute attr in baseComplexType.AttributeUses)
|
|
|
+ XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
|
|
|
+ }
|
|
|
+ if (baseAnyAttribute != null && localAnyAttribute != null)
|
|
|
+ // 1.3 attribute wildcard subset. (=> 3.10.6)
|
|
|
+ localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
|
|
|
+ }
|
|
|
+ // complexType/simpleContent/restriction
|
|
|
+ if (scr != null) {
|
|
|
+ if (baseComplexType == null) {
|
|
|
+ // 3.4.3 :: 2.
|
|
|
+ error (h, "Base type of a simple content restriction must be a complex type.");
|
|
|
+ } else {
|
|
|
+ // Attributes
|
|
|
+ baseAnyAttribute = baseComplexType.AttributeWildcard;
|
|
|
+
|
|
|
+ localAnyAttribute = scr.AnyAttribute;
|
|
|
+ if (localAnyAttribute != null && baseAnyAttribute != null)
|
|
|
+ // 1.3 attribute wildcard subset. (=> 3.10.6)
|
|
|
+ baseAnyAttribute.ValidateWildcardSubset (localAnyAttribute, h, schema);
|
|
|
+ // TODO: 3.4.6 :: 5.1. Beware that There is an errata for 5.1!!
|
|
|
+ // http://www.w3.org/2001/05/xmlschema-errata#Errata1
|
|
|
+
|
|
|
+ // FIXME: Check 3.4.2 Complex Type Definition with simple content Schema Component
|
|
|
+ // and its {attribute uses} and {attribute wildcard}
|
|
|
+ errorCount += XmlSchemaUtil.ValidateAttributesResolved (
|
|
|
+ this.attributeUses, h, schema, scr.Attributes,
|
|
|
+ scr.AnyAttribute, ref attributeWildcard, null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Common process of AttributeWildcard.
|
|
|
+ // TODO: Check 3.4.2 {attribute wildcard} to fill the complete wildcard.
|
|
|
+ if (localAnyAttribute != null) {
|
|
|
+ this.attributeWildcard = localAnyAttribute;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ this.attributeWildcard = baseAnyAttribute;
|
|
|
+ this.baseSchemaTypeInternal = baseType;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AddExtensionAttributes (XmlSchemaObjectCollection attributes,
|
|
|
+ XmlSchemaAnyAttribute anyAttribute, ValidationEventHandler h, XmlSchema schema)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ // It was formerly placed directly in ContentType property.
|
|
|
+ // I get it out, since ContentType is _post_ compilation property value.
|
|
|
+ private XmlSchemaContentType GetContentType ()
|
|
|
+ {
|
|
|
+ if (this.isMixed)
|
|
|
+ return XmlSchemaContentType.Mixed;
|
|
|
+ XmlSchemaComplexContent xcc =
|
|
|
+ ContentModel as XmlSchemaComplexContent;
|
|
|
+ if (xcc != null && xcc.IsMixed)
|
|
|
+ return XmlSchemaContentType.Mixed;
|
|
|
+
|
|
|
+ XmlSchemaSimpleContent xsc = ContentModel as XmlSchemaSimpleContent;
|
|
|
+ if (xsc != null)
|
|
|
+ return XmlSchemaContentType.TextOnly;
|
|
|
+
|
|
|
+ return contentTypeParticle != XmlSchemaParticle.Empty ?
|
|
|
+ XmlSchemaContentType.ElementOnly :
|
|
|
+ XmlSchemaContentType.Empty;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3.4.6 Type Derivation OK (Complex)
|
|
|
+ internal void ValidateTypeDerivationOK (object b, ValidationEventHandler h, XmlSchema schema)
|
|
|
+ {
|
|
|
+ // AnyType derives from AnyType itself.
|
|
|
+ if (this == XmlSchemaComplexType.AnyType && BaseSchemaType == this)
|
|
|
+ return;
|
|
|
+
|
|
|
+ XmlSchemaType bst = b as XmlSchemaType;
|
|
|
+ if (b == this) // 1 and 2.1
|
|
|
+ return;
|
|
|
+ if (bst != null && (resolvedDerivedBy & bst.FinalResolved) != 0) // 1
|
|
|
+ error (h, "Derivation type " + resolvedDerivedBy + " is prohibited by the base type.");
|
|
|
+ if (BaseSchemaType == b) // 2.2
|
|
|
+ return;
|
|
|
+ if (BaseSchemaType == XmlSchemaComplexType.AnyType) { // 2.3.1
|
|
|
+ error (h, "Derived type's base schema type is anyType.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 2.3.2.1
|
|
|
+ XmlSchemaComplexType dbct = BaseSchemaType as XmlSchemaComplexType;
|
|
|
+ if (dbct != null) {
|
|
|
+ dbct.ValidateTypeDerivationOK (b, h, schema);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 2.3.2.2
|
|
|
+ XmlSchemaSimpleType dbst = BaseSchemaType as XmlSchemaSimpleType;
|
|
|
+ if (dbst != null) {
|
|
|
+ dbst.ValidateTypeDerivationOK (b, h, schema, true);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Term. 1 of 3.4.6 Derivation Valid (Extension)
|
|
|
+ internal void ValidateComplexBaseDerivationValidExtension (XmlSchemaComplexType baseComplexType,
|
|
|
+ ValidationEventHandler h, XmlSchema schema)
|
|
|
+ {
|
|
|
+ // 1.1
|
|
|
+ if ((baseComplexType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
|
|
|
+ error (h, "Derivation by extension is prohibited.");
|
|
|
+ // 1.2
|
|
|
+ foreach (XmlSchemaAttribute ba in baseComplexType.AttributeUses) {
|
|
|
+ XmlSchemaAttribute da = AttributeUses [ba.QualifiedName] as XmlSchemaAttribute;
|
|
|
+ if (da == null)
|
|
|
+ error (h, "Invalid complex type derivation by extension was found. Missing attribute was found: " + ba.QualifiedName + " .");
|
|
|
+ // TODO: How to evaluate "equal" type ...?
|
|
|
+ }
|
|
|
+ // 1.3 -> 3.10.6 Wildcard Subset.
|
|
|
+ if (AnyAttribute != null) {
|
|
|
+ if (baseComplexType.AnyAttribute == null)
|
|
|
+ error (h, "Invalid complex type derivation by extension was found. Base complex type does not have an attribute wildcard.");
|
|
|
+ else
|
|
|
+ baseComplexType.AnyAttribute.ValidateWildcardSubset (AnyAttribute, h, schema);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1.4 => 1.4.2 (1.4.1 would be included in SimpleContentExtention).
|
|
|
+ // 1.4.2.1
|
|
|
+// if (contentTypeParticle == null)
|
|
|
+// error (h, "Extended complex type's content type must not be empty.");
|
|
|
+ // 1.4.2.2.1
|
|
|
+ if (baseComplexType.ContentType != XmlSchemaContentType.Empty) {
|
|
|
+ // 1.4.2.2.2.1
|
|
|
+ if (this.GetContentType () == baseComplexType.ContentType) {
|
|
|
+ // nothing to do
|
|
|
+ }
|
|
|
+ // 1.4.2.2.2.2
|
|
|
+ // 3.9.6 Particle Valid (Extension)
|
|
|
+ else if (this.contentTypeParticle != baseComplexType.ContentTypeParticle) {
|
|
|
+ XmlSchemaSequence seq = contentTypeParticle as XmlSchemaSequence;
|
|
|
+ if (contentTypeParticle.ValidatedMinOccurs != 1 ||
|
|
|
+ contentTypeParticle.ValidatedMaxOccurs != 1 ||
|
|
|
+ seq == null)
|
|
|
+ error (h, "Invalid complex content extension was found.");
|
|
|
+ else {
|
|
|
+ // Identical sequence item should be checked, but
|
|
|
+ // I think it is naturally achieved as coded above.
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ error (h, "Invalid complex content extension was found. Extended complex type has different content type from base type.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Term. 2 of 3.4.6 Derivation Valid (Extension)
|
|
|
+ internal void ValidateSimpleBaseDerivationValidExtension (object baseType,
|
|
|
+ ValidationEventHandler h, XmlSchema schema)
|
|
|
+ {
|
|
|
+ XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;
|
|
|
+ if (st != null && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
|
|
|
+ error (h, "Extension is prohibited by the base type.");
|
|
|
+
|
|
|
+ XmlSchemaDatatype dt = baseType as XmlSchemaDatatype;
|
|
|
+ if (dt == null)
|
|
|
+ dt = st.Datatype;
|
|
|
+ if (dt != this.Datatype)
|
|
|
+ error (h, "To extend simple type, a complex type must have the same content type as the base type.");
|
|
|
+
|
|
|
+ /*
|
|
|
+ switch (resolvedContentType) {
|
|
|
+ case XmlSchemaContentType.Mixed:
|
|
|
+ case XmlSchemaContentType.TextOnly:
|
|
|
+ XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;
|
|
|
+ if ((st == null && Datatype != baseType) ||
|
|
|
+ (st != null && st.Datatype != Datatype))
|
|
|
+ goto case XmlSchemaContentType.ElementOnly;
|
|
|
+ if (st != null
|
|
|
+ && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
|
|
|
+ error (h, "Extension is prohibited by the base type.");
|
|
|
+ break;
|
|
|
+ case XmlSchemaContentType.ElementOnly:
|
|
|
+ case XmlSchemaContentType.Empty:
|
|
|
+ error (h, "To extend simple type, a complex type must have the same content type as the base type.");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ */
|
|
|
+ }
|
|
|
+
|
|
|
+ internal void ValidateDerivationValidRestriction (XmlSchemaComplexType baseType,
|
|
|
+ ValidationEventHandler h, XmlSchema schema)
|
|
|
+ {
|
|
|
+ // 1.
|
|
|
+ if (baseType == null) {
|
|
|
+ error (h, "Base schema type is not a complex type.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
|
|
|
+ error (h, "Prohibited derivation by restriction by base schema type.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // TODO: 2. - 4.
|
|
|
+
|
|
|
+ // 5.
|
|
|
+ if (contentTypeParticle == XmlSchemaParticle.Empty) {
|
|
|
+ // TODO: 5.1
|
|
|
+ // 5.2
|
|
|
+ if (baseType.ContentTypeParticle != XmlSchemaParticle.Empty &&
|
|
|
+ !baseType.ContentTypeParticle.ValidateIsEmptiable ())
|
|
|
+ error (h, "Invalid content type derivation.");
|
|
|
+ } else {
|
|
|
+ // 5.3 => 3.9.6 Particle Valid (Restriction)
|
|
|
+ if (baseType.ContentTypeParticle != null) {
|
|
|
+ contentTypeParticle.ActualParticle.ValidateDerivationByRestriction (
|
|
|
+ baseType.ContentTypeParticle.ActualParticle, h, schema);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+#region Read
|
|
|
//<complexType
|
|
|
// abstract = boolean : false
|
|
|
// block = (#all | List of (extension | restriction))
|
|
|
@@ -400,13 +886,15 @@ namespace System.Xml.Schema
|
|
|
}
|
|
|
else if(reader.Name == "block")
|
|
|
{
|
|
|
- ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block");
|
|
|
+ ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
|
|
|
+ XmlSchemaUtil.ComplexTypeBlockAllowed);
|
|
|
if(innerex != null)
|
|
|
warn(h,"some invalid values for block attribute were found",innerex);
|
|
|
}
|
|
|
else if(reader.Name == "final")
|
|
|
{
|
|
|
- ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block");
|
|
|
+ ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
|
|
|
+ XmlSchemaUtil.FinalAllowed);
|
|
|
if(innerex != null)
|
|
|
warn(h,"some invalid values for final attribute were found",innerex);
|
|
|
}
|
|
|
@@ -543,5 +1031,6 @@ namespace System.Xml.Schema
|
|
|
}
|
|
|
return ctype;
|
|
|
}
|
|
|
+#endregion
|
|
|
}
|
|
|
}
|