XmlSchemaElement.cs 35 KB

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