// Author: Dwivedi, Ajay kumar // Adwiv@Yahoo.com using System; using System.Xml; using System.ComponentModel; using System.Xml.Serialization; namespace System.Xml.Schema { /// /// Summary description for XmlSchemaAttribute. /// public class XmlSchemaAttribute : XmlSchemaAnnotated { private object attributeType; private string defaultValue; private string fixedValue; private XmlSchemaForm form; private string name; private XmlQualifiedName qualifiedName; private XmlQualifiedName refName; private XmlSchemaSimpleType schemaType; private XmlQualifiedName schemaTypeName; private XmlSchemaUse use; //Compilation fields internal bool parentIsSchema = false; internal XmlSchema schema = null; internal bool errorOccured = false; public XmlSchemaAttribute() { //FIXME: Docs says the default is optional. //Whereas the MS implementation has default None. form = XmlSchemaForm.None; use = XmlSchemaUse.None; schemaTypeName = XmlQualifiedName.Empty; qualifiedName = XmlQualifiedName.Empty; refName = XmlQualifiedName.Empty; } // Properties [XmlIgnore] public object AttributeType { //FIXME: This is not correct. Is it? get{ return attributeType; } } [DefaultValue(null)] [System.Xml.Serialization.XmlAttribute("default")] public string DefaultValue { get{ return defaultValue;} set { // Default Value and fixed Value are mutually exclusive fixedValue = null; defaultValue = value; } } [DefaultValue(null)] [System.Xml.Serialization.XmlAttribute("fixed")] public string FixedValue { get{ return fixedValue;} set { // Default Value and fixed Value are mutually exclusive defaultValue = null; fixedValue = value; } } [DefaultValue(XmlSchemaForm.None)] [System.Xml.Serialization.XmlAttribute("form")] public XmlSchemaForm Form { get{ return form;} set{ form = value;} } [System.Xml.Serialization.XmlAttribute("name")] public string Name { get{ return name;} set { name = value; } } [XmlIgnore] public XmlQualifiedName QualifiedName { get{ return qualifiedName;} } [System.Xml.Serialization.XmlAttribute("ref")] public XmlQualifiedName RefName { get{ return refName;} set { refName = value; } } [XmlElement("simpleType",Namespace="http://www.w3.org/2001/XMLSchema")] public XmlSchemaSimpleType SchemaType { get{ return schemaType;} set{ schemaType = value;} } [System.Xml.Serialization.XmlAttribute("type")] public XmlQualifiedName SchemaTypeName { get{ return schemaTypeName;} set{ schemaTypeName = value;} } [DefaultValue(XmlSchemaUse.None)] [System.Xml.Serialization.XmlAttribute("use")] public XmlSchemaUse Use { get{ return use;} set{ use = value;} } /// /// For an attribute: /// a) If the parent is schema /// 1-5 are from in the Schema for Schema /// 6-8 are from "Constraints on XML Representations of Attribute Declarations" /// 9-10 are from "Attribute Declaration Schema Component" /// 11-16 are from "Constraints on Attribute Declaration Schema Components" /// 1. ref must be absent /// 2. form must be absent /// 3. use must be absent /// 4. name must be present and of type NCName /// 5. *NO CHECK REQUIRED* Only simple types and annotation are allowed as content /// 6. default and fixed must not both be present. /// 7. *NO CHECK REQUIRED* If default and use are both present... (Not possible since use is absent) /// 8. type and must not both be present. /// 9. Target Namespace should be schema's targetnamespace or absent /// 10. Type Definiton coressponds to element, or type value, or absent /// 11. *TO UNDERSTAND* Missing Sub-components /// 12. value constraint must be of the same datatype as of type /// 13. if the type definition is ID then there should be no value constraint. /// 14. name must not be xmlns /// 15. Targetnamespace must not be xsi. This implies the target namespace of schema can't be xsi if toplevel attributes are used. /// 16. *Exception to rule 15* inbuilt attributes: xsi:nil, xsi:type, xsi:schemaLocation, xsi: noNamespaceSchemaLocation /// b) *TODO*: If the parent is complextype and ref is not set /// c) *TODO*: if the parent is not schema and ref is set /// [MonoTODO] //FIXME: Should we set a property to null if an error occurs? Or should we stop the validation? internal bool Compile(ValidationEventHandler h, XmlSchemaInfo info) { if(parentIsSchema)//a { if(this.refName!= null && !this.refName.IsEmpty) // a.1 error(h,"ref must be absent in the top level "); if(this.form != XmlSchemaForm.None) // a.2 error(h,"form must be absent in the top level "); if(this.use != XmlSchemaUse.None) // a.3 error(h,"use must be absent in the top level "); if(this.name == null) //a.4 error(h,"name must be present if attribute has schema as its parent"); else if(!XmlSchemaUtil.CheckNCName(this.name)) // a.4.2 error(h,"attribute name must be NCName"); else if(this.name == "xmlns") // a.14 error(h,"attribute name can't be xmlns"); else this.qualifiedName = new XmlQualifiedName(this.name, info.targetNS); // TODO: a.10, a.11, a.12, a.13 if(this.defaultValue != null && this.fixedValue != null) // a.6 error(h,"default and fixed must not both be present in an Attribute"); if(this.schemaType != null) { if(this.schemaTypeName != null && !this.SchemaTypeName.IsEmpty) // a.8 error(h,"attribute can't have both a type and content"); else { this.SchemaType.islocal = true; this.schemaType.Compile(h,info); } } if(info.targetNS == XmlSchema.InstanceNamespace && this.name != "nil" && this.name != "type" && this.name != "schemaLocation" && this.name != "noNamespaceSchemaLocation") // a.15, a.16 error(h,"targetNamespace can't be " + XmlSchema.InstanceNamespace); } // TODO: // else // { // } if(!XmlSchemaUtil.CheckID(this.Id)) error(h,"id must be a valid ID"); return !errorOccured; } [MonoTODO] internal bool Validate(ValidationEventHandler h) { return false; } internal void error(ValidationEventHandler handle,string message) { this.errorOccured = true; ValidationHandler.RaiseValidationError(handle,this,message); } } }