// Author: Dwivedi, Ajay kumar
// Adwiv@Yahoo.com
using System;
using System.Xml;
using System.IO;
using System.Xml.Serialization;
using System.ComponentModel;
namespace System.Xml.Schema
{
///
/// Summary description for XmlSchema.
///
[XmlRoot("schema",Namespace="http://www.w3.org/2001/XMLSchema")]
public class XmlSchema : XmlSchemaObject
{
//public constants
public const string InstanceNamespace = "http://www.w3.org/2001/XMLSchema-instance";
public const string Namespace = "http://www.w3.org/2001/XMLSchema";
//private fields
private XmlSchemaForm attributeFormDefault ;
private XmlSchemaObjectTable attributeGroups ;
private XmlSchemaObjectTable attributes ;
private XmlSchemaDerivationMethod blockDefault ;
private XmlSchemaForm elementFormDefault ;
private XmlSchemaObjectTable elements ;
private XmlSchemaDerivationMethod finalDefault ;
private XmlSchemaObjectTable groups ;
private string id ;
private XmlSchemaObjectCollection includes ;
private bool isCompiled ;
private XmlSchemaObjectCollection items ;
private XmlSchemaObjectTable notations ;
private XmlSchemaObjectTable schemaTypes ;
private string targetNamespace ;
private XmlAttribute[] unhandledAttributes ;
private string version;
private string language;
// Compiler specific things
private XmlSchemaInfo info;
public XmlSchema()
{
attributeFormDefault= XmlSchemaForm.None;
blockDefault = XmlSchemaDerivationMethod.None;
elementFormDefault = XmlSchemaForm.None;
finalDefault = XmlSchemaDerivationMethod.None;
includes = new XmlSchemaObjectCollection();
isCompiled = false;
items = new XmlSchemaObjectCollection();
attributeGroups = new XmlSchemaObjectTable();
attributes = new XmlSchemaObjectTable();
elements = new XmlSchemaObjectTable();
groups = new XmlSchemaObjectTable();
notations = new XmlSchemaObjectTable();
schemaTypes = new XmlSchemaObjectTable();
}
#region Properties
[DefaultValue(XmlSchemaForm.None)]
[System.Xml.Serialization.XmlAttribute("attributeFormDefault")]
public XmlSchemaForm AttributeFormDefault
{
get{ return attributeFormDefault; }
set{ this.attributeFormDefault = value;}
}
[XmlIgnore]
public XmlSchemaObjectTable AttributeGroups
{
get{ return attributeGroups; }
}
[XmlIgnore]
public XmlSchemaObjectTable Attributes
{
get{ return attributes;}
}
[DefaultValue(XmlSchemaDerivationMethod.None)]
[System.Xml.Serialization.XmlAttribute("blockDefault")]
public XmlSchemaDerivationMethod BlockDefault
{
get{ return blockDefault;}
set{ blockDefault = value;}
}
[DefaultValue(XmlSchemaForm.None)]
[System.Xml.Serialization.XmlAttribute("elementFormDefault")]
public XmlSchemaForm ElementFormDefault
{
get{ return elementFormDefault;}
set{ elementFormDefault = value;}
}
[XmlIgnore]
public XmlSchemaObjectTable Elements
{
get{ return elements;}
}
[DefaultValue(XmlSchemaDerivationMethod.None)]
[System.Xml.Serialization.XmlAttribute("finalDefault")]
public XmlSchemaDerivationMethod FinalDefault
{
get{ return finalDefault;}
set{ finalDefault = value;}
}
[XmlIgnore]
public XmlSchemaObjectTable Groups
{
get{ return groups;}
}
[System.Xml.Serialization.XmlAttribute("id")]
public string Id
{
get{ return id;}
set{ id = value;}
}
[XmlElement("include",typeof(XmlSchemaInclude),Namespace="http://www.w3.org/2001/XMLSchema")]
[XmlElement("import",typeof(XmlSchemaImport),Namespace="http://www.w3.org/2001/XMLSchema")]
[XmlElement("redefine",typeof(XmlSchemaRedefine),Namespace="http://www.w3.org/2001/XMLSchema")]
public XmlSchemaObjectCollection Includes
{
get{ return includes;}
}
[XmlIgnore]
public bool IsCompiled
{
get{ return isCompiled;}
}
[XmlElement("simpleType",typeof(XmlSchemaSimpleType),Namespace="http://www.w3.org/2001/XMLSchema")]
[XmlElement("complexType",typeof(XmlSchemaComplexType),Namespace="http://www.w3.org/2001/XMLSchema")]
[XmlElement("group",typeof(XmlSchemaGroup),Namespace="http://www.w3.org/2001/XMLSchema")]
//Only Schema's attributeGroup has type XmlSchemaAttributeGroup.
//Others (complextype, restrictions etc) must have XmlSchemaAttributeGroupRef
[XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroup),Namespace="http://www.w3.org/2001/XMLSchema")]
[XmlElement("element",typeof(XmlSchemaElement),Namespace="http://www.w3.org/2001/XMLSchema")]
[XmlElement("attribute",typeof(XmlSchemaAttribute),Namespace="http://www.w3.org/2001/XMLSchema")]
[XmlElement("notation",typeof(XmlSchemaNotation),Namespace="http://www.w3.org/2001/XMLSchema")]
[XmlElement("annotation",typeof(XmlSchemaAnnotation),Namespace="http://www.w3.org/2001/XMLSchema")]
public XmlSchemaObjectCollection Items
{
get{ return items;}
}
[XmlIgnore]
public XmlSchemaObjectTable Notations
{
get{ return notations;}
}
[XmlIgnore]
public XmlSchemaObjectTable SchemaTypes
{
get{ return schemaTypes;}
}
[System.Xml.Serialization.XmlAttribute("targetNamespace")]
public string TargetNamespace
{
get{ return targetNamespace;}
set{ targetNamespace = value;}
}
[XmlAnyAttribute]
public XmlAttribute[] UnhandledAttributes
{
get{ return unhandledAttributes;}
set{ unhandledAttributes = value;}
}
[System.Xml.Serialization.XmlAttribute("version")]
public string Version
{
get{ return version;}
set{ version = value;}
}
// New attribute defined in W3C schema element
[System.Xml.Serialization.XmlAttribute("xml:lang")]
public string Language
{
get{ return language; }
set{ language = value; }
}
#endregion
// Methods
///
/// This compile method does two things:
/// 1. It compiles and fills the PSVI dataset
/// 2. Validates the schema by calling Validate method.
/// Every XmlSchemaObject has a Compile Method which gets called.
///
[MonoTODO]
public void Compile(ValidationEventHandler handler)
{
// Create the xmlschemainfo object which we use to pass variables like targetnamespace;
info = new XmlSchemaInfo();
info.targetNS = this.TargetNamespace;
info.finalDefault = this.FinalDefault;
foreach(XmlSchemaObject obj in Includes)
{
if(obj is XmlSchemaExternal)
{
//FIXME: Kuch to karo (Do Something ;)
}
else
{
ValidationHandler.RaiseValidationError(handler,this,
"Object of Type "+obj.GetType().Name+" is not valid in Includes Property of Schema");
}
}
foreach(XmlSchemaObject obj in Items)
{
if(obj is XmlSchemaAnnotation)
{
if(((XmlSchemaAnnotation)obj).Compile(handler,info))
{
//FIXME: What PSVI set do we add this to?
}
}
else if(obj is XmlSchemaAttribute)
{
XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
if(attr.Compile(handler,info))
{
Attributes.Add(attr.QualifiedName, attr);
}
}
else if(obj is XmlSchemaAttributeGroup)
{
XmlSchemaAttributeGroup attrgrp = (XmlSchemaAttributeGroup) obj;
if(attrgrp.Compile(handler,info))
{
AttributeGroups.Add(XmlQualifiedName.Empty, attrgrp);
}
}
else if(obj is XmlSchemaComplexType)
{
XmlSchemaComplexType ctype = (XmlSchemaComplexType) obj;
if(ctype.Compile(handler,info))
{
schemaTypes.Add(ctype.QualifiedName, ctype);
}
}
else if(obj is XmlSchemaSimpleType)
{
XmlSchemaSimpleType stype = (XmlSchemaSimpleType) obj;
if(stype.Compile(handler,info))
{
SchemaTypes.Add(stype.QualifiedName, stype);
}
}
else if(obj is XmlSchemaElement)
{
XmlSchemaElement elem = (XmlSchemaElement) obj;
if(elem.Compile(handler,info))
{
Elements.Add(elem.QualifiedName,elem);
}
}
else if(obj is XmlSchemaGroup)
{
XmlSchemaGroup grp = (XmlSchemaGroup) obj;
if(grp.Compile(handler,info))
{
Groups.Add(XmlQualifiedName.Empty,grp);
}
}
else if(obj is XmlSchemaNotation)
{
XmlSchemaNotation ntn = (XmlSchemaNotation) obj;
if(ntn.Compile(handler,info))
{
Notations.Add(XmlQualifiedName.Empty, ntn);
}
}
else
{
ValidationHandler.RaiseValidationError(handler,this,
"Object of Type "+obj.GetType().Name+" is not valid in Item Property of Schema");
}
}
Validate(handler);
}
[MonoTODO]
protected void Validate(ValidationEventHandler handler)
{
foreach(XmlSchemaObject obj in Includes)
{
}
foreach(XmlSchemaObject obj in Items)
{
// foreach(XmlSchemaAnnotation ann in ??????)
// {
// ann.Validate(handler);
// }
foreach(XmlSchemaAttribute attr in Attributes)
{
attr.parentIsSchema = true;
attr.Validate(handler);
}
foreach(XmlSchemaAttributeGroup attrgrp in AttributeGroups)
{
attrgrp.Validate(handler);
}
foreach(XmlSchemaType type in SchemaTypes)
{
if(type is XmlSchemaComplexType)
{
((XmlSchemaComplexType)type).Validate(handler);
}
else
((XmlSchemaSimpleType)type).Validate(handler);
}
foreach(XmlSchemaElement elem in Elements)
{
elem.Validate(handler);
}
foreach(XmlSchemaGroup grp in Groups)
{
grp.Validate(handler);
}
foreach(XmlSchemaNotation ntn in Notations)
{
ntn.Validate(handler);
}
}
}
public static XmlSchema Read(TextReader reader, ValidationEventHandler validationEventHandler)
{
return Read(new XmlTextReader(reader),validationEventHandler);
}
public static XmlSchema Read(Stream stream, ValidationEventHandler validationEventHandler)
{
return Read(new XmlTextReader(stream),validationEventHandler);
}
[MonoTODO]
//FIXME: Use the validationeventhandler. Probably needs the parser
public static XmlSchema Read(XmlReader reader, ValidationEventHandler validationEventHandler)
{
XmlSerializer xser = new XmlSerializer(typeof(XmlSchema));
return (XmlSchema) xser.Deserialize(reader);
}
public void Write(System.IO.Stream stream)
{
Write(stream,null);
}
public void Write(System.IO.TextWriter writer)
{
Write(writer,null);
}
public void Write(System.Xml.XmlWriter writer)
{
Write(writer,null);
}
public void Write(System.IO.Stream stream, System.Xml.XmlNamespaceManager namespaceManager)
{
Write(new XmlTextWriter(stream,null),namespaceManager);
}
public void Write(System.IO.TextWriter writer, System.Xml.XmlNamespaceManager namespaceManager)
{
XmlTextWriter xwriter = new XmlTextWriter(writer);
xwriter.Formatting = Formatting.Indented;
Write(xwriter,namespaceManager);
}
[MonoTODO]
public void Write(System.Xml.XmlWriter writer, System.Xml.XmlNamespaceManager namespaceManager)
{
XmlSerializerNamespaces xns;
if(Namespaces != null)
{
xns = new XmlSerializerNamespaces(this.Namespaces);
}
else
{
xns = new XmlSerializerNamespaces();
}
if(namespaceManager != null)
{
foreach(string name in namespaceManager)
{
//xml and xmlns namespaced are added by default in namespaceManager.
//So we should ignore them
if(name!="xml" && name != "xmlns")
xns.Add(name,namespaceManager.LookupNamespace(name));
}
}
this.Namespaces = xns;
XmlSerializer xser = new XmlSerializer(typeof(XmlSchema));
xser.Serialize(writer,this,xns);
writer.Flush();
}
}
}