XmlSchema.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. // Author: Dwivedi, Ajay kumar
  2. // [email protected]
  3. using System;
  4. using System.Xml;
  5. using System.IO;
  6. using System.Xml.Serialization;
  7. using System.ComponentModel;
  8. namespace System.Xml.Schema
  9. {
  10. /// <summary>
  11. /// Summary description for XmlSchema.
  12. /// </summary>
  13. [XmlRoot("schema",Namespace="http://www.w3.org/2001/XMLSchema")]
  14. public class XmlSchema : XmlSchemaObject
  15. {
  16. //public constants
  17. public const string InstanceNamespace = "http://www.w3.org/2001/XMLSchema-instance";
  18. public const string Namespace = "http://www.w3.org/2001/XMLSchema";
  19. //private fields
  20. private XmlSchemaForm attributeFormDefault ;
  21. private XmlSchemaObjectTable attributeGroups ;
  22. private XmlSchemaObjectTable attributes ;
  23. private XmlSchemaDerivationMethod blockDefault ;
  24. private XmlSchemaForm elementFormDefault ;
  25. private XmlSchemaObjectTable elements ;
  26. private XmlSchemaDerivationMethod finalDefault ;
  27. private XmlSchemaObjectTable groups ;
  28. private string id ;
  29. private XmlSchemaObjectCollection includes ;
  30. private bool isCompiled ;
  31. private XmlSchemaObjectCollection items ;
  32. private XmlSchemaObjectTable notations ;
  33. private XmlSchemaObjectTable schemaTypes ;
  34. private string targetNamespace ;
  35. private XmlAttribute[] unhandledAttributes ;
  36. private string version;
  37. private string language;
  38. // Compiler specific things
  39. private XmlSchemaInfo info;
  40. public XmlSchema()
  41. {
  42. attributeFormDefault= XmlSchemaForm.None;
  43. blockDefault = XmlSchemaDerivationMethod.None;
  44. elementFormDefault = XmlSchemaForm.None;
  45. finalDefault = XmlSchemaDerivationMethod.None;
  46. includes = new XmlSchemaObjectCollection();
  47. isCompiled = false;
  48. items = new XmlSchemaObjectCollection();
  49. attributeGroups = new XmlSchemaObjectTable();
  50. attributes = new XmlSchemaObjectTable();
  51. elements = new XmlSchemaObjectTable();
  52. groups = new XmlSchemaObjectTable();
  53. notations = new XmlSchemaObjectTable();
  54. schemaTypes = new XmlSchemaObjectTable();
  55. }
  56. #region Properties
  57. [DefaultValue(XmlSchemaForm.None)]
  58. [System.Xml.Serialization.XmlAttribute("attributeFormDefault")]
  59. public XmlSchemaForm AttributeFormDefault
  60. {
  61. get{ return attributeFormDefault; }
  62. set{ this.attributeFormDefault = value;}
  63. }
  64. [XmlIgnore]
  65. public XmlSchemaObjectTable AttributeGroups
  66. {
  67. get{ return attributeGroups; }
  68. }
  69. [XmlIgnore]
  70. public XmlSchemaObjectTable Attributes
  71. {
  72. get{ return attributes;}
  73. }
  74. [DefaultValue(XmlSchemaDerivationMethod.None)]
  75. [System.Xml.Serialization.XmlAttribute("blockDefault")]
  76. public XmlSchemaDerivationMethod BlockDefault
  77. {
  78. get{ return blockDefault;}
  79. set{ blockDefault = value;}
  80. }
  81. [DefaultValue(XmlSchemaForm.None)]
  82. [System.Xml.Serialization.XmlAttribute("elementFormDefault")]
  83. public XmlSchemaForm ElementFormDefault
  84. {
  85. get{ return elementFormDefault;}
  86. set{ elementFormDefault = value;}
  87. }
  88. [XmlIgnore]
  89. public XmlSchemaObjectTable Elements
  90. {
  91. get{ return elements;}
  92. }
  93. [DefaultValue(XmlSchemaDerivationMethod.None)]
  94. [System.Xml.Serialization.XmlAttribute("finalDefault")]
  95. public XmlSchemaDerivationMethod FinalDefault
  96. {
  97. get{ return finalDefault;}
  98. set{ finalDefault = value;}
  99. }
  100. [XmlIgnore]
  101. public XmlSchemaObjectTable Groups
  102. {
  103. get{ return groups;}
  104. }
  105. [System.Xml.Serialization.XmlAttribute("id")]
  106. public string Id
  107. {
  108. get{ return id;}
  109. set{ id = value;}
  110. }
  111. [XmlElement("include",typeof(XmlSchemaInclude),Namespace="http://www.w3.org/2001/XMLSchema")]
  112. [XmlElement("import",typeof(XmlSchemaImport),Namespace="http://www.w3.org/2001/XMLSchema")]
  113. [XmlElement("redefine",typeof(XmlSchemaRedefine),Namespace="http://www.w3.org/2001/XMLSchema")]
  114. public XmlSchemaObjectCollection Includes
  115. {
  116. get{ return includes;}
  117. }
  118. [XmlIgnore]
  119. public bool IsCompiled
  120. {
  121. get{ return isCompiled;}
  122. }
  123. [XmlElement("simpleType",typeof(XmlSchemaSimpleType),Namespace="http://www.w3.org/2001/XMLSchema")]
  124. [XmlElement("complexType",typeof(XmlSchemaComplexType),Namespace="http://www.w3.org/2001/XMLSchema")]
  125. [XmlElement("group",typeof(XmlSchemaGroup),Namespace="http://www.w3.org/2001/XMLSchema")]
  126. //Only Schema's attributeGroup has type XmlSchemaAttributeGroup.
  127. //Others (complextype, restrictions etc) must have XmlSchemaAttributeGroupRef
  128. [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroup),Namespace="http://www.w3.org/2001/XMLSchema")]
  129. [XmlElement("element",typeof(XmlSchemaElement),Namespace="http://www.w3.org/2001/XMLSchema")]
  130. [XmlElement("attribute",typeof(XmlSchemaAttribute),Namespace="http://www.w3.org/2001/XMLSchema")]
  131. [XmlElement("notation",typeof(XmlSchemaNotation),Namespace="http://www.w3.org/2001/XMLSchema")]
  132. [XmlElement("annotation",typeof(XmlSchemaAnnotation),Namespace="http://www.w3.org/2001/XMLSchema")]
  133. public XmlSchemaObjectCollection Items
  134. {
  135. get{ return items;}
  136. }
  137. [XmlIgnore]
  138. public XmlSchemaObjectTable Notations
  139. {
  140. get{ return notations;}
  141. }
  142. [XmlIgnore]
  143. public XmlSchemaObjectTable SchemaTypes
  144. {
  145. get{ return schemaTypes; }
  146. }
  147. [System.Xml.Serialization.XmlAttribute("targetNamespace")]
  148. public string TargetNamespace
  149. {
  150. get{ return targetNamespace;}
  151. set{ targetNamespace = value;}
  152. }
  153. [XmlAnyAttribute]
  154. public XmlAttribute[] UnhandledAttributes
  155. {
  156. get{ return unhandledAttributes;}
  157. set{ unhandledAttributes = value;}
  158. }
  159. [System.Xml.Serialization.XmlAttribute("version")]
  160. public string Version
  161. {
  162. get{ return version;}
  163. set{ version = value;}
  164. }
  165. // New attribute defined in W3C schema element
  166. [System.Xml.Serialization.XmlAttribute("xml:lang")]
  167. public string Language
  168. {
  169. get{ return language; }
  170. set{ language = value; }
  171. }
  172. #endregion
  173. // Methods
  174. /// <summary>
  175. /// This compile method does two things:
  176. /// 1. It compiles and fills the PSVI dataset
  177. /// 2. Validates the schema by calling Validate method.
  178. /// Every XmlSchemaObject has a Compile Method which gets called.
  179. /// </summary>
  180. /// <remarks>
  181. /// 1. blockDefault must be one of #all | List of (extension | restriction | substitution)
  182. /// 2. finalDefault must be one of (#all | List of (extension | restriction))
  183. /// BUGS: MS Implementation allows union and list on finaldefault. Why?
  184. /// 3. id must be of type ID
  185. /// 4. targetNamespace should be any uri
  186. /// 5. version should be a token
  187. /// 6. xml:lang should be a language
  188. ///
  189. /// </remarks>
  190. [MonoTODO]
  191. public void Compile(ValidationEventHandler handler)
  192. {
  193. //1. Union and List are not allowed in block default
  194. if(this.blockDefault != XmlSchemaDerivationMethod.All)
  195. {
  196. if((this.blockDefault & XmlSchemaDerivationMethod.List)!=0 )
  197. error(handler, "list is not allowed in blockDefault attribute");
  198. if((this.blockDefault & XmlSchemaDerivationMethod.Union)!=0 )
  199. error(handler, "union is not allowed in blockDefault attribute");
  200. }
  201. //2. List, Union and Substitution are not allowed in finaldefault.
  202. if(this.finalDefault != XmlSchemaDerivationMethod.All)
  203. {
  204. if((this.finalDefault & XmlSchemaDerivationMethod.List)!=0 )
  205. error(handler, "list is not allowed in finalDefault attribute");
  206. if((this.finalDefault & XmlSchemaDerivationMethod.Union)!=0 )
  207. error(handler, "union is not allowed in finalDefault attribute");
  208. if((this.finalDefault & XmlSchemaDerivationMethod.Substitution)!=0 )
  209. error(handler, "substitution is not allowed in finalDefault attribute");
  210. }
  211. //3. id must be of type ID
  212. if(!XmlSchemaUtil.CheckID(this.id))
  213. error(handler, "id attribute is not a valid ID");
  214. //4. targetNamespace should be of type anyURI
  215. if(!XmlSchemaUtil.CheckAnyUri(this.targetNamespace))
  216. error(handler, "targetNamespace is not a valid URI");
  217. //5. version should be of type TOKEN
  218. if(!XmlSchemaUtil.CheckToken(this.version))
  219. error(handler, "version is not a valid token");
  220. //6. xml:lang must be a language
  221. if(!XmlSchemaUtil.CheckLanguage(this.language))
  222. error(handler, "xml:lang is not a valid language");
  223. // Create the xmlschemainfo object which we use to pass variables like targetnamespace;
  224. info = new XmlSchemaInfo();
  225. if(this.targetNamespace != null && XmlSchemaUtil.CheckAnyUri(this.targetNamespace))
  226. info.targetNS = this.TargetNamespace;
  227. info.finalDefault = (FinalDefault & XmlSchemaDerivationMethod.Extension & XmlSchemaDerivationMethod.Restriction);
  228. info.blockDefault = (blockDefault & XmlSchemaDerivationMethod.Extension &
  229. XmlSchemaDerivationMethod.Restriction & XmlSchemaDerivationMethod.Substitution);
  230. // Compile the content of this schema
  231. foreach(XmlSchemaObject obj in Includes)
  232. {
  233. if(obj is XmlSchemaExternal)
  234. {
  235. //FIXME: Kuch to karo! (Do Something ;)
  236. }
  237. else
  238. {
  239. error(handler,"Object of Type "+obj.GetType().Name+" is not valid in Includes Property of Schema");
  240. }
  241. }
  242. foreach(XmlSchemaObject obj in Items)
  243. {
  244. if(obj is XmlSchemaAnnotation)
  245. {
  246. if(((XmlSchemaAnnotation)obj).Compile(handler,info))
  247. {
  248. //FIXME: What PSVI set do we add this to?
  249. }
  250. }
  251. else if(obj is XmlSchemaAttribute)
  252. {
  253. XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
  254. if(attr.Compile(handler,info))
  255. {
  256. attr.parentIsSchema = true;
  257. Attributes.Add(attr.QualifiedName, attr);
  258. }
  259. }
  260. else if(obj is XmlSchemaAttributeGroup)
  261. {
  262. XmlSchemaAttributeGroup attrgrp = (XmlSchemaAttributeGroup) obj;
  263. if(attrgrp.Compile(handler,info))
  264. {
  265. AttributeGroups.Add(attrgrp.QualifiedName, attrgrp);
  266. }
  267. }
  268. else if(obj is XmlSchemaComplexType)
  269. {
  270. XmlSchemaComplexType ctype = (XmlSchemaComplexType) obj;
  271. if(ctype.Compile(handler,info))
  272. {
  273. schemaTypes.Add(ctype.QualifiedName, ctype);
  274. }
  275. }
  276. else if(obj is XmlSchemaSimpleType)
  277. {
  278. XmlSchemaSimpleType stype = (XmlSchemaSimpleType) obj;
  279. if(stype.Compile(handler,info))
  280. {
  281. SchemaTypes.Add(stype.QualifiedName, stype);
  282. }
  283. }
  284. else if(obj is XmlSchemaElement)
  285. {
  286. XmlSchemaElement elem = (XmlSchemaElement) obj;
  287. if(elem.Compile(handler,info))
  288. {
  289. Elements.Add(elem.QualifiedName,elem);
  290. }
  291. }
  292. else if(obj is XmlSchemaGroup)
  293. {
  294. XmlSchemaGroup grp = (XmlSchemaGroup) obj;
  295. if(grp.Compile(handler,info))
  296. {
  297. Groups.Add(grp.QualifiedName,grp);
  298. }
  299. }
  300. else if(obj is XmlSchemaNotation)
  301. {
  302. XmlSchemaNotation ntn = (XmlSchemaNotation) obj;
  303. if(ntn.Compile(handler,info))
  304. {
  305. Notations.Add(ntn.QualifiedName, ntn);
  306. }
  307. }
  308. else
  309. {
  310. ValidationHandler.RaiseValidationError(handler,this,
  311. "Object of Type "+obj.GetType().Name+" is not valid in Item Property of Schema");
  312. }
  313. }
  314. Validate(handler);
  315. }
  316. [MonoTODO]
  317. protected void Validate(ValidationEventHandler handler)
  318. {
  319. foreach(XmlSchemaObject obj in Includes)
  320. {
  321. }
  322. // foreach(XmlSchemaAnnotation ann in ??????)
  323. // {
  324. // ann.Validate(handler);
  325. // }
  326. foreach(XmlSchemaAttribute attr in Attributes.Values)
  327. {
  328. attr.Validate(handler);
  329. }
  330. foreach(XmlSchemaAttributeGroup attrgrp in AttributeGroups.Values)
  331. {
  332. attrgrp.Validate(handler);
  333. }
  334. foreach(XmlSchemaType type in SchemaTypes.Values)
  335. {
  336. if(type is XmlSchemaComplexType)
  337. {
  338. ((XmlSchemaComplexType)type).Validate(handler);
  339. }
  340. else
  341. ((XmlSchemaSimpleType)type).Validate(handler);
  342. }
  343. foreach(XmlSchemaElement elem in Elements.Values)
  344. {
  345. elem.Validate(handler);
  346. }
  347. foreach(XmlSchemaGroup grp in Groups.Values)
  348. {
  349. grp.Validate(handler);
  350. }
  351. foreach(XmlSchemaNotation ntn in Notations.Values)
  352. {
  353. ntn.Validate(handler);
  354. }
  355. }
  356. public static XmlSchema Read(TextReader reader, ValidationEventHandler validationEventHandler)
  357. {
  358. return Read(new XmlTextReader(reader),validationEventHandler);
  359. }
  360. public static XmlSchema Read(Stream stream, ValidationEventHandler validationEventHandler)
  361. {
  362. return Read(new XmlTextReader(stream),validationEventHandler);
  363. }
  364. [MonoTODO]
  365. //FIXME: Use the validationeventhandler. Probably needs the parser
  366. public static XmlSchema Read(XmlReader reader, ValidationEventHandler validationEventHandler)
  367. {
  368. XmlSerializer xser = new XmlSerializer(typeof(XmlSchema));
  369. return (XmlSchema) xser.Deserialize(reader);
  370. }
  371. public void Write(System.IO.Stream stream)
  372. {
  373. Write(stream,null);
  374. }
  375. public void Write(System.IO.TextWriter writer)
  376. {
  377. Write(writer,null);
  378. }
  379. public void Write(System.Xml.XmlWriter writer)
  380. {
  381. Write(writer,null);
  382. }
  383. public void Write(System.IO.Stream stream, System.Xml.XmlNamespaceManager namespaceManager)
  384. {
  385. Write(new XmlTextWriter(stream,null),namespaceManager);
  386. }
  387. public void Write(System.IO.TextWriter writer, System.Xml.XmlNamespaceManager namespaceManager)
  388. {
  389. XmlTextWriter xwriter = new XmlTextWriter(writer);
  390. xwriter.Formatting = Formatting.Indented;
  391. Write(xwriter,namespaceManager);
  392. }
  393. [MonoTODO]
  394. public void Write(System.Xml.XmlWriter writer, System.Xml.XmlNamespaceManager namespaceManager)
  395. {
  396. XmlSerializerNamespaces xns;
  397. if(Namespaces != null)
  398. {
  399. xns = new XmlSerializerNamespaces(this.Namespaces);
  400. }
  401. else
  402. {
  403. xns = new XmlSerializerNamespaces();
  404. }
  405. if(namespaceManager != null)
  406. {
  407. foreach(string name in namespaceManager)
  408. {
  409. //xml and xmlns namespaced are added by default in namespaceManager.
  410. //So we should ignore them
  411. if(name!="xml" && name != "xmlns")
  412. xns.Add(name,namespaceManager.LookupNamespace(name));
  413. }
  414. }
  415. this.Namespaces = xns;
  416. XmlSerializer xser = new XmlSerializer(typeof(XmlSchema));
  417. xser.Serialize(writer,this,xns);
  418. writer.Flush();
  419. }
  420. internal void error(ValidationEventHandler handle,string message)
  421. {
  422. ValidationHandler.RaiseValidationError(handle,this,message);
  423. }
  424. }
  425. }