XmlSchemaElement.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. // Author: Dwivedi, Ajay kumar
  2. // [email protected]
  3. using System;
  4. using System.Xml;
  5. using System.Xml.Serialization;
  6. using System.ComponentModel;
  7. namespace System.Xml.Schema
  8. {
  9. /// <summary>
  10. /// Summary description for XmlSchemaElement.
  11. /// </summary>
  12. public class XmlSchemaElement : XmlSchemaParticle
  13. {
  14. private XmlSchemaDerivationMethod block;
  15. private XmlSchemaDerivationMethod blockResolved;
  16. private XmlSchemaObjectCollection constraints;
  17. private string defaultValue;
  18. private object elementType;
  19. private XmlSchemaDerivationMethod final;
  20. private XmlSchemaDerivationMethod finalResolved;
  21. private string fixedValue;
  22. private XmlSchemaForm form;
  23. private bool isAbstract;
  24. private bool isNillable;
  25. private string name;
  26. private XmlQualifiedName qName;
  27. private XmlQualifiedName refName;
  28. private XmlSchemaType schemaType;
  29. private XmlQualifiedName schemaTypeName;
  30. private XmlQualifiedName substitutionGroup;
  31. internal bool parentIsSchema = false;
  32. private string targetNamespace;
  33. private string hash;
  34. private static string xmlname = "element";
  35. public XmlSchemaElement()
  36. {
  37. block = XmlSchemaDerivationMethod.None;
  38. final = XmlSchemaDerivationMethod.None;
  39. constraints = new XmlSchemaObjectCollection();
  40. qName = XmlQualifiedName.Empty;
  41. refName = XmlQualifiedName.Empty;
  42. schemaTypeName = XmlQualifiedName.Empty;
  43. substitutionGroup = XmlQualifiedName.Empty;
  44. substitutionGroup = XmlQualifiedName.Empty;
  45. }
  46. #region Attributes
  47. [DefaultValue(false)]
  48. [System.Xml.Serialization.XmlAttribute("abstract")]
  49. public bool IsAbstract
  50. {
  51. get{ return isAbstract; }
  52. set{ isAbstract = value; }
  53. }
  54. [DefaultValue(XmlSchemaDerivationMethod.None)]
  55. [System.Xml.Serialization.XmlAttribute("block")]
  56. public XmlSchemaDerivationMethod Block
  57. {
  58. get{ return block; }
  59. set{ block = value; }
  60. }
  61. [DefaultValue(null)]
  62. [System.Xml.Serialization.XmlAttribute("default")]
  63. public string DefaultValue
  64. {
  65. get{ return defaultValue; }
  66. set{ defaultValue = value; }
  67. }
  68. [DefaultValue(XmlSchemaDerivationMethod.None)]
  69. [System.Xml.Serialization.XmlAttribute("final")]
  70. public XmlSchemaDerivationMethod Final
  71. {
  72. get{ return final; }
  73. set{ final = value; }
  74. }
  75. [DefaultValue(null)]
  76. [System.Xml.Serialization.XmlAttribute("fixed")]
  77. public string FixedValue
  78. {
  79. get{ return fixedValue; }
  80. set{ fixedValue = value; }
  81. }
  82. [DefaultValue(XmlSchemaForm.None)]
  83. [System.Xml.Serialization.XmlAttribute("form")]
  84. public XmlSchemaForm Form
  85. {
  86. get{ return form; }
  87. set{ form = value; }
  88. }
  89. [DefaultValue(null)]
  90. [System.Xml.Serialization.XmlAttribute("name")]
  91. public string Name
  92. {
  93. get{ return name; }
  94. set{ name = value; }
  95. }
  96. [DefaultValue(false)]
  97. [System.Xml.Serialization.XmlAttribute("nillable")]
  98. public bool IsNillable
  99. {
  100. get{ return isNillable; }
  101. set{ isNillable = value; }
  102. }
  103. [System.Xml.Serialization.XmlAttribute("ref")]
  104. public XmlQualifiedName RefName
  105. {
  106. get{ return refName; }
  107. set{ refName = value;}
  108. }
  109. [System.Xml.Serialization.XmlAttribute("substitutionGroup")]
  110. public XmlQualifiedName SubstitutionGroup
  111. {
  112. get{ return substitutionGroup; }
  113. set{ substitutionGroup = value; }
  114. }
  115. [System.Xml.Serialization.XmlAttribute("type")]
  116. public XmlQualifiedName SchemaTypeName
  117. {
  118. get{ return schemaTypeName; }
  119. set{ schemaTypeName = value; }
  120. }
  121. [XmlElement("simpleType",typeof(XmlSchemaSimpleType),Namespace="http://www.w3.org/2001/XMLSchema")]
  122. [XmlElement("complexType",typeof(XmlSchemaComplexType),Namespace="http://www.w3.org/2001/XMLSchema")]
  123. public XmlSchemaType SchemaType
  124. {
  125. get{ return schemaType; }
  126. set{ schemaType = value; }
  127. }
  128. [XmlElement("unique",typeof(XmlSchemaUnique),Namespace="http://www.w3.org/2001/XMLSchema")]
  129. [XmlElement("key",typeof(XmlSchemaKey),Namespace="http://www.w3.org/2001/XMLSchema")]
  130. [XmlElement("keyref",typeof(XmlSchemaKeyref),Namespace="http://www.w3.org/2001/XMLSchema")]
  131. public XmlSchemaObjectCollection Constraints
  132. {
  133. get{ return constraints; }
  134. }
  135. [XmlIgnore]
  136. public XmlQualifiedName QualifiedName
  137. {
  138. get{ return qName; }
  139. }
  140. [XmlIgnore]
  141. public object ElementType
  142. {
  143. get{ return elementType; }
  144. }
  145. [XmlIgnore]
  146. public XmlSchemaDerivationMethod BlockResolved
  147. {
  148. get{ return blockResolved; }
  149. }
  150. [XmlIgnore]
  151. public XmlSchemaDerivationMethod FinalResolved
  152. {
  153. get{ return finalResolved; }
  154. }
  155. #endregion
  156. /// <remarks>
  157. /// a) If Element has parent as schema:
  158. /// 1. name must be present and of type NCName.
  159. /// 2. ref must be absent
  160. /// 3. form must be absent
  161. /// 4. minOccurs must be absent
  162. /// 5. maxOccurs must be absent
  163. /// b) If Element has parent is not schema and ref is absent
  164. /// 1. name must be present and of type NCName.
  165. /// 2. if form equals qualified or form is absent and schema's formdefault is qualifed,
  166. /// targetNamespace is schema's targetnamespace else empty.
  167. /// 3. type and either <simpleType> or <complexType> are mutually exclusive
  168. /// 4. default and fixed must not both be present.
  169. /// 5. substitutiongroup must be absent
  170. /// 6. final must be absent
  171. /// 7. abstract must be absent
  172. /// c) if the parent is not schema and ref is set
  173. /// 1. name must not be present
  174. /// 2. all of <simpleType>,<complexType>, <key>, <keyref>, <unique>, nillable,
  175. /// default, fixed, form, block and type, must be absent.
  176. /// 3. substitutiongroup is prohibited
  177. /// 4. final is prohibited
  178. /// 5. abstract is prohibited
  179. /// 6. default and fixed must not both be present.(Actually both are absent)
  180. /// </remarks>
  181. [MonoTODO]
  182. internal int Compile(ValidationEventHandler h, XmlSchemaInfo info)
  183. {
  184. if(this.defaultValue != null && this.fixedValue != null)
  185. error(h,"both default and fixed can't be present");
  186. if(parentIsSchema)
  187. {
  188. if(this.refName != null && !RefName.IsEmpty)
  189. error(h,"ref must be absent");
  190. if(this.name == null) //b1
  191. error(h,"Required attribute name must be present");
  192. else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
  193. error(h,"attribute name must be NCName");
  194. else
  195. this.qName = new XmlQualifiedName(this.name, info.TargetNamespace);
  196. if(form != XmlSchemaForm.None)
  197. error(h,"form must be absent");
  198. if(MinOccursString != null)
  199. error(h,"minOccurs must be absent");
  200. if(MaxOccursString != null)
  201. error(h,"maxOccurs must be absent");
  202. XmlSchemaDerivationMethod allfinal = (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
  203. if(final == XmlSchemaDerivationMethod.All)
  204. finalResolved = allfinal;
  205. else if(final == XmlSchemaDerivationMethod.None)
  206. finalResolved = info.BlockDefault & allfinal;
  207. else
  208. {
  209. if((final & ~allfinal) != 0)
  210. warn(h,"some values for final are invalid in this context");
  211. finalResolved = final & allfinal;
  212. }
  213. XmlSchemaDerivationMethod allblock = XmlSchemaDerivationMethod.Extension |
  214. XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Substitution;
  215. if(block == XmlSchemaDerivationMethod.All)
  216. blockResolved = allblock;
  217. else if(block == XmlSchemaDerivationMethod.None)
  218. blockResolved = info.BlockDefault & allblock;
  219. else
  220. {
  221. if((block & ~allblock) != 0)
  222. warn(h,"Some of the values for block are invalid in this context");
  223. blockResolved = block & allblock;
  224. }
  225. if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
  226. {
  227. error(h,"both schemaType and content can't be present");
  228. }
  229. //Even if both are present, read both of them.
  230. if(schemaType != null)
  231. {
  232. if(schemaType is XmlSchemaSimpleType)
  233. {
  234. errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,info);
  235. }
  236. else if(schemaType is XmlSchemaComplexType)
  237. {
  238. errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,info);
  239. }
  240. else
  241. error(h,"only simpletype or complextype is allowed");
  242. }
  243. if(schemaTypeName != null && !schemaTypeName.IsEmpty)
  244. {
  245. if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
  246. error(h,"SchemaTypeName must be an XmlQualifiedName");
  247. }
  248. if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
  249. {
  250. if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
  251. error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
  252. }
  253. foreach(XmlSchemaObject obj in constraints)
  254. {
  255. if(obj is XmlSchemaUnique)
  256. errorCount += ((XmlSchemaUnique)obj).Compile(h,info);
  257. else if(obj is XmlSchemaKey)
  258. errorCount += ((XmlSchemaKey)obj).Compile(h,info);
  259. else if(obj is XmlSchemaKeyref)
  260. errorCount += ((XmlSchemaKeyref)obj).Compile(h,info);
  261. }
  262. }
  263. else
  264. {
  265. if(substitutionGroup != null && !substitutionGroup.IsEmpty)
  266. error(h,"substitutionGroup must be absent");
  267. if(final != XmlSchemaDerivationMethod.None)
  268. error(h,"final must be absent");
  269. if(isAbstract)
  270. error(h,"abstract must be absent");
  271. //FIXME: Should we reset the values
  272. if(MinOccurs > MaxOccurs)
  273. error(h,"minOccurs must be less than or equal to maxOccurs");
  274. if(refName == null || RefName.IsEmpty)
  275. {
  276. if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && info.ElementFormDefault == XmlSchemaForm.Qualified))
  277. this.targetNamespace = info.TargetNamespace;
  278. else
  279. this.targetNamespace = string.Empty;
  280. if(this.name == null) //b1
  281. error(h,"Required attribute name must be present");
  282. else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
  283. error(h,"attribute name must be NCName");
  284. else
  285. this.qName = new XmlQualifiedName(this.name, this.targetNamespace);
  286. XmlSchemaDerivationMethod allblock = XmlSchemaDerivationMethod.Extension |
  287. XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Substitution;
  288. if(block == XmlSchemaDerivationMethod.All)
  289. blockResolved = allblock;
  290. else if(block == XmlSchemaDerivationMethod.None)
  291. blockResolved = info.BlockDefault & allblock;
  292. else
  293. {
  294. if((block & ~allblock) != 0)
  295. warn(h,"Some of the values for block are invalid in this context");
  296. blockResolved = block & allblock;
  297. }
  298. if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
  299. {
  300. error(h,"both schemaType and content can't be present");
  301. }
  302. //Even if both are present, read both of them.
  303. if(schemaType != null)
  304. {
  305. if(schemaType is XmlSchemaSimpleType)
  306. {
  307. errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,info);
  308. }
  309. else if(schemaType is XmlSchemaComplexType)
  310. {
  311. errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,info);
  312. }
  313. else
  314. error(h,"only simpletype or complextype is allowed");
  315. }
  316. if(schemaTypeName != null && !schemaTypeName.IsEmpty)
  317. {
  318. if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
  319. error(h,"SchemaTypeName must be an XmlQualifiedName");
  320. }
  321. if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
  322. {
  323. if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
  324. error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
  325. }
  326. foreach(XmlSchemaObject obj in constraints)
  327. {
  328. if(obj is XmlSchemaUnique)
  329. errorCount += ((XmlSchemaUnique)obj).Compile(h,info);
  330. else if(obj is XmlSchemaKey)
  331. errorCount += ((XmlSchemaKey)obj).Compile(h,info);
  332. else if(obj is XmlSchemaKeyref)
  333. errorCount += ((XmlSchemaKeyref)obj).Compile(h,info);
  334. }
  335. }
  336. else
  337. {
  338. if(!XmlSchemaUtil.CheckQName(RefName))
  339. error(h,"RefName must be a XmlQualifiedName");
  340. if(name != null)
  341. error(h,"name must not be present when ref is present");
  342. if(Constraints.Count != 0)
  343. error(h,"key, keyref and unique must be absent");
  344. if(isNillable)
  345. error(h,"nillable must be absent");
  346. if(defaultValue != null)
  347. error(h,"default must be absent");
  348. if(fixedValue != null)
  349. error(h,"fixed must be null");
  350. if(form != XmlSchemaForm.None)
  351. error(h,"form must be absent");
  352. if(block != XmlSchemaDerivationMethod.None)
  353. error(h,"block must be absent");
  354. if(schemaTypeName != null && !schemaTypeName.IsEmpty)
  355. error(h,"type must be absent");
  356. if(SchemaType != null)
  357. error(h,"simpleType or complexType must be absent");
  358. }
  359. }
  360. XmlSchemaUtil.CompileID(Id,this,info.IDCollection,h);
  361. return errorCount;
  362. }
  363. [MonoTODO]
  364. internal int Validate(ValidationEventHandler h)
  365. {
  366. return errorCount;
  367. }
  368. //<element
  369. // abstract = boolean : false
  370. // block = (#all | List of (extension | restriction | substitution))
  371. // default = string
  372. // final = (#all | List of (extension | restriction))
  373. // fixed = string
  374. // form = (qualified | unqualified)
  375. // id = ID
  376. // maxOccurs = (nonNegativeInteger | unbounded) : 1
  377. // minOccurs = nonNegativeInteger : 1
  378. // name = NCName
  379. // nillable = boolean : false
  380. // ref = QName
  381. // substitutionGroup = QName
  382. // type = QName
  383. // {any attributes with non-schema namespace . . .}>
  384. // Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
  385. //</element>
  386. internal static XmlSchemaElement Read(XmlSchemaReader reader, ValidationEventHandler h)
  387. {
  388. XmlSchemaElement element = new XmlSchemaElement();
  389. Exception innerex;
  390. reader.MoveToElement();
  391. if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
  392. {
  393. error(h,"Should not happen :1: XmlSchemaElement.Read, name="+reader.Name,null);
  394. reader.Skip();
  395. return null;
  396. }
  397. element.LineNumber = reader.LineNumber;
  398. element.LinePosition = reader.LinePosition;
  399. element.SourceUri = reader.BaseURI;
  400. while(reader.MoveToNextAttribute())
  401. {
  402. if(reader.Name == "abstract")
  403. {
  404. element.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
  405. if(innerex != null)
  406. error(h,reader.Value + " is invalid value for abstract",innerex);
  407. }
  408. else if(reader.Name == "block")
  409. {
  410. element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block");
  411. if(innerex != null)
  412. warn(h,"some invalid values for block attribute were found",innerex);
  413. }
  414. else if(reader.Name == "default")
  415. {
  416. element.defaultValue = reader.Value;
  417. }
  418. else if(reader.Name == "final")
  419. {
  420. element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block");
  421. if(innerex != null)
  422. warn(h,"some invalid values for final attribute were found",innerex);
  423. }
  424. else if(reader.Name == "fixed")
  425. {
  426. element.fixedValue = reader.Value;
  427. }
  428. else if(reader.Name == "form")
  429. {
  430. element.form = XmlSchemaUtil.ReadFormAttribute(reader,out innerex);
  431. if(innerex != null)
  432. error(h,reader.Value + " is an invalid value for form attribute",innerex);
  433. }
  434. else if(reader.Name == "id")
  435. {
  436. element.Id = reader.Value;
  437. }
  438. else if(reader.Name == "maxOccurs")
  439. {
  440. try
  441. {
  442. element.MaxOccursString = reader.Value;
  443. }
  444. catch(Exception e)
  445. {
  446. error(h,reader.Value + " is an invalid value for maxOccurs",e);
  447. }
  448. }
  449. else if(reader.Name == "minOccurs")
  450. {
  451. try
  452. {
  453. element.MinOccursString = reader.Value;
  454. }
  455. catch(Exception e)
  456. {
  457. error(h,reader.Value + " is an invalid value for minOccurs",e);
  458. }
  459. }
  460. else if(reader.Name == "name")
  461. {
  462. element.Name = reader.Value;
  463. }
  464. else if(reader.Name == "nillable")
  465. {
  466. element.IsNillable = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
  467. if(innerex != null)
  468. error(h,reader.Value + "is not a valid value for nillable",innerex);
  469. }
  470. else if(reader.Name == "ref")
  471. {
  472. element.refName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
  473. if(innerex != null)
  474. error(h, reader.Value + " is not a valid value for ref attribute",innerex);
  475. }
  476. else if(reader.Name == "substitutionGroup")
  477. {
  478. element.substitutionGroup = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
  479. if(innerex != null)
  480. error(h, reader.Value + " is not a valid value for substitutionGroup attribute",innerex);
  481. }
  482. else if(reader.Name == "type")
  483. {
  484. element.SchemaTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
  485. if(innerex != null)
  486. error(h, reader.Value + " is not a valid value for type attribute",innerex);
  487. }
  488. else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
  489. {
  490. error(h,reader.Name + " is not a valid attribute for element",null);
  491. }
  492. else
  493. {
  494. XmlSchemaUtil.ReadUnhandledAttribute(reader,element);
  495. }
  496. }
  497. reader.MoveToElement();
  498. if(reader.IsEmptyElement)
  499. return element;
  500. // Content: annotation?,
  501. // (simpleType | complexType)?,
  502. // (unique | key | keyref)*
  503. int level = 1;
  504. while(reader.ReadNextElement())
  505. {
  506. if(reader.NodeType == XmlNodeType.EndElement)
  507. {
  508. if(reader.LocalName != xmlname)
  509. error(h,"Should not happen :2: XmlSchemaElement.Read, name="+reader.Name,null);
  510. break;
  511. }
  512. if(level <= 1 && reader.LocalName == "annotation")
  513. {
  514. level = 2; //Only one annotation
  515. XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
  516. if(annotation != null)
  517. element.Annotation = annotation;
  518. continue;
  519. }
  520. if(level <= 2)
  521. {
  522. if(reader.LocalName == "simpleType")
  523. {
  524. level = 3;
  525. XmlSchemaSimpleType simple = XmlSchemaSimpleType.Read(reader,h);
  526. if(simple != null)
  527. element.SchemaType = simple;
  528. continue;
  529. }
  530. if(reader.LocalName == "complexType")
  531. {
  532. level = 3;
  533. XmlSchemaComplexType complex = XmlSchemaComplexType.Read(reader,h);
  534. if(complex != null)
  535. {
  536. element.SchemaType = complex;
  537. }
  538. continue;
  539. }
  540. }
  541. if(level <= 3)
  542. {
  543. if(reader.LocalName == "unique")
  544. {
  545. level = 3;
  546. XmlSchemaUnique unique = XmlSchemaUnique.Read(reader,h);
  547. if(unique != null)
  548. element.constraints.Add(unique);
  549. continue;
  550. }
  551. else if(reader.LocalName == "key")
  552. {
  553. level = 3;
  554. XmlSchemaKey key = XmlSchemaKey.Read(reader,h);
  555. if(key != null)
  556. element.constraints.Add(key);
  557. continue;
  558. }
  559. else if(reader.LocalName == "keyref")
  560. {
  561. level = 3;
  562. XmlSchemaKeyref keyref = XmlSchemaKeyref.Read(reader,h);
  563. if(keyref != null)
  564. element.constraints.Add(keyref);
  565. continue;
  566. }
  567. }
  568. reader.RaiseInvalidElementError();
  569. }
  570. return element;
  571. }
  572. }
  573. }