XmlSchemaElement.cs 35 KB

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