XmlSchemaElement.cs 39 KB

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