XmlSchemaElement.cs 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  1. //
  2. // System.Xml.Schema.XmlSchemaElement.cs
  3. //
  4. // Authors:
  5. // Dwivedi, Ajay kumar [email protected]
  6. // Enomoto, Atsushi [email protected]
  7. //
  8. using System;
  9. using System.Collections;
  10. using System.Xml;
  11. using System.Xml.Serialization;
  12. using System.ComponentModel;
  13. namespace System.Xml.Schema
  14. {
  15. /// <summary>
  16. /// Summary description for XmlSchemaElement.
  17. /// </summary>
  18. public class XmlSchemaElement : XmlSchemaParticle
  19. {
  20. private XmlSchemaDerivationMethod block;
  21. private XmlSchemaDerivationMethod blockResolved;
  22. private XmlSchemaObjectCollection constraints;
  23. private string defaultValue;
  24. private object elementType;
  25. private XmlSchemaDerivationMethod final;
  26. private XmlSchemaDerivationMethod finalResolved;
  27. private string fixedValue;
  28. private XmlSchemaForm form;
  29. private bool isAbstract;
  30. private bool isNillable;
  31. private string name;
  32. private XmlQualifiedName qName;
  33. private XmlQualifiedName refName;
  34. private XmlSchemaType schemaType;
  35. private XmlQualifiedName schemaTypeName;
  36. private XmlQualifiedName substitutionGroup;
  37. internal bool parentIsSchema = false;
  38. private string validatedDefaultValue;
  39. private string validatedFixedValue;
  40. private bool actualIsAbstract;
  41. private bool actualIsNillable;
  42. private XmlSchemaElement substitutionGroupElement;
  43. private ArrayList substitutingElements = new ArrayList ();
  44. private XmlSchemaElement referencedElement;
  45. // Post compilation items. It should be added on all schema components.
  46. XmlSchema schema;
  47. private static string xmlname = "element";
  48. public XmlSchemaElement()
  49. {
  50. block = XmlSchemaDerivationMethod.None;
  51. final = XmlSchemaDerivationMethod.None;
  52. constraints = new XmlSchemaObjectCollection();
  53. qName = XmlQualifiedName.Empty;
  54. refName = XmlQualifiedName.Empty;
  55. schemaTypeName = XmlQualifiedName.Empty;
  56. substitutionGroup = XmlQualifiedName.Empty;
  57. substitutionGroup = XmlQualifiedName.Empty;
  58. }
  59. #region Attributes
  60. [DefaultValue(false)]
  61. [System.Xml.Serialization.XmlAttribute("abstract")]
  62. public bool IsAbstract
  63. {
  64. get{ return isAbstract; }
  65. set{ isAbstract = value; }
  66. }
  67. [DefaultValue(XmlSchemaDerivationMethod.None)]
  68. [System.Xml.Serialization.XmlAttribute("block")]
  69. public XmlSchemaDerivationMethod Block
  70. {
  71. get{ return block; }
  72. set{ block = value; }
  73. }
  74. [DefaultValue(null)]
  75. [System.Xml.Serialization.XmlAttribute("default")]
  76. public string DefaultValue
  77. {
  78. get{ return defaultValue; }
  79. set{ defaultValue = value; }
  80. }
  81. [DefaultValue(XmlSchemaDerivationMethod.None)]
  82. [System.Xml.Serialization.XmlAttribute("final")]
  83. public XmlSchemaDerivationMethod Final
  84. {
  85. get{ return final; }
  86. set{ final = value; }
  87. }
  88. [DefaultValue(null)]
  89. [System.Xml.Serialization.XmlAttribute("fixed")]
  90. public string FixedValue
  91. {
  92. get{ return fixedValue; }
  93. set{ fixedValue = value; }
  94. }
  95. [DefaultValue(XmlSchemaForm.None)]
  96. [System.Xml.Serialization.XmlAttribute("form")]
  97. public XmlSchemaForm Form
  98. {
  99. get{ return form; }
  100. set{ form = value; }
  101. }
  102. [DefaultValue(null)]
  103. [System.Xml.Serialization.XmlAttribute("name")]
  104. public string Name
  105. {
  106. get{ return name; }
  107. set{ name = value; }
  108. }
  109. [DefaultValue(false)]
  110. [System.Xml.Serialization.XmlAttribute("nillable")]
  111. public bool IsNillable
  112. {
  113. get{ return isNillable; }
  114. set{ isNillable = value; }
  115. }
  116. [System.Xml.Serialization.XmlAttribute("ref")]
  117. public XmlQualifiedName RefName
  118. {
  119. get{ return refName; }
  120. set{ refName = value;}
  121. }
  122. [System.Xml.Serialization.XmlAttribute("substitutionGroup")]
  123. public XmlQualifiedName SubstitutionGroup
  124. {
  125. get{ return substitutionGroup; }
  126. set{ substitutionGroup = value; }
  127. }
  128. [System.Xml.Serialization.XmlAttribute("type")]
  129. public XmlQualifiedName SchemaTypeName
  130. {
  131. get{ return schemaTypeName; }
  132. set{ schemaTypeName = value; }
  133. }
  134. #endregion
  135. #region Elements
  136. [XmlElement("simpleType",typeof(XmlSchemaSimpleType),Namespace="http://www.w3.org/2001/XMLSchema")]
  137. [XmlElement("complexType",typeof(XmlSchemaComplexType),Namespace="http://www.w3.org/2001/XMLSchema")]
  138. public XmlSchemaType SchemaType
  139. {
  140. get{ return schemaType; }
  141. set{ schemaType = value; }
  142. }
  143. [XmlElement("unique",typeof(XmlSchemaUnique),Namespace="http://www.w3.org/2001/XMLSchema")]
  144. [XmlElement("key",typeof(XmlSchemaKey),Namespace="http://www.w3.org/2001/XMLSchema")]
  145. [XmlElement("keyref",typeof(XmlSchemaKeyref),Namespace="http://www.w3.org/2001/XMLSchema")]
  146. public XmlSchemaObjectCollection Constraints
  147. {
  148. get{ return constraints; }
  149. }
  150. #endregion
  151. #region Post Compilation Schema Info
  152. [XmlIgnore]
  153. public XmlQualifiedName QualifiedName
  154. {
  155. get{ return qName; }
  156. }
  157. [XmlIgnore]
  158. public object ElementType
  159. {
  160. get {
  161. if (referencedElement != null)
  162. return referencedElement.ElementType;
  163. else
  164. return elementType;
  165. }
  166. }
  167. [XmlIgnore]
  168. public XmlSchemaDerivationMethod BlockResolved
  169. {
  170. get{
  171. if (referencedElement != null)
  172. return referencedElement.BlockResolved;
  173. else
  174. return blockResolved;
  175. }
  176. }
  177. [XmlIgnore]
  178. public XmlSchemaDerivationMethod FinalResolved
  179. {
  180. get{
  181. if (referencedElement != null)
  182. return referencedElement.FinalResolved;
  183. else
  184. return finalResolved;
  185. }
  186. }
  187. internal bool ActualIsNillable {
  188. get {
  189. if (referencedElement != null)
  190. return referencedElement.ActualIsNillable;
  191. else
  192. return actualIsNillable;
  193. }
  194. }
  195. internal bool ActualIsAbstract {
  196. get {
  197. if (referencedElement != null)
  198. return referencedElement.ActualIsAbstract;
  199. else
  200. return actualIsAbstract;
  201. }
  202. }
  203. // Post compilation default value (normalized)
  204. internal string ValidatedDefaultValue {
  205. get{
  206. if (referencedElement != null)
  207. return referencedElement.ValidatedDefaultValue;
  208. else
  209. return validatedDefaultValue;
  210. }
  211. }
  212. // Post compilation fixed value (normalized)
  213. internal string ValidatedFixedValue {
  214. get{
  215. if (referencedElement != null)
  216. return referencedElement.ValidatedFixedValue;
  217. else
  218. return validatedFixedValue;
  219. }
  220. }
  221. internal ArrayList SubstitutingElements {
  222. get {
  223. if (referencedElement != null)
  224. return referencedElement.SubstitutingElements;
  225. else
  226. return this.substitutingElements;
  227. }
  228. }
  229. internal XmlSchemaElement SubstitutionGroupElement {
  230. get {
  231. if (referencedElement != null)
  232. return referencedElement.SubstitutionGroupElement;
  233. else
  234. return substitutionGroupElement;
  235. }
  236. }
  237. #endregion
  238. private XmlSchemaParticle substChoice;
  239. /// <remarks>
  240. /// a) If Element has parent as schema:
  241. /// 1. name must be present and of type NCName.
  242. /// 2. ref must be absent
  243. /// 3. form must be absent
  244. /// 4. minOccurs must be absent
  245. /// 5. maxOccurs must be absent
  246. /// b) If Element has parent is not schema and ref is absent
  247. /// 1. name must be present and of type NCName.
  248. /// 2. if form equals qualified or form is absent and schema's formdefault is qualifed,
  249. /// targetNamespace is schema's targetnamespace else empty.
  250. /// 3. type and either <simpleType> or <complexType> are mutually exclusive
  251. /// 4. default and fixed must not both be present.
  252. /// 5. substitutiongroup must be absent
  253. /// 6. final must be absent
  254. /// 7. abstract must be absent
  255. /// c) if the parent is not schema and ref is set
  256. /// 1. name must not be present
  257. /// 2. all of <simpleType>,<complexType>, <key>, <keyref>, <unique>, nillable,
  258. /// default, fixed, form, block and type, must be absent.
  259. /// 3. substitutiongroup is prohibited
  260. /// 4. final is prohibited
  261. /// 5. abstract is prohibited
  262. /// 6. default and fixed must not both be present.(Actually both are absent)
  263. /// </remarks>
  264. internal override int Compile(ValidationEventHandler h, XmlSchema schema)
  265. {
  266. // If this is already compiled this time, simply skip.
  267. if (this.IsComplied (schema.CompilationId))
  268. return 0;
  269. this.schema = schema;
  270. if(this.defaultValue != null && this.fixedValue != null)
  271. error(h,"both default and fixed can't be present");
  272. if(parentIsSchema || isRedefineChild)
  273. {
  274. if(this.refName != null && !RefName.IsEmpty)
  275. error(h,"ref must be absent");
  276. if(this.name == null) //b1
  277. error(h,"Required attribute name must be present");
  278. else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
  279. error(h,"attribute name must be NCName");
  280. else
  281. this.qName = new XmlQualifiedName (this.name, schema.TargetNamespace);
  282. if(form != XmlSchemaForm.None)
  283. error(h,"form must be absent");
  284. if(MinOccursString != null)
  285. error(h,"minOccurs must be absent");
  286. if(MaxOccursString != null)
  287. error(h,"maxOccurs must be absent");
  288. XmlSchemaDerivationMethod allfinal = (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
  289. if(final == XmlSchemaDerivationMethod.All)
  290. finalResolved = allfinal;
  291. else if(final == XmlSchemaDerivationMethod.None)
  292. finalResolved = XmlSchemaDerivationMethod.Empty;
  293. else
  294. {
  295. // if((final & ~allfinal) != 0)
  296. if ((final | XmlSchemaUtil.FinalAllowed) != XmlSchemaUtil.FinalAllowed)
  297. error (h,"some values for final are invalid in this context");
  298. finalResolved = final & allfinal;
  299. }
  300. if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
  301. {
  302. error(h,"both schemaType and content can't be present");
  303. }
  304. //Even if both are present, read both of them.
  305. if(schemaType != null)
  306. {
  307. if(schemaType is XmlSchemaSimpleType)
  308. {
  309. errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);
  310. }
  311. else if(schemaType is XmlSchemaComplexType)
  312. {
  313. errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);
  314. }
  315. else
  316. error(h,"only simpletype or complextype is allowed");
  317. }
  318. if(schemaTypeName != null && !schemaTypeName.IsEmpty)
  319. {
  320. if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
  321. error(h,"SchemaTypeName must be an XmlQualifiedName");
  322. }
  323. if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
  324. {
  325. if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
  326. error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
  327. }
  328. foreach(XmlSchemaObject obj in constraints)
  329. {
  330. if(obj is XmlSchemaUnique)
  331. errorCount += ((XmlSchemaUnique)obj).Compile(h,schema);
  332. else if(obj is XmlSchemaKey)
  333. errorCount += ((XmlSchemaKey)obj).Compile(h,schema);
  334. else if(obj is XmlSchemaKeyref)
  335. errorCount += ((XmlSchemaKeyref)obj).Compile(h,schema);
  336. }
  337. }
  338. else
  339. {
  340. if(substitutionGroup != null && !substitutionGroup.IsEmpty)
  341. error(h,"substitutionGroup must be absent");
  342. if(final != XmlSchemaDerivationMethod.None)
  343. error(h,"final must be absent");
  344. CompileOccurence (h, schema);
  345. if(refName == null || RefName.IsEmpty)
  346. {
  347. string targetNamespace = String.Empty;
  348. if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && schema.ElementFormDefault == XmlSchemaForm.Qualified))
  349. targetNamespace = schema.TargetNamespace;
  350. if(this.name == null) //b1
  351. error(h,"Required attribute name must be present");
  352. else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
  353. error(h,"attribute name must be NCName");
  354. else
  355. this.qName = new XmlQualifiedName(this.name, targetNamespace);
  356. if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
  357. {
  358. error(h,"both schemaType and content can't be present");
  359. }
  360. //Even if both are present, read both of them.
  361. if(schemaType != null)
  362. {
  363. if(schemaType is XmlSchemaSimpleType)
  364. {
  365. errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);
  366. }
  367. else if(schemaType is XmlSchemaComplexType)
  368. {
  369. errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);
  370. }
  371. else
  372. error(h,"only simpletype or complextype is allowed");
  373. }
  374. if(schemaTypeName != null && !schemaTypeName.IsEmpty)
  375. {
  376. if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
  377. error(h,"SchemaTypeName must be an XmlQualifiedName");
  378. }
  379. if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
  380. {
  381. if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
  382. error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
  383. }
  384. foreach(XmlSchemaObject obj in constraints)
  385. {
  386. if(obj is XmlSchemaUnique)
  387. errorCount += ((XmlSchemaUnique)obj).Compile(h,schema);
  388. else if(obj is XmlSchemaKey)
  389. errorCount += ((XmlSchemaKey)obj).Compile(h,schema);
  390. else if(obj is XmlSchemaKeyref)
  391. errorCount += ((XmlSchemaKeyref)obj).Compile(h,schema);
  392. }
  393. }
  394. else
  395. {
  396. if(!XmlSchemaUtil.CheckQName(RefName))
  397. error(h,"RefName must be a XmlQualifiedName");
  398. if(name != null)
  399. error(h,"name must not be present when ref is present");
  400. if(Constraints.Count != 0)
  401. error(h,"key, keyref and unique must be absent");
  402. if(isNillable)
  403. error(h,"nillable must be absent");
  404. if(defaultValue != null)
  405. error(h,"default must be absent");
  406. if(fixedValue != null)
  407. error(h,"fixed must be null");
  408. if(form != XmlSchemaForm.None)
  409. error(h,"form must be absent");
  410. if(block != XmlSchemaDerivationMethod.None)
  411. error(h,"block must be absent");
  412. if(schemaTypeName != null && !schemaTypeName.IsEmpty)
  413. error(h,"type must be absent");
  414. if(SchemaType != null)
  415. error(h,"simpleType or complexType must be absent");
  416. qName = RefName;
  417. }
  418. }
  419. switch (block) {
  420. case XmlSchemaDerivationMethod.All:
  421. blockResolved = XmlSchemaDerivationMethod.All;
  422. break;
  423. case XmlSchemaDerivationMethod.None:
  424. blockResolved = XmlSchemaDerivationMethod.Empty;
  425. break;
  426. default:
  427. if ((block | XmlSchemaUtil.ElementBlockAllowed) != XmlSchemaUtil.ElementBlockAllowed)
  428. error (h,"Some of the values for block are invalid in this context");
  429. blockResolved = block;
  430. break;
  431. }
  432. if (Constraints != null) {
  433. XmlSchemaObjectTable table = new XmlSchemaObjectTable ();
  434. foreach (XmlSchemaIdentityConstraint c in Constraints) {
  435. XmlSchemaUtil.AddToTable (table, c, c.QualifiedName, h);
  436. }
  437. }
  438. XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);
  439. this.CompilationId = schema.CompilationId;
  440. return errorCount;
  441. }
  442. [MonoTODO ("Return clone in case when it returns itself")]
  443. internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)
  444. {
  445. if (OptimizedParticle != null)
  446. return OptimizedParticle;
  447. if (RefName != null && RefName != XmlQualifiedName.Empty) {
  448. referencedElement = schema.Elements [RefName] as XmlSchemaElement;
  449. }
  450. // if (this.referencedElement != null)
  451. // OptimizedParticle = referencedElement.GetOptimizedParticle (isTop);
  452. // else
  453. if (ValidatedMaxOccurs == 0)
  454. OptimizedParticle = XmlSchemaParticle.Empty;
  455. // Substitution Group
  456. else if (SubstitutingElements != null && SubstitutingElements.Count > 0) {
  457. XmlSchemaChoice choice = new XmlSchemaChoice ();
  458. choice.MinOccurs = MinOccurs;
  459. choice.MaxOccurs = MaxOccurs;
  460. substChoice = choice;
  461. choice.Compile (null, schema); // compute Validated Min/Max Occurs.
  462. XmlSchemaElement item = this.MemberwiseClone () as XmlSchemaElement;
  463. item.MinOccurs = 1;
  464. item.MaxOccurs = 1;
  465. item.substitutionGroupElement = null;
  466. item.substitutingElements = null;
  467. for (int i = 0; i < SubstitutingElements.Count; i++) {
  468. XmlSchemaElement se = SubstitutingElements [i] as XmlSchemaElement;
  469. // choice.Items.Add (se);
  470. // choice.CompiledItems.Add (se);
  471. this.AddSubstElementRecursively (choice.Items, se);
  472. this.AddSubstElementRecursively (choice.CompiledItems, se);
  473. }
  474. if (!choice.Items.Contains (item)) {
  475. choice.Items.Add (item);
  476. choice.CompiledItems.Add (item);
  477. }
  478. OptimizedParticle = choice;
  479. }
  480. else
  481. OptimizedParticle = this;//.MemberwiseClone () as XmlSchemaElement;
  482. return OptimizedParticle;
  483. }
  484. private void AddSubstElementRecursively (XmlSchemaObjectCollection col, XmlSchemaElement el)
  485. {
  486. if (el.SubstitutingElements != null)
  487. for (int i = 0; i < el.SubstitutingElements.Count; i++)
  488. this.AddSubstElementRecursively (col, el.SubstitutingElements [i] as XmlSchemaElement);
  489. if (!col.Contains (el))
  490. col.Add (el);
  491. }
  492. internal void FillSubstitutionElementInfo ()
  493. {
  494. if (this.substitutionGroupElement != null)
  495. return;
  496. if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
  497. XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;
  498. this.substitutionGroupElement = substElem;
  499. if (substElem != null)
  500. substElem.substitutingElements.Add (this);
  501. }
  502. }
  503. internal override int Validate(ValidationEventHandler h, XmlSchema schema)
  504. {
  505. if (IsValidated (schema.CompilationId))
  506. return errorCount;
  507. // See XML Schema Structures 3.6 for the complete description.
  508. // Element Declaration Properties Correct
  509. // 1. = 3.3.1 (modulo 5.3)
  510. // 3.3.1:
  511. // {annotation} is as is.
  512. // {name}, {target namespace}, {scope}, {disallowed substitution},
  513. // {substitution group exclusions} (handled the same as 'disallowed substitution')
  514. // and {identity-constraint-definitions} are Compile()d.
  515. // {value constraint} is going to be filled in step 2.
  516. // actual {nillable}, {abstract}
  517. this.actualIsNillable = IsNillable;
  518. this.actualIsAbstract = IsAbstract;
  519. // Before determining element type, we need to validate substituting element
  520. if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
  521. XmlSchemaElement substElem = substitutionGroupElement;
  522. if (substElem != null)
  523. substElem.Validate (h, schema);
  524. }
  525. // {type} from here
  526. XmlSchemaDatatype datatype = null;
  527. if (schemaType != null)
  528. elementType = schemaType;
  529. else if (SchemaTypeName != XmlQualifiedName.Empty) {
  530. XmlSchemaType type = schema.SchemaTypes [SchemaTypeName] as XmlSchemaType;
  531. // If el is null, then it is missing sub components .
  532. if (type != null) {
  533. type.Validate (h, schema);
  534. elementType = type;
  535. }
  536. else if (SchemaTypeName == XmlSchemaComplexType.AnyTypeName)
  537. elementType = XmlSchemaComplexType.AnyType;
  538. else if (SchemaTypeName.Namespace == XmlSchema.Namespace) {
  539. datatype = XmlSchemaDatatype.FromName (SchemaTypeName);
  540. if (datatype == null)
  541. error (h, "Invalid schema datatype was specified.");
  542. else
  543. elementType = datatype;
  544. }
  545. // otherwise, it might be missing sub components.
  546. else if (!schema.IsNamespaceAbsent (SchemaTypeName.Namespace))
  547. error (h, "Referenced element schema type " + SchemaTypeName + " was not found in the corresponding schema.");
  548. }
  549. else if (RefName != XmlQualifiedName.Empty)
  550. {
  551. XmlSchemaElement refElem = schema.Elements [RefName] as XmlSchemaElement;
  552. // If el is null, then it is missing sub components .
  553. if (refElem != null) {
  554. this.referencedElement = refElem;
  555. errorCount += refElem.Validate (h, schema);
  556. }
  557. // otherwise, it might be missing sub components.
  558. else if (!schema.IsNamespaceAbsent (RefName.Namespace))
  559. error (h, "Referenced element " + RefName + " was not found in the corresponding schema.");
  560. }
  561. // Otherwise if there are substitution group, then the type of the substitution group element.
  562. if (referencedElement == null) {
  563. if (elementType == null && this.substitutionGroupElement != null)
  564. elementType = substitutionGroupElement.ElementType;
  565. // Otherwise, the -ur type- definition.
  566. if (elementType == null)
  567. elementType = XmlSchemaComplexType.AnyType;
  568. }
  569. XmlSchemaType xsType = elementType as XmlSchemaType;
  570. if (xsType != null) {
  571. errorCount += xsType.Validate (h, schema);
  572. datatype = xsType.Datatype;
  573. }
  574. // basic {type} is now filled, except for derivation by {substitution group}.
  575. // {substitution group affiliation}
  576. // 3. subsitution group's type derivation check.
  577. if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
  578. XmlSchemaElement substElem = substitutionGroupElement;
  579. // If el is null, then it is missing sub components .
  580. if (substElem != null) {
  581. XmlSchemaType substSchemaType = substElem.ElementType as XmlSchemaType;
  582. if (substSchemaType != null) {
  583. // 3.3.6 Properties Correct 3.
  584. if ((substElem.FinalResolved & XmlSchemaDerivationMethod.Substitution) != 0)
  585. error (h, "Substituted element blocks substitution.");
  586. if (xsType != null && (substElem.FinalResolved & xsType.DerivedBy) != 0)
  587. error (h, "Invalid derivation was found. Substituted element prohibits this derivation method: " + xsType.DerivedBy + ".");
  588. }
  589. XmlSchemaComplexType xsComplexType = xsType as XmlSchemaComplexType;
  590. if (xsComplexType != null)
  591. xsComplexType.ValidateTypeDerivationOK (substElem.ElementType, h, schema);
  592. else {
  593. XmlSchemaSimpleType xsSimpleType = xsType as XmlSchemaSimpleType;
  594. if (xsSimpleType != null)
  595. xsSimpleType.ValidateTypeDerivationOK (substElem.ElementType, h, schema, true);
  596. }
  597. }
  598. // otherwise, it might be missing sub components.
  599. else if (!schema.IsNamespaceAbsent (SubstitutionGroup.Namespace))
  600. error (h, "Referenced element type " + SubstitutionGroup + " was not found in the corresponding schema.");
  601. }
  602. // 2. ElementDefaultValid
  603. // 4. ID with {value constraint} is prohibited.
  604. if (defaultValue != null || fixedValue != null) {
  605. ValidateElementDefaultValidImmediate (h, schema);
  606. if (datatype != null && // Such situation is basically an error. For ValidationEventHandler.
  607. datatype.TokenizedType == XmlTokenizedType.ID)
  608. error (h, "Element type is ID, which does not allows default or fixed values.");
  609. }
  610. // Identity constraints (3.11.3 / 3.11.6)
  611. foreach (XmlSchemaIdentityConstraint ident in Constraints)
  612. ident.Validate (h, schema);
  613. ValidationId = schema.ValidationId;
  614. return errorCount;
  615. }
  616. internal override bool ParticleEquals (XmlSchemaParticle other)
  617. {
  618. XmlSchemaElement element = other as XmlSchemaElement;
  619. if (element == null)
  620. return false;
  621. if (this.ValidatedMaxOccurs != element.ValidatedMaxOccurs ||
  622. this.ValidatedMinOccurs != element.ValidatedMinOccurs)
  623. return false;
  624. if (this.QualifiedName != element.QualifiedName ||
  625. this.ElementType != element.ElementType ||
  626. this.Constraints.Count != element.Constraints.Count)
  627. return false;
  628. for (int i = 0; i < this.Constraints.Count; i++) {
  629. XmlSchemaIdentityConstraint c1 = Constraints [i] as XmlSchemaIdentityConstraint;
  630. XmlSchemaIdentityConstraint c2 = element.Constraints [i] as XmlSchemaIdentityConstraint;
  631. if (c1.QualifiedName != c2.QualifiedName ||
  632. c1.Selector.XPath != c2.Selector.XPath ||
  633. c1.Fields.Count != c2.Fields.Count)
  634. return false;
  635. for (int f = 0; f < c1.Fields.Count; f++) {
  636. XmlSchemaXPath f1 = c1.Fields [f] as XmlSchemaXPath;
  637. XmlSchemaXPath f2 = c2.Fields [f] as XmlSchemaXPath;
  638. if (f1.XPath != f2.XPath)
  639. return false;
  640. }
  641. }
  642. if (this.BlockResolved != element.BlockResolved ||
  643. this.FinalResolved != element.FinalResolved ||
  644. this.ValidatedDefaultValue != element.ValidatedDefaultValue ||
  645. this.ValidatedFixedValue != element.ValidatedFixedValue)
  646. return false;
  647. return true;
  648. }
  649. internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
  650. ValidationEventHandler h, XmlSchema schema, bool raiseError)
  651. {
  652. // element - NameAndTypeOK
  653. XmlSchemaElement baseElement = baseParticle as XmlSchemaElement;
  654. if (baseElement != null) {
  655. return ValidateDerivationByRestrictionNameAndTypeOK (baseElement, h, schema, raiseError);
  656. }
  657. // any - NSCompat
  658. XmlSchemaAny baseAny = baseParticle as XmlSchemaAny;
  659. if (baseAny != null) {
  660. // NSCompat
  661. if (!baseAny.ValidateWildcardAllowsNamespaceName (this.QualifiedName.Namespace, h, schema, raiseError))
  662. return false;
  663. return ValidateOccurenceRangeOK (baseAny, h, schema, raiseError);
  664. }
  665. //*
  666. // choice - RecurseAsIfGroup
  667. XmlSchemaGroupBase gb = null;
  668. if (baseParticle is XmlSchemaSequence)
  669. gb = new XmlSchemaSequence ();
  670. else if (baseParticle is XmlSchemaChoice)
  671. gb = new XmlSchemaChoice ();
  672. else if (baseParticle is XmlSchemaAll)
  673. gb = new XmlSchemaAll ();
  674. if (gb != null) {
  675. gb.Items.Add (this);
  676. gb.Compile (h, schema);
  677. gb.Validate (h, schema);
  678. // It looks weird, but here we never think about
  679. // _pointlessness_ of this groupbase particle.
  680. return gb.ValidateDerivationByRestriction (baseParticle, h, schema, raiseError);
  681. }
  682. //*/
  683. return true;
  684. }
  685. private bool ValidateDerivationByRestrictionNameAndTypeOK (XmlSchemaElement baseElement,
  686. ValidationEventHandler h, XmlSchema schema, bool raiseError)
  687. {
  688. // 1.
  689. if (this.QualifiedName != baseElement.QualifiedName) {
  690. if (raiseError)
  691. error (h, "Invalid derivation by restriction of particle was found. Both elements must have the same name.");
  692. return false;
  693. }
  694. // 2.
  695. if (this.isNillable && !baseElement.isNillable) {
  696. if (raiseError)
  697. error (h, "Invalid element derivation by restriction of particle was found. Base element is not nillable and derived type is nillable.");
  698. return false;
  699. }
  700. // 3.
  701. if (!ValidateOccurenceRangeOK (baseElement, h, schema, raiseError))
  702. return false;
  703. // 4.
  704. if (baseElement.ValidatedFixedValue != null &&
  705. baseElement.ValidatedFixedValue != this.ValidatedFixedValue) {
  706. if (raiseError)
  707. error (h, "Invalid element derivation by restriction of particle was found. Both fixed value must be the same.");
  708. return false;
  709. }
  710. // 5. TODO: What is "identity constraints subset" ???
  711. // 6.
  712. if ((baseElement.BlockResolved | this.BlockResolved) != this.BlockResolved) {
  713. if (raiseError)
  714. error (h, "Invalid derivation by restriction of particle was found. Derived element must contain all of the base element's block value.");
  715. return false;
  716. }
  717. // 7.
  718. if (baseElement.ElementType != null) {
  719. XmlSchemaComplexType derivedCType = this.ElementType as XmlSchemaComplexType;
  720. if (derivedCType != null) {
  721. // FIXME: W3C REC says that it is Type Derivation OK to be check, but
  722. // in fact it should be DerivationValid (Restriction, Complex).
  723. derivedCType.ValidateDerivationValidRestriction (
  724. baseElement.ElementType as XmlSchemaComplexType, h, schema);
  725. derivedCType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema);
  726. } else {
  727. XmlSchemaSimpleType derivedSType = this.ElementType as XmlSchemaSimpleType;
  728. if (derivedSType != null)
  729. derivedSType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema, true);
  730. else if (baseElement.ElementType != XmlSchemaComplexType.AnyType && baseElement.ElementType != this.ElementType) {
  731. if (raiseError)
  732. error (h, "Invalid element derivation by restriction of particle was found. Both primitive types differ.");
  733. return false;
  734. }
  735. }
  736. }
  737. return true;
  738. }
  739. internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
  740. {
  741. XmlSchemaComplexType ct = this.ElementType as XmlSchemaComplexType;
  742. if (ct == null || ct.Particle == null)
  743. return;
  744. ct.Particle.CheckRecursion (depth + 1, h, schema);
  745. }
  746. internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
  747. ValidationEventHandler h, XmlSchema schema)
  748. {
  749. if (qnames.Contains (this.QualifiedName))// && !this.ParticleEquals ((XmlSchemaParticle) qnames [this.QualifiedName]))
  750. error (h, "Ambiguous element label was detected: " + this.QualifiedName);
  751. else {
  752. foreach (XmlSchemaAny any in nsNames) {
  753. if (any.ValidatedMaxOccurs == 0)
  754. continue;
  755. if (any.HasValueAny ||
  756. any.HasValueLocal && this.QualifiedName.Namespace == "" ||
  757. any.HasValueOther && this.QualifiedName.Namespace != this.QualifiedName.Namespace ||
  758. any.HasValueTargetNamespace && this.QualifiedName.Namespace == this.QualifiedName.Namespace) {
  759. error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
  760. break;
  761. } else if (!any.HasValueOther) {
  762. bool bad = false;
  763. foreach (string ns in any.ResolvedNamespaces) {
  764. if (ns == this.QualifiedName.Namespace) {
  765. bad = true;
  766. break;
  767. }
  768. }
  769. if (bad) {
  770. error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
  771. break;
  772. }
  773. } else {
  774. if (any.TargetNamespace.Length == 0 ||
  775. any.TargetNamespace != this.QualifiedName.Namespace)
  776. error (h, "Ambiguous element label which is contained by -any- particle with ##other value was detected: " + this.QualifiedName);
  777. }
  778. }
  779. qnames.Add (this.QualifiedName, this);
  780. }
  781. }
  782. internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
  783. ValidationEventHandler h, XmlSchema schema)
  784. {
  785. XmlSchemaElement labeled = labels [this.QualifiedName] as XmlSchemaElement;
  786. if (labeled == null)
  787. labels.Add (this.QualifiedName, this);
  788. else if (labeled.ElementType != this.ElementType)
  789. error (h, "Different types are specified on the same named elements in the same sequence. Element name is " + QualifiedName);
  790. }
  791. // 3.3.6 Element Default Valid (Immediate)
  792. private void ValidateElementDefaultValidImmediate (ValidationEventHandler h, XmlSchema schema)
  793. {
  794. // This presumes that ElementType is already filled.
  795. XmlSchemaDatatype datatype = elementType as XmlSchemaDatatype;
  796. XmlSchemaSimpleType simpleType = elementType as XmlSchemaSimpleType;
  797. if (simpleType != null)
  798. datatype = simpleType.Datatype;
  799. if (datatype == null) {
  800. XmlSchemaComplexType complexType = elementType as XmlSchemaComplexType;
  801. switch (complexType.ContentType) {
  802. case XmlSchemaContentType.Empty:
  803. case XmlSchemaContentType.ElementOnly:
  804. error (h, "Element content type must be simple type or mixed.");
  805. break;
  806. }
  807. datatype = XmlSchemaSimpleType.AnySimpleType;
  808. }
  809. XmlNamespaceManager nsmgr = null;
  810. if (datatype.TokenizedType == XmlTokenizedType.QName) {
  811. if (this.Namespaces != null)
  812. foreach (XmlQualifiedName qname in Namespaces.ToArray ())
  813. nsmgr.AddNamespace (qname.Name, qname.Namespace);
  814. }
  815. try {
  816. if (defaultValue != null) {
  817. validatedDefaultValue = datatype.Normalize (defaultValue);
  818. datatype.ParseValue (validatedDefaultValue, null, nsmgr);
  819. }
  820. } catch (Exception ex) {
  821. // FIXME: This is not a good way to handle exception, but
  822. // I think there is no remedy for such Framework specification.
  823. error (h, "The Element's default value is invalid with respect to its type definition.", ex);
  824. }
  825. try {
  826. if (fixedValue != null) {
  827. validatedFixedValue = datatype.Normalize (fixedValue);
  828. datatype.ParseValue (validatedFixedValue, null, nsmgr);
  829. }
  830. } catch (Exception ex) {
  831. // FIXME: This is not a good way to handle exception.
  832. error (h, "The Element's fixed value is invalid with its type definition.", ex);
  833. }
  834. }
  835. //<element
  836. // abstract = boolean : false
  837. // block = (#all | List of (extension | restriction | substitution))
  838. // default = string
  839. // final = (#all | List of (extension | restriction))
  840. // fixed = string
  841. // form = (qualified | unqualified)
  842. // id = ID
  843. // maxOccurs = (nonNegativeInteger | unbounded) : 1
  844. // minOccurs = nonNegativeInteger : 1
  845. // name = NCName
  846. // nillable = boolean : false
  847. // ref = QName
  848. // substitutionGroup = QName
  849. // type = QName
  850. // {any attributes with non-schema namespace . . .}>
  851. // Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
  852. //</element>
  853. internal static XmlSchemaElement Read(XmlSchemaReader reader, ValidationEventHandler h)
  854. {
  855. XmlSchemaElement element = new XmlSchemaElement();
  856. Exception innerex;
  857. reader.MoveToElement();
  858. if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
  859. {
  860. error(h,"Should not happen :1: XmlSchemaElement.Read, name="+reader.Name,null);
  861. reader.Skip();
  862. return null;
  863. }
  864. element.LineNumber = reader.LineNumber;
  865. element.LinePosition = reader.LinePosition;
  866. element.SourceUri = reader.BaseURI;
  867. while(reader.MoveToNextAttribute())
  868. {
  869. if(reader.Name == "abstract")
  870. {
  871. element.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
  872. if(innerex != null)
  873. error(h,reader.Value + " is invalid value for abstract",innerex);
  874. }
  875. else if(reader.Name == "block")
  876. {
  877. element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
  878. XmlSchemaUtil.ElementBlockAllowed);
  879. if(innerex != null)
  880. error (h,"some invalid values for block attribute were found",innerex);
  881. }
  882. else if(reader.Name == "default")
  883. {
  884. element.defaultValue = reader.Value;
  885. }
  886. else if(reader.Name == "final")
  887. {
  888. element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
  889. XmlSchemaUtil.FinalAllowed);
  890. if(innerex != null)
  891. error (h,"some invalid values for final attribute were found",innerex);
  892. }
  893. else if(reader.Name == "fixed")
  894. {
  895. element.fixedValue = reader.Value;
  896. }
  897. else if(reader.Name == "form")
  898. {
  899. element.form = XmlSchemaUtil.ReadFormAttribute(reader,out innerex);
  900. if(innerex != null)
  901. error(h,reader.Value + " is an invalid value for form attribute",innerex);
  902. }
  903. else if(reader.Name == "id")
  904. {
  905. element.Id = reader.Value;
  906. }
  907. else if(reader.Name == "maxOccurs")
  908. {
  909. try
  910. {
  911. element.MaxOccursString = reader.Value;
  912. }
  913. catch(Exception e)
  914. {
  915. error(h,reader.Value + " is an invalid value for maxOccurs",e);
  916. }
  917. }
  918. else if(reader.Name == "minOccurs")
  919. {
  920. try
  921. {
  922. element.MinOccursString = reader.Value;
  923. }
  924. catch(Exception e)
  925. {
  926. error(h,reader.Value + " is an invalid value for minOccurs",e);
  927. }
  928. }
  929. else if(reader.Name == "name")
  930. {
  931. element.Name = reader.Value;
  932. }
  933. else if(reader.Name == "nillable")
  934. {
  935. element.IsNillable = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
  936. if(innerex != null)
  937. error(h,reader.Value + "is not a valid value for nillable",innerex);
  938. }
  939. else if(reader.Name == "ref")
  940. {
  941. element.refName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
  942. if(innerex != null)
  943. error(h, reader.Value + " is not a valid value for ref attribute",innerex);
  944. }
  945. else if(reader.Name == "substitutionGroup")
  946. {
  947. element.substitutionGroup = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
  948. if(innerex != null)
  949. error(h, reader.Value + " is not a valid value for substitutionGroup attribute",innerex);
  950. }
  951. else if(reader.Name == "type")
  952. {
  953. element.SchemaTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
  954. if(innerex != null)
  955. error(h, reader.Value + " is not a valid value for type attribute",innerex);
  956. }
  957. else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
  958. {
  959. error(h,reader.Name + " is not a valid attribute for element",null);
  960. }
  961. else
  962. {
  963. XmlSchemaUtil.ReadUnhandledAttribute(reader,element);
  964. }
  965. }
  966. reader.MoveToElement();
  967. if(reader.IsEmptyElement)
  968. return element;
  969. // Content: annotation?,
  970. // (simpleType | complexType)?,
  971. // (unique | key | keyref)*
  972. int level = 1;
  973. while(reader.ReadNextElement())
  974. {
  975. if(reader.NodeType == XmlNodeType.EndElement)
  976. {
  977. if(reader.LocalName != xmlname)
  978. error(h,"Should not happen :2: XmlSchemaElement.Read, name="+reader.Name,null);
  979. break;
  980. }
  981. if(level <= 1 && reader.LocalName == "annotation")
  982. {
  983. level = 2; //Only one annotation
  984. XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
  985. if(annotation != null)
  986. element.Annotation = annotation;
  987. continue;
  988. }
  989. if(level <= 2)
  990. {
  991. if(reader.LocalName == "simpleType")
  992. {
  993. level = 3;
  994. XmlSchemaSimpleType simple = XmlSchemaSimpleType.Read(reader,h);
  995. if(simple != null)
  996. element.SchemaType = simple;
  997. continue;
  998. }
  999. if(reader.LocalName == "complexType")
  1000. {
  1001. level = 3;
  1002. XmlSchemaComplexType complex = XmlSchemaComplexType.Read(reader,h);
  1003. if(complex != null)
  1004. {
  1005. element.SchemaType = complex;
  1006. }
  1007. continue;
  1008. }
  1009. }
  1010. if(level <= 3)
  1011. {
  1012. if(reader.LocalName == "unique")
  1013. {
  1014. level = 3;
  1015. XmlSchemaUnique unique = XmlSchemaUnique.Read(reader,h);
  1016. if(unique != null)
  1017. element.constraints.Add(unique);
  1018. continue;
  1019. }
  1020. else if(reader.LocalName == "key")
  1021. {
  1022. level = 3;
  1023. XmlSchemaKey key = XmlSchemaKey.Read(reader,h);
  1024. if(key != null)
  1025. element.constraints.Add(key);
  1026. continue;
  1027. }
  1028. else if(reader.LocalName == "keyref")
  1029. {
  1030. level = 3;
  1031. XmlSchemaKeyref keyref = XmlSchemaKeyref.Read(reader,h);
  1032. if(keyref != null)
  1033. element.constraints.Add(keyref);
  1034. continue;
  1035. }
  1036. }
  1037. reader.RaiseInvalidElementError();
  1038. }
  1039. return element;
  1040. }
  1041. }
  1042. }