PageRenderTime 57ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/mcs/class/referencesource/System.Xml/System/Xml/Schema/Inference/Infer.cs

http://github.com/mono/mono
C# | 2509 lines | 2265 code | 100 blank | 144 comment | 756 complexity | 8717547022fa98fcaf2dfcfb99dd04a2 MD5 | raw file
Possible License(s): GPL-2.0, CC-BY-SA-3.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.1, Unlicense, Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. //------------------------------------------------------------------------------
  2. // <copyright file="Infer.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">Microsoft</owner>
  6. // <owner current="false" primary="false">Microsoft</owner>
  7. //------------------------------------------------------------------------------
  8. using System;
  9. using System.IO;
  10. using System.Xml;
  11. using System.Collections;
  12. using System.Diagnostics;
  13. using System.Globalization;
  14. using System.Security.Permissions;
  15. namespace System.Xml.Schema
  16. {
  17. /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer"]/*' />
  18. /// <summary>
  19. /// Infer class serves for infering XML Schema from given XML instance document.
  20. /// </summary>
  21. public sealed class XmlSchemaInference
  22. {
  23. internal static XmlQualifiedName ST_boolean = new XmlQualifiedName("boolean", XmlSchema.Namespace);
  24. internal static XmlQualifiedName ST_byte = new XmlQualifiedName("byte", XmlSchema.Namespace);
  25. internal static XmlQualifiedName ST_unsignedByte = new XmlQualifiedName("unsignedByte", XmlSchema.Namespace);
  26. internal static XmlQualifiedName ST_short = new XmlQualifiedName("short", XmlSchema.Namespace);
  27. internal static XmlQualifiedName ST_unsignedShort = new XmlQualifiedName("unsignedShort", XmlSchema.Namespace);
  28. internal static XmlQualifiedName ST_int = new XmlQualifiedName("int", XmlSchema.Namespace);
  29. internal static XmlQualifiedName ST_unsignedInt = new XmlQualifiedName("unsignedInt", XmlSchema.Namespace);
  30. internal static XmlQualifiedName ST_long = new XmlQualifiedName("long", XmlSchema.Namespace);
  31. internal static XmlQualifiedName ST_unsignedLong = new XmlQualifiedName("unsignedLong", XmlSchema.Namespace);
  32. internal static XmlQualifiedName ST_integer = new XmlQualifiedName("integer", XmlSchema.Namespace);
  33. internal static XmlQualifiedName ST_decimal = new XmlQualifiedName("decimal", XmlSchema.Namespace);
  34. internal static XmlQualifiedName ST_float = new XmlQualifiedName("float", XmlSchema.Namespace);
  35. internal static XmlQualifiedName ST_double = new XmlQualifiedName("double", XmlSchema.Namespace);
  36. internal static XmlQualifiedName ST_duration = new XmlQualifiedName("duration", XmlSchema.Namespace);
  37. internal static XmlQualifiedName ST_dateTime = new XmlQualifiedName("dateTime", XmlSchema.Namespace);
  38. internal static XmlQualifiedName ST_time = new XmlQualifiedName("time", XmlSchema.Namespace);
  39. internal static XmlQualifiedName ST_date = new XmlQualifiedName("date", XmlSchema.Namespace);
  40. internal static XmlQualifiedName ST_gYearMonth = new XmlQualifiedName("gYearMonth", XmlSchema.Namespace);
  41. internal static XmlQualifiedName ST_string = new XmlQualifiedName("string", XmlSchema.Namespace);
  42. internal static XmlQualifiedName ST_anySimpleType = new XmlQualifiedName("anySimpleType", XmlSchema.Namespace);
  43. internal static XmlQualifiedName[] SimpleTypes =
  44. {
  45. ST_boolean,
  46. ST_byte,
  47. ST_unsignedByte,
  48. ST_short,
  49. ST_unsignedShort,
  50. ST_int,
  51. ST_unsignedInt,
  52. ST_long,
  53. ST_unsignedLong,
  54. ST_integer,
  55. ST_decimal,
  56. ST_float,
  57. ST_double,
  58. ST_duration,
  59. ST_dateTime,
  60. ST_time,
  61. ST_date,
  62. ST_gYearMonth,
  63. ST_string
  64. };
  65. internal const short HC_ST_boolean = 0;
  66. internal const short HC_ST_byte = 1;
  67. internal const short HC_ST_unsignedByte = 2;
  68. internal const short HC_ST_short = 3;
  69. internal const short HC_ST_unsignedShort = 4;
  70. internal const short HC_ST_int = 5;
  71. internal const short HC_ST_unsignedInt = 6;
  72. internal const short HC_ST_long = 7;
  73. internal const short HC_ST_unsignedLong = 8;
  74. internal const short HC_ST_integer = 9;
  75. internal const short HC_ST_decimal = 10;
  76. internal const short HC_ST_float = 11;
  77. internal const short HC_ST_double = 12;
  78. internal const short HC_ST_duration = 13;
  79. internal const short HC_ST_dateTime = 14;
  80. internal const short HC_ST_time = 15;
  81. internal const short HC_ST_date = 16;
  82. internal const short HC_ST_gYearMonth = 17;
  83. internal const short HC_ST_string = 18;
  84. internal const short HC_ST_Count = HC_ST_string +1;
  85. internal const int TF_boolean = 1<<HC_ST_boolean;
  86. internal const int TF_byte = 1<<HC_ST_byte;
  87. internal const int TF_unsignedByte = 1<<HC_ST_unsignedByte;
  88. internal const int TF_short = 1<<HC_ST_short;
  89. internal const int TF_unsignedShort = 1<<HC_ST_unsignedShort;
  90. internal const int TF_int = 1<<HC_ST_int;
  91. internal const int TF_unsignedInt = 1<<HC_ST_unsignedInt;
  92. internal const int TF_long = 1<<HC_ST_long;
  93. internal const int TF_unsignedLong = 1<<HC_ST_unsignedLong;
  94. internal const int TF_integer = 1<<HC_ST_integer;
  95. internal const int TF_decimal = 1<<HC_ST_decimal;
  96. internal const int TF_float = 1<<HC_ST_float;
  97. internal const int TF_double = 1<<HC_ST_double;
  98. internal const int TF_duration = 1<<HC_ST_duration;
  99. internal const int TF_dateTime = 1<<HC_ST_dateTime;
  100. internal const int TF_time = 1<<HC_ST_time;
  101. internal const int TF_date = 1<<HC_ST_date;
  102. internal const int TF_gYearMonth = 1<<HC_ST_gYearMonth;
  103. internal const int TF_string = 1<<HC_ST_string;
  104. XmlSchema rootSchema = null; //(XmlSchema) xsc[TargetNamespace];
  105. private XmlSchemaSet schemaSet;
  106. private XmlReader xtr;
  107. private NameTable nametable;
  108. private string TargetNamespace;
  109. private XmlNamespaceManager NamespaceManager;
  110. //private Hashtable schemas; //contains collection of schemas before they get added to the XmlSchemaSet xsc
  111. //private bool bRefine = false; //indicates if we are going to infer or refine schema when InferSchema is called
  112. ArrayList schemaList;
  113. InferenceOption occurrence = InferenceOption.Restricted;
  114. InferenceOption typeInference = InferenceOption.Restricted;
  115. /* internal struct ReplaceList
  116. {
  117. internal XmlSchemaObjectCollection col;
  118. internal int position;
  119. internal ReplaceList(XmlSchemaObjectCollection col, int position)
  120. {
  121. this.col = col;
  122. this.position = position;
  123. }
  124. }*/
  125. /// <include file='doc\Infer.uex' path='docs/doc[@for="InferenceOption"]/*' />
  126. public enum InferenceOption
  127. {
  128. /// <include file='doc\Infer.uex' path='docs/doc[@for="InferenceOption.Restricted"]/*' />
  129. Restricted,
  130. /// <include file='doc\Infer.uex' path='docs/doc[@for="InferenceOption.Relaxed"]/*' />
  131. Relaxed
  132. };
  133. /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer.Occurrence"]/*' />
  134. public InferenceOption Occurrence
  135. {
  136. set
  137. {
  138. this.occurrence = value;
  139. }
  140. get
  141. {
  142. return this.occurrence;
  143. }
  144. }
  145. /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer.TypeInference"]/*' />
  146. public InferenceOption TypeInference
  147. {
  148. set
  149. {
  150. this.typeInference = value;
  151. }
  152. get
  153. {
  154. return this.typeInference;
  155. }
  156. }
  157. /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer.Infer"]/*' />
  158. public XmlSchemaInference()
  159. {
  160. this.nametable = new NameTable();
  161. this.NamespaceManager = new XmlNamespaceManager(nametable);
  162. this.NamespaceManager.AddNamespace("xs", XmlSchema.Namespace);
  163. this.schemaList = new ArrayList();
  164. }
  165. /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer.InferSchema"]/*' />
  166. public XmlSchemaSet InferSchema(XmlReader instanceDocument)
  167. {
  168. return InferSchema1(instanceDocument, new XmlSchemaSet(nametable));
  169. }
  170. /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer.InferSchema1"]/*' />
  171. public XmlSchemaSet InferSchema(XmlReader instanceDocument, XmlSchemaSet schemas)
  172. {
  173. if (schemas == null)
  174. {
  175. schemas = new XmlSchemaSet(nametable);
  176. }
  177. return InferSchema1(instanceDocument, schemas);
  178. }
  179. internal XmlSchemaSet InferSchema1(XmlReader instanceDocument, XmlSchemaSet schemas)
  180. {
  181. if (instanceDocument == null)
  182. {
  183. throw new ArgumentNullException("instanceDocument");
  184. }
  185. this.rootSchema = null;
  186. xtr = instanceDocument;
  187. schemas.Compile();
  188. this.schemaSet = schemas;
  189. //schemas = new Hashtable();
  190. //while(xtr.Read())
  191. while (xtr.NodeType != XmlNodeType.Element && xtr.Read()) ;
  192. if (xtr.NodeType == XmlNodeType.Element)
  193. {
  194. //Create and process the root element
  195. TargetNamespace = xtr.NamespaceURI;
  196. if ( xtr.NamespaceURI == XmlSchema.Namespace)
  197. {
  198. throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
  199. }
  200. XmlSchemaElement xse = null;
  201. foreach (XmlSchemaElement elem in schemas.GlobalElements.Values)
  202. {
  203. if (elem.Name == xtr.LocalName && elem.QualifiedName.Namespace == xtr.NamespaceURI)
  204. {
  205. rootSchema = elem.Parent as XmlSchema;
  206. xse = elem;
  207. break;
  208. }
  209. }
  210. if (rootSchema == null)
  211. {
  212. //rootSchema = CreateXmlSchema(xtr.NamespaceURI);
  213. xse = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, null, null, -1);
  214. }
  215. else
  216. {
  217. //bRefine = true;
  218. InferElement(xse, false, rootSchema);
  219. }
  220. /* foreach (ReplaceList listItem in schemaList)
  221. {
  222. if (listItem.position < listItem.col.Count)
  223. {
  224. XmlSchemaElement particle = listItem.col[listItem.position] as XmlSchemaElement;
  225. if (particle != null && (particle.RefName.Namespace == XmlSchema.Namespace))
  226. {
  227. XmlSchemaAny any = new XmlSchemaAny();
  228. if (particle.MaxOccurs != 1)
  229. {
  230. any.MaxOccurs = particle.MaxOccurs;
  231. }
  232. if (particle.MinOccurs != 1)
  233. {
  234. any.MinOccurs = particle.MinOccurs;
  235. }
  236. any.ProcessContents = XmlSchemaContentProcessing.Skip;
  237. any.MinOccurs = decimal.Zero;
  238. any.Namespace = particle.RefName.Namespace;
  239. listItem.col[listItem.position] = any;
  240. }
  241. }
  242. }*/
  243. foreach(String prefix in this.NamespaceManager)
  244. {
  245. if (!prefix.Equals("xml") && !prefix.Equals("xmlns"))
  246. {
  247. String ns = this.NamespaceManager.LookupNamespace(this.nametable.Get(prefix));
  248. if (ns.Length != 0) { //Do not add xmlns=""
  249. rootSchema.Namespaces.Add(prefix, ns);
  250. }
  251. }
  252. }
  253. Debug.Assert(this.rootSchema != null, "rootSchema is null");
  254. schemas.Reprocess(rootSchema);
  255. schemas.Compile();
  256. //break;
  257. }
  258. else
  259. {
  260. throw new XmlSchemaInferenceException(Res.SchInf_NoElement, 0, 0);
  261. }
  262. return schemas;
  263. }
  264. private XmlSchemaAttribute AddAttribute(string localName, string prefix, string childURI, string attrValue, bool bCreatingNewType, XmlSchema parentSchema, XmlSchemaObjectCollection addLocation, XmlSchemaObjectTable compiledAttributes)
  265. {
  266. if (childURI == XmlSchema.Namespace)
  267. {
  268. throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
  269. }
  270. XmlSchemaAttribute xsa = null;
  271. int AttributeType = -1;
  272. XmlSchemaAttribute returnedAttribute = null; //this value will change to attributeReference if childURI!= parentURI
  273. XmlSchema xs = null;
  274. bool add = true;
  275. Debug.Assert(compiledAttributes != null); //AttributeUses is never null
  276. // First we need to look into the already compiled attributes
  277. // (they come from the schemaset which we got on input)
  278. // If there are none or we don't find it there, then we must search the list of attributes
  279. // where we are going to add a new one (if it doesn't exist).
  280. // This is necessary to avoid adding duplicate attribute declarations.
  281. ICollection searchCollectionPrimary, searchCollectionSecondary;
  282. if (compiledAttributes.Count > 0) {
  283. searchCollectionPrimary = compiledAttributes.Values;
  284. searchCollectionSecondary = addLocation;
  285. }
  286. else {
  287. searchCollectionPrimary = addLocation;
  288. searchCollectionSecondary = null;
  289. }
  290. if (childURI == XmlReservedNs.NsXml)
  291. {
  292. XmlSchemaAttribute attributeReference = null;
  293. //see if the reference exists
  294. attributeReference = FindAttributeRef(searchCollectionPrimary, localName, childURI);
  295. if (attributeReference == null && searchCollectionSecondary != null) {
  296. attributeReference = FindAttributeRef(searchCollectionSecondary, localName, childURI);
  297. }
  298. if (attributeReference == null)
  299. {
  300. attributeReference = new XmlSchemaAttribute();
  301. attributeReference.RefName = new XmlQualifiedName(localName, childURI);
  302. if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted)
  303. {
  304. attributeReference.Use = XmlSchemaUse.Required;
  305. }
  306. else
  307. {
  308. attributeReference.Use = XmlSchemaUse.Optional;
  309. }
  310. addLocation.Add(attributeReference);
  311. }
  312. returnedAttribute = attributeReference;
  313. }
  314. else
  315. {
  316. if (childURI.Length == 0)
  317. {
  318. xs = parentSchema;
  319. add = false;
  320. }
  321. else if (childURI != null && !schemaSet.Contains(childURI))
  322. {
  323. /*if (parentSchema.AttributeFormDefault = XmlSchemaForm.Unqualified && childURI.Length == 0)
  324. {
  325. xs = parentSchema;
  326. add = false;
  327. break;
  328. }*/
  329. xs = new XmlSchema();
  330. xs.AttributeFormDefault = XmlSchemaForm.Unqualified;
  331. xs.ElementFormDefault = XmlSchemaForm.Qualified;
  332. if (childURI.Length != 0)
  333. xs.TargetNamespace = childURI;
  334. //schemas.Add(childURI, xs);
  335. this.schemaSet.Add(xs);
  336. if (prefix.Length != 0 && String.Compare(prefix, "xml", StringComparison.OrdinalIgnoreCase) != 0)
  337. NamespaceManager.AddNamespace(prefix, childURI);
  338. }
  339. else
  340. {
  341. ArrayList col = this.schemaSet.Schemas(childURI) as ArrayList;
  342. if (col != null && col.Count > 0)
  343. {
  344. xs = col[0] as XmlSchema;
  345. }
  346. }
  347. if (childURI.Length != 0) //
  348. {
  349. XmlSchemaAttribute attributeReference = null;
  350. //see if the reference exists
  351. attributeReference = FindAttributeRef(searchCollectionPrimary, localName, childURI);
  352. if (attributeReference == null & searchCollectionSecondary != null) {
  353. attributeReference = FindAttributeRef(searchCollectionSecondary, localName, childURI);
  354. }
  355. if (attributeReference == null)
  356. {
  357. attributeReference = new XmlSchemaAttribute();
  358. attributeReference.RefName = new XmlQualifiedName(localName, childURI);
  359. if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted)
  360. {
  361. attributeReference.Use = XmlSchemaUse.Required;
  362. }
  363. else
  364. {
  365. attributeReference.Use = XmlSchemaUse.Optional;
  366. }
  367. addLocation.Add(attributeReference);
  368. }
  369. returnedAttribute = attributeReference;
  370. //see if the attribute exists on the global level
  371. xsa = FindAttribute(xs.Items, localName);
  372. if (xsa == null)
  373. {
  374. xsa = new XmlSchemaAttribute();
  375. xsa.Name = localName;
  376. xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
  377. xsa.LineNumber = AttributeType; //we use LineNumber to store flags of valid types
  378. xs.Items.Add(xsa);
  379. }
  380. else
  381. {
  382. if (xsa.Parent == null)
  383. {
  384. AttributeType = xsa.LineNumber; // we use LineNumber to store flags of valid types
  385. }
  386. else
  387. {
  388. AttributeType = GetSchemaType(xsa.SchemaTypeName);
  389. xsa.Parent = null;
  390. }
  391. xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
  392. xsa.LineNumber = AttributeType; // we use LineNumber to store flags of valid types
  393. }
  394. }
  395. else
  396. {
  397. xsa = FindAttribute(searchCollectionPrimary, localName);
  398. if (xsa == null && searchCollectionSecondary != null) {
  399. xsa = FindAttribute(searchCollectionSecondary, localName);
  400. }
  401. if (xsa == null)
  402. {
  403. xsa = new XmlSchemaAttribute();
  404. xsa.Name = localName;
  405. xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
  406. xsa.LineNumber = AttributeType; // we use LineNumber to store flags of valid types
  407. if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted)
  408. xsa.Use = XmlSchemaUse.Required;
  409. else
  410. xsa.Use = XmlSchemaUse.Optional;
  411. addLocation.Add(xsa);
  412. if (xs.AttributeFormDefault != XmlSchemaForm.Unqualified)
  413. {
  414. xsa.Form = XmlSchemaForm.Unqualified;
  415. }
  416. }
  417. else
  418. {
  419. if (xsa.Parent == null)
  420. {
  421. AttributeType = xsa.LineNumber; // we use LineNumber to store flags of valid types
  422. }
  423. else
  424. {
  425. AttributeType = GetSchemaType(xsa.SchemaTypeName);
  426. xsa.Parent = null;
  427. }
  428. xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
  429. xsa.LineNumber = AttributeType; // we use LineNumber to store flags of valid types
  430. }
  431. returnedAttribute = xsa;
  432. }
  433. }
  434. string nullString = null;
  435. if (add && childURI != parentSchema.TargetNamespace)
  436. {
  437. for (int i = 0; i < parentSchema.Includes.Count; ++i)
  438. {
  439. XmlSchemaImport import = parentSchema.Includes[i] as XmlSchemaImport;
  440. if (import == null)
  441. {
  442. continue;
  443. }
  444. if (import.Namespace == childURI)
  445. {
  446. add = false;
  447. }
  448. }
  449. if (add)
  450. {
  451. XmlSchemaImport import = new XmlSchemaImport();
  452. import.Schema = xs;
  453. if (childURI.Length != 0)
  454. {
  455. nullString = childURI;
  456. }
  457. import.Namespace = nullString;
  458. parentSchema.Includes.Add(import);
  459. }
  460. }
  461. return returnedAttribute;
  462. }
  463. private XmlSchema CreateXmlSchema(string targetNS)
  464. {
  465. Debug.Assert(targetNS == null || targetNS.Length > 0 , "targetns for schema is empty");
  466. XmlSchema xs = new XmlSchema();
  467. xs.AttributeFormDefault = XmlSchemaForm.Unqualified;
  468. xs.ElementFormDefault = XmlSchemaForm.Qualified;
  469. xs.TargetNamespace = targetNS;
  470. this.schemaSet.Add(xs);
  471. return xs;
  472. }
  473. private XmlSchemaElement AddElement(string localName, string prefix, string childURI, XmlSchema parentSchema, XmlSchemaObjectCollection addLocation, int positionWithinCollection)
  474. {
  475. if (childURI == XmlSchema.Namespace)
  476. {
  477. throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
  478. }
  479. XmlSchemaElement xse = null;
  480. XmlSchemaElement returnedElement = xse; //this value will change to elementReference if childURI!= parentURI
  481. XmlSchema xs = null;
  482. bool bCreatingNewType = true;
  483. if (childURI == String.Empty)
  484. {
  485. childURI = null;
  486. }
  487. // The new element belongs to the same ns as parent and addlocation is not null
  488. if (parentSchema != null && childURI == parentSchema.TargetNamespace)
  489. {
  490. xse = new XmlSchemaElement();
  491. xse.Name = localName;
  492. xs = parentSchema;
  493. if (xs.ElementFormDefault != XmlSchemaForm.Qualified && addLocation != null)
  494. {
  495. xse.Form = XmlSchemaForm.Qualified;
  496. }
  497. }
  498. else if (schemaSet.Contains(childURI))
  499. {
  500. xse = this.FindGlobalElement(childURI, localName, out xs);
  501. if (xse == null)
  502. {
  503. ArrayList col = this.schemaSet.Schemas(childURI)as ArrayList;
  504. if (col != null && col.Count > 0 )
  505. {
  506. xs = col[0] as XmlSchema;
  507. }
  508. xse = new XmlSchemaElement();
  509. xse.Name = localName;
  510. xs.Items.Add(xse);
  511. }
  512. else
  513. bCreatingNewType = false;
  514. }
  515. else
  516. {
  517. xs = CreateXmlSchema(childURI);
  518. if (prefix.Length!=0)
  519. NamespaceManager.AddNamespace(prefix, childURI);
  520. xse=new XmlSchemaElement();
  521. xse.Name = localName;
  522. xs.Items.Add(xse); //add global element declaration only when creating new schema
  523. }
  524. if (parentSchema == null)
  525. {
  526. parentSchema = xs;
  527. this.rootSchema = parentSchema;
  528. }
  529. if (childURI != parentSchema.TargetNamespace )
  530. {
  531. bool add = true;
  532. for (int i = 0; i < parentSchema.Includes.Count; ++i)
  533. {
  534. XmlSchemaImport import = parentSchema.Includes[i] as XmlSchemaImport;
  535. if (import == null)
  536. {
  537. continue;
  538. }
  539. //Debug.WriteLine(import.Schema.TargetNamespace);
  540. if (import.Namespace == childURI)
  541. {
  542. add = false;
  543. }
  544. }
  545. if (add)
  546. {
  547. XmlSchemaImport import = new XmlSchemaImport();
  548. import.Schema = xs;
  549. import.Namespace = childURI;
  550. parentSchema.Includes.Add(import);
  551. }
  552. }
  553. returnedElement = xse;
  554. if (addLocation != null)
  555. {
  556. if (childURI == parentSchema.TargetNamespace )
  557. {
  558. if (this.Occurrence == InferenceOption.Relaxed /*&& parentSchema.Items != addLocation*/)
  559. {
  560. xse.MinOccurs = 0;
  561. }
  562. if (positionWithinCollection == -1)
  563. {
  564. positionWithinCollection = addLocation.Add(xse);
  565. }
  566. else
  567. {
  568. addLocation.Insert(positionWithinCollection, xse);
  569. }
  570. }
  571. else
  572. {
  573. XmlSchemaElement elementReference = new XmlSchemaElement();
  574. elementReference.RefName = new XmlQualifiedName(localName, childURI);
  575. if (this.Occurrence == InferenceOption.Relaxed)
  576. {
  577. elementReference.MinOccurs = 0;
  578. }
  579. if (positionWithinCollection == -1)
  580. {
  581. positionWithinCollection = addLocation.Add(elementReference);
  582. }
  583. else
  584. {
  585. addLocation.Insert(positionWithinCollection, elementReference);
  586. }
  587. returnedElement = elementReference;
  588. /* if (childURI == XmlSchema.Namespace)
  589. {
  590. schemaList.Add(new ReplaceList(addLocation, positionWithinCollection));
  591. }*/
  592. }
  593. }
  594. InferElement(xse, bCreatingNewType, xs);
  595. return returnedElement;
  596. }
  597. /// <summary>
  598. /// Sets type of the xse based on the currently read element.
  599. /// If the type is already set, verifies that it matches the instance and if not, updates the type to validate the instance.
  600. /// </summary>
  601. /// <param name="xse">XmlSchemaElement corresponding to the element just read by the xtr XmlTextReader</param>
  602. /// <param name="bCreatingNewType">true if the type is newly created, false if the type already existed and matches the current element name</param>
  603. /// <param name="nsContext">namespaceURI of the parent element. Used to distinguish if ref= should be used when parent is in different ns than child.</param>
  604. internal void InferElement(XmlSchemaElement xse, bool bCreatingNewType, XmlSchema parentSchema)
  605. {
  606. bool bEmptyElement = xtr.IsEmptyElement;
  607. int lastUsedSeqItem = -1;
  608. Hashtable table = new Hashtable();
  609. XmlSchemaType schemaType = GetEffectiveSchemaType(xse, bCreatingNewType);
  610. XmlSchemaComplexType ct = schemaType as XmlSchemaComplexType;
  611. //infer type based on content of the current element
  612. if (xtr.MoveToFirstAttribute())
  613. {
  614. ProcessAttributes(ref xse, schemaType, bCreatingNewType, parentSchema);
  615. }
  616. else
  617. {
  618. if (!bCreatingNewType && ct != null)
  619. { //if type already exists and can potentially have attributes
  620. MakeExistingAttributesOptional(ct, null);
  621. }
  622. }
  623. if (ct == null || ct == XmlSchemaComplexType.AnyType) { //It was null or simple type, after processing attributes, this might have been set
  624. ct = xse.SchemaType as XmlSchemaComplexType;
  625. }
  626. //xse's type is set either to complex type if attributes exist or null
  627. if (bEmptyElement) //<element attr="3232" />
  628. {
  629. if (!bCreatingNewType)
  630. {
  631. if (null != ct)
  632. {
  633. if (null!= ct.Particle )
  634. {
  635. ct.Particle.MinOccurs = 0;
  636. }
  637. else if (null != ct.ContentModel)
  638. {
  639. XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  640. sce.BaseTypeName = ST_string;
  641. sce.LineNumber = TF_string;
  642. }
  643. }
  644. else if (!xse.SchemaTypeName.IsEmpty)
  645. {
  646. xse.LineNumber = TF_string;
  647. xse.SchemaTypeName = ST_string;
  648. }
  649. }
  650. else
  651. {
  652. xse.LineNumber = TF_string;
  653. //xse.SchemaTypeName = ST_string; //My change
  654. }
  655. return; //We are done processing this element - all attributes are already added
  656. }
  657. bool bWhiteSpace = false;
  658. do
  659. {
  660. xtr.Read();
  661. if (xtr.NodeType == XmlNodeType.Whitespace)
  662. {
  663. bWhiteSpace = true;
  664. }
  665. if (xtr.NodeType == XmlNodeType.EntityReference)
  666. {
  667. throw new XmlSchemaInferenceException(Res.SchInf_entity, 0, 0);
  668. }
  669. } while( (!xtr.EOF) && (xtr.NodeType != XmlNodeType.EndElement) && (xtr.NodeType != XmlNodeType.CDATA)&&(xtr.NodeType != XmlNodeType.Element)&&(xtr.NodeType != XmlNodeType.Text) );
  670. if (xtr.NodeType == XmlNodeType.EndElement)
  671. {
  672. if (bWhiteSpace) {
  673. if (ct != null)
  674. {
  675. if (null != ct.ContentModel)
  676. {
  677. XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  678. sce.BaseTypeName = ST_string;
  679. sce.LineNumber = TF_string;
  680. }
  681. else if (bCreatingNewType)
  682. {
  683. //attributes exist, but both Particle and ContentModel == null - this must be complex type with simpleContent extension
  684. XmlSchemaSimpleContent sc = new XmlSchemaSimpleContent();
  685. ct.ContentModel = sc;
  686. XmlSchemaSimpleContentExtension sce = new XmlSchemaSimpleContentExtension();
  687. sc.Content = sce;
  688. MoveAttributes(ct, sce, bCreatingNewType);
  689. sce.BaseTypeName = ST_string;
  690. sce.LineNumber = TF_string;
  691. }
  692. else
  693. ct.IsMixed = true;
  694. }
  695. else
  696. {
  697. xse.SchemaTypeName = ST_string;
  698. xse.LineNumber = TF_string;
  699. }
  700. }
  701. if (bCreatingNewType)
  702. {
  703. xse.LineNumber = TF_string;
  704. //xse.SchemaTypeName = ST_string; //my change
  705. }
  706. else
  707. {
  708. if (null != ct)
  709. {
  710. if (null!= ct.Particle)
  711. {
  712. ct.Particle.MinOccurs = 0;
  713. }
  714. else if (null != ct.ContentModel)
  715. {
  716. XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  717. sce.BaseTypeName = ST_string;
  718. sce.LineNumber = TF_string;
  719. }
  720. }
  721. else if (!xse.SchemaTypeName.IsEmpty)
  722. {
  723. xse.LineNumber = TF_string;
  724. xse.SchemaTypeName = ST_string;
  725. }
  726. }
  727. return; //<element attr="232"></element>
  728. }
  729. int iChildNumber = 0;
  730. bool bCreatingNewSequence = false;
  731. while (!xtr.EOF && (xtr.NodeType != XmlNodeType.EndElement))
  732. {
  733. bool bNextNodeAlreadyRead = false; //In some cases we have to look ahead one node. If true means that we did look ahead.
  734. iChildNumber++;
  735. if ((xtr.NodeType == XmlNodeType.Text) || (xtr.NodeType == XmlNodeType.CDATA) ) //node can be simple type, complex with simple content or complex with mixed content
  736. {
  737. if (null != ct)
  738. {
  739. if (null != ct.Particle)
  740. {
  741. ct.IsMixed = true;
  742. if (iChildNumber==1)
  743. {
  744. //if this is the only child and other elements do not follow, we must set particle minOccurs="0"
  745. do{ xtr.Read();} while( (!xtr.EOF) && ((xtr.NodeType == XmlNodeType.CDATA)||(xtr.NodeType == XmlNodeType.Text) || (xtr.NodeType == XmlNodeType.Comment) || (xtr.NodeType == XmlNodeType.ProcessingInstruction) || (xtr.NodeType == XmlNodeType.Whitespace) || (xtr.NodeType == XmlNodeType.SignificantWhitespace) || (xtr.NodeType == XmlNodeType.XmlDeclaration)));
  746. bNextNodeAlreadyRead = true;
  747. if (xtr.NodeType == XmlNodeType.EndElement)
  748. ct.Particle.MinOccurs=decimal.Zero;
  749. }
  750. }
  751. else if (null!=ct.ContentModel)
  752. { //complexType with simpleContent
  753. XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  754. if ((xtr.NodeType == XmlNodeType.Text) && (iChildNumber==1))
  755. {
  756. int SimpleType = -1;
  757. if (xse.Parent == null)
  758. {
  759. SimpleType = sce.LineNumber; // we use LineNumber to represent valid type flags
  760. }
  761. else
  762. {
  763. SimpleType = GetSchemaType(sce.BaseTypeName);
  764. xse.Parent = null;
  765. }
  766. sce.BaseTypeName = RefineSimpleType(xtr.Value, ref SimpleType);
  767. sce.LineNumber = SimpleType; // we use LineNumber to represent valid type flags
  768. }
  769. else
  770. {
  771. sce.BaseTypeName = ST_string;
  772. sce.LineNumber = TF_string;
  773. }
  774. }
  775. else
  776. {
  777. //attributes exist, but both Particle and ContentModel == null - this must be complex type with simpleContent extension
  778. XmlSchemaSimpleContent sc = new XmlSchemaSimpleContent();
  779. ct.ContentModel = sc;
  780. XmlSchemaSimpleContentExtension sce = new XmlSchemaSimpleContentExtension();
  781. sc.Content = sce;
  782. MoveAttributes(ct, sce, bCreatingNewType);
  783. if (xtr.NodeType == XmlNodeType.Text)
  784. {
  785. int TypeFlags;
  786. if(!bCreatingNewType)
  787. //previously this was empty element
  788. TypeFlags=TF_string;
  789. else
  790. TypeFlags = -1;
  791. sce.BaseTypeName = RefineSimpleType(xtr.Value, ref TypeFlags);
  792. sce.LineNumber = TypeFlags; // we use LineNumber to store flags of valid types
  793. }
  794. else
  795. {
  796. sce.BaseTypeName = ST_string;
  797. sce.LineNumber = TF_string;
  798. }
  799. }
  800. }
  801. else
  802. { //node is currently empty or with SimpleType
  803. //node will become simple type
  804. if (iChildNumber>1)
  805. {
  806. //more than one consecutive text nodes probably with PI in between
  807. xse.SchemaTypeName = ST_string;
  808. xse.LineNumber = TF_string;// we use LineNumber to store flags of valid types
  809. }
  810. else
  811. {
  812. int TypeFlags = -1;
  813. if (bCreatingNewType)
  814. if (xtr.NodeType == XmlNodeType.Text)
  815. {
  816. xse.SchemaTypeName = RefineSimpleType(xtr.Value, ref TypeFlags);
  817. xse.LineNumber = TypeFlags; // we use LineNumber to store flags of valid types
  818. }
  819. else
  820. {
  821. xse.SchemaTypeName = ST_string;
  822. xse.LineNumber = TF_string;// we use LineNumber to store flags of valid types
  823. }
  824. else if (xtr.NodeType == XmlNodeType.Text)
  825. {
  826. if (xse.Parent == null)
  827. {
  828. TypeFlags = xse.LineNumber;
  829. }
  830. else
  831. {
  832. TypeFlags = GetSchemaType(xse.SchemaTypeName);
  833. if (TypeFlags == -1 && xse.LineNumber == TF_string) { //Since schemaTypeName is not set for empty elements (<e></e>)
  834. TypeFlags = TF_string;
  835. }
  836. xse.Parent = null;
  837. }
  838. xse.SchemaTypeName = RefineSimpleType(xtr.Value, ref TypeFlags); //simple type
  839. xse.LineNumber = TypeFlags; // we use LineNumber to store flags of valid types
  840. }
  841. else
  842. {
  843. xse.SchemaTypeName = ST_string;
  844. xse.LineNumber = TF_string;// we use LineNumber to store flags of valid types
  845. }
  846. }
  847. }
  848. }
  849. else if (xtr.NodeType == XmlNodeType.Element)
  850. {
  851. XmlQualifiedName qname = new XmlQualifiedName(xtr.LocalName, xtr.NamespaceURI);
  852. bool Maxoccursflag = false;
  853. if (table.Contains(qname))
  854. {
  855. Maxoccursflag = true;
  856. }
  857. else
  858. {
  859. table.Add(qname, null);
  860. }
  861. if (ct==null)
  862. { //untill now the element was empty or SimpleType - it now becomes complex type
  863. ct = new XmlSchemaComplexType();
  864. xse.SchemaType = ct;
  865. if (!xse.SchemaTypeName.IsEmpty) //
  866. {
  867. ct.IsMixed=true;
  868. xse.SchemaTypeName = XmlQualifiedName.Empty;
  869. }
  870. }
  871. if (ct.ContentModel !=null)
  872. { //type was previously identified as simple content extension - we need to convert it to sequence
  873. XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  874. MoveAttributes(sce, ct);
  875. ct.ContentModel = null;
  876. ct.IsMixed = true;
  877. if (ct.Particle != null)
  878. throw new XmlSchemaInferenceException(Res.SchInf_particle, 0, 0);
  879. ct.Particle = new XmlSchemaSequence();
  880. bCreatingNewSequence = true;
  881. XmlSchemaElement subelement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema,((XmlSchemaSequence)ct.Particle).Items, -1);
  882. lastUsedSeqItem = 0;
  883. if (!bCreatingNewType)
  884. ct.Particle.MinOccurs=0; //previously this was simple type so subelements did not exist
  885. }
  886. else if (ct.Particle == null)
  887. {
  888. ct.Particle = new XmlSchemaSequence();
  889. bCreatingNewSequence = true;
  890. XmlSchemaElement subelement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema,((XmlSchemaSequence)ct.Particle).Items, -1);
  891. if (!bCreatingNewType)
  892. {
  893. ((XmlSchemaSequence)ct.Particle).MinOccurs = decimal.Zero;
  894. // subelement.MinOccurs = decimal.Zero;
  895. }
  896. lastUsedSeqItem = 0;
  897. }
  898. else
  899. {
  900. bool bParticleChanged = false;
  901. XmlSchemaElement subelement = FindMatchingElement(bCreatingNewType || bCreatingNewSequence, xtr, ct, ref lastUsedSeqItem, ref bParticleChanged, parentSchema, Maxoccursflag);
  902. }
  903. }
  904. else if (xtr.NodeType == XmlNodeType.Text)
  905. {
  906. if (ct==null)
  907. throw new XmlSchemaInferenceException(Res.SchInf_ct, 0, 0);
  908. ct.IsMixed = true;
  909. }
  910. do
  911. {
  912. if (xtr.NodeType == XmlNodeType.EntityReference)
  913. {
  914. throw new XmlSchemaInferenceException(Res.SchInf_entity, 0, 0);
  915. }
  916. if (!bNextNodeAlreadyRead)
  917. {
  918. xtr.Read();
  919. }
  920. else
  921. {
  922. bNextNodeAlreadyRead = false;
  923. }
  924. } while( (!xtr.EOF) && (xtr.NodeType != XmlNodeType.EndElement) && (xtr.NodeType != XmlNodeType.CDATA)&&(xtr.NodeType != XmlNodeType.Element)&&(xtr.NodeType != XmlNodeType.Text));
  925. }
  926. if (lastUsedSeqItem != -1)
  927. {
  928. //Verify if all elements in a sequence exist, if not set MinOccurs=0
  929. while (++lastUsedSeqItem < ((XmlSchemaSequence)ct.Particle).Items.Count)
  930. {
  931. if (((XmlSchemaSequence)ct.Particle).Items[lastUsedSeqItem].GetType() != typeof (XmlSchemaElement))
  932. throw new XmlSchemaInferenceException(Res.SchInf_seq, 0 , 0);
  933. XmlSchemaElement subElement = (XmlSchemaElement) ((XmlSchemaSequence)ct.Particle).Items[lastUsedSeqItem];
  934. subElement.MinOccurs = 0;
  935. }
  936. }
  937. }
  938. private XmlSchemaSimpleContentExtension CheckSimpleContentExtension(XmlSchemaComplexType ct) {
  939. XmlSchemaSimpleContent sc = ct.C

Large files files are truncated, but you can click here to view the full file