XmlSchemaElement.cs 35 KB

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