XmlSchemaElement.cs 35 KB

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