XmlSchemaExporter.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. //
  2. // System.Xml.Serialization.XmlSchemaExporter
  3. //
  4. // Author:
  5. // Tim Coleman ([email protected])
  6. // Lluis Sanchez Gual ([email protected])
  7. //
  8. // Copyright (C) Tim Coleman, 2002
  9. //
  10. using System.Xml;
  11. using System.Xml.Schema;
  12. using System.Collections;
  13. namespace System.Xml.Serialization {
  14. public class XmlSchemaExporter {
  15. #region Fields
  16. XmlSchemas schemas;
  17. Hashtable exportedMaps = new Hashtable();
  18. Hashtable exportedElements = new Hashtable();
  19. bool encodedFormat = false;
  20. XmlDocument xmlDoc;
  21. #endregion
  22. #region Constructors
  23. public XmlSchemaExporter (XmlSchemas schemas)
  24. {
  25. this.schemas = schemas;
  26. }
  27. internal XmlSchemaExporter (XmlSchemas schemas, bool encodedFormat)
  28. {
  29. this.encodedFormat = encodedFormat;
  30. this.schemas = schemas;
  31. }
  32. #endregion // Constructors
  33. #region Methods
  34. [MonoTODO]
  35. public string ExportAnyType (string ns)
  36. {
  37. throw new NotImplementedException ();
  38. }
  39. public void ExportMembersMapping (XmlMembersMapping xmlMembersMapping)
  40. {
  41. ExportMembersMapping (xmlMembersMapping, true);
  42. }
  43. internal void ExportMembersMapping (XmlMembersMapping xmlMembersMapping, bool exportEnclosingType)
  44. {
  45. ClassMap cmap = (ClassMap) xmlMembersMapping.ObjectMap;
  46. if (xmlMembersMapping.HasWrapperElement && exportEnclosingType)
  47. {
  48. XmlSchema schema = GetSchema (xmlMembersMapping.Namespace);
  49. XmlSchemaComplexType stype = new XmlSchemaComplexType ();
  50. XmlSchemaSequence particle;
  51. XmlSchemaAnyAttribute anyAttribute;
  52. ExportMembersMapSchema (schema, cmap, null, stype.Attributes, out particle, out anyAttribute);
  53. stype.Particle = particle;
  54. stype.AnyAttribute = anyAttribute;
  55. if (encodedFormat)
  56. {
  57. stype.Name = xmlMembersMapping.ElementName;
  58. schema.Items.Add (stype);
  59. }
  60. else
  61. {
  62. XmlSchemaElement selem = new XmlSchemaElement ();
  63. selem.Name = xmlMembersMapping.ElementName;
  64. selem.SchemaType = stype;
  65. schema.Items.Add (selem);
  66. }
  67. }
  68. else
  69. {
  70. ICollection members = cmap.ElementMembers;
  71. if (members != null)
  72. {
  73. foreach (XmlTypeMapMemberElement member in members)
  74. {
  75. if (member is XmlTypeMapMemberAnyElement && member.TypeData.IsListType)
  76. {
  77. XmlSchema mschema = GetSchema (xmlMembersMapping.Namespace);
  78. XmlSchemaParticle par = GetSchemaArrayElement (mschema, member.ElementInfo);
  79. if (par is XmlSchemaAny)
  80. {
  81. XmlSchemaComplexType ct = FindComplexType (mschema.Items, "any");
  82. if (ct != null) continue;
  83. ct = new XmlSchemaComplexType ();
  84. ct.Name = "any";
  85. ct.IsMixed = true;
  86. XmlSchemaSequence seq = new XmlSchemaSequence ();
  87. ct.Particle = seq;
  88. seq.Items.Add (par);
  89. mschema.Items.Add (ct);
  90. continue;
  91. }
  92. }
  93. XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) member.ElementInfo [0];
  94. XmlSchema schema;
  95. if (encodedFormat)
  96. {
  97. schema = GetSchema (xmlMembersMapping.Namespace);
  98. ImportNamespace (schema, XmlSerializer.EncodingNamespace);
  99. }
  100. else
  101. schema = GetSchema (einfo.Namespace);
  102. XmlSchemaElement exe = FindElement (schema.Items, einfo.ElementName);
  103. XmlSchemaElement elem;
  104. Type memType = member.GetType();
  105. if (member is XmlTypeMapMemberFlatList)
  106. throw new InvalidOperationException ("Unwrapped arrays not supported as parameters");
  107. else if (memType == typeof(XmlTypeMapMemberElement))
  108. elem = (XmlSchemaElement) GetSchemaElement (schema, einfo, member.DefaultValue, false);
  109. else
  110. elem = (XmlSchemaElement) GetSchemaElement (schema, einfo, false);
  111. // In encoded format, the schema elements are not needed
  112. if (!encodedFormat)
  113. schema.Items.Add (elem);
  114. if (exe != null)
  115. {
  116. if (exe.SchemaTypeName.Equals (elem.SchemaTypeName))
  117. schema.Items.Remove (elem);
  118. else
  119. {
  120. string s = "The XML element named '" + einfo.ElementName + "' ";
  121. s += "from namespace '" + schema.TargetNamespace + "' references distinct types " + elem.SchemaTypeName.Name + " and " + exe.SchemaTypeName.Name + ". ";
  122. s += "Use XML attributes to specify another XML name or namespace for the element or types.";
  123. throw new InvalidOperationException (s);
  124. }
  125. }
  126. }
  127. }
  128. }
  129. CompileSchemas ();
  130. }
  131. [MonoTODO]
  132. public XmlQualifiedName ExportTypeMapping (XmlMembersMapping xmlMembersMapping)
  133. {
  134. throw new NotImplementedException ();
  135. }
  136. public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping)
  137. {
  138. if (!xmlTypeMapping.IncludeInSchema) return;
  139. if (IsElementExported (xmlTypeMapping)) return;
  140. if (encodedFormat)
  141. {
  142. ExportClassSchema (xmlTypeMapping);
  143. XmlSchema schema = GetSchema (xmlTypeMapping.XmlTypeNamespace);
  144. ImportNamespace (schema, XmlSerializer.EncodingNamespace);
  145. }
  146. else
  147. {
  148. XmlSchema schema = GetSchema (xmlTypeMapping.Namespace);
  149. XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (null, xmlTypeMapping.TypeData);
  150. einfo.Namespace = xmlTypeMapping.Namespace;
  151. einfo.ElementName = xmlTypeMapping.ElementName;
  152. if (xmlTypeMapping.TypeData.IsComplexType)
  153. einfo.MappedType = xmlTypeMapping;
  154. einfo.IsNullable = false;
  155. schema.Items.Add (GetSchemaElement (schema, einfo, false));
  156. SetElementExported (xmlTypeMapping);
  157. }
  158. CompileSchemas ();
  159. }
  160. void ExportClassSchema (XmlTypeMapping map)
  161. {
  162. if (IsMapExported (map)) return;
  163. SetMapExported (map);
  164. if (map.TypeData.Type == typeof(object))
  165. {
  166. foreach (XmlTypeMapping dmap in map.DerivedTypes)
  167. if (dmap.TypeData.SchemaType == SchemaTypes.Class) ExportClassSchema (dmap);
  168. return;
  169. }
  170. XmlSchema schema = GetSchema (map.XmlTypeNamespace);
  171. XmlSchemaComplexType stype = new XmlSchemaComplexType ();
  172. stype.Name = map.XmlType;
  173. schema.Items.Add (stype);
  174. ClassMap cmap = (ClassMap)map.ObjectMap;
  175. if (cmap.HasSimpleContent)
  176. {
  177. XmlSchemaSimpleContent simple = new XmlSchemaSimpleContent ();
  178. stype.ContentModel = simple;
  179. XmlSchemaSimpleContentExtension ext = new XmlSchemaSimpleContentExtension ();
  180. simple.Content = ext;
  181. XmlSchemaSequence particle;
  182. XmlSchemaAnyAttribute anyAttribute;
  183. ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
  184. ext.AnyAttribute = anyAttribute;
  185. if (map.BaseMap == null)
  186. ext.BaseTypeName = cmap.SimpleContentBaseType;
  187. else
  188. ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
  189. }
  190. else if (map.BaseMap != null && map.BaseMap.IncludeInSchema)
  191. {
  192. XmlSchemaComplexContent cstype = new XmlSchemaComplexContent ();
  193. XmlSchemaComplexContentExtension ext = new XmlSchemaComplexContentExtension ();
  194. ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
  195. cstype.Content = ext;
  196. stype.ContentModel = cstype;
  197. XmlSchemaSequence particle;
  198. XmlSchemaAnyAttribute anyAttribute;
  199. ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
  200. ext.Particle = particle;
  201. ext.AnyAttribute = anyAttribute;
  202. stype.IsMixed = cmap.XmlTextCollector != null;
  203. ImportNamespace (schema, map.BaseMap.XmlTypeNamespace);
  204. ExportClassSchema (map.BaseMap);
  205. }
  206. else
  207. {
  208. XmlSchemaSequence particle;
  209. XmlSchemaAnyAttribute anyAttribute;
  210. ExportMembersMapSchema (schema, cmap, map.BaseMap, stype.Attributes, out particle, out anyAttribute);
  211. stype.Particle = particle;
  212. stype.AnyAttribute = anyAttribute;
  213. stype.IsMixed = cmap.XmlTextCollector != null;
  214. }
  215. foreach (XmlTypeMapping dmap in map.DerivedTypes)
  216. if (dmap.TypeData.SchemaType == SchemaTypes.Class) ExportClassSchema (dmap);
  217. }
  218. void ExportMembersMapSchema (XmlSchema schema, ClassMap map, XmlTypeMapping baseMap, XmlSchemaObjectCollection outAttributes, out XmlSchemaSequence particle, out XmlSchemaAnyAttribute anyAttribute)
  219. {
  220. particle = null;
  221. XmlSchemaSequence seq = new XmlSchemaSequence ();
  222. ICollection members = map.ElementMembers;
  223. if (members != null && !map.HasSimpleContent)
  224. {
  225. foreach (XmlTypeMapMemberElement member in members)
  226. {
  227. if (baseMap != null && DefinedInBaseMap (baseMap, member)) continue;
  228. Type memType = member.GetType();
  229. if (memType == typeof(XmlTypeMapMemberFlatList))
  230. {
  231. XmlSchemaParticle part = GetSchemaArrayElement (schema, member.ElementInfo);
  232. if (part != null) seq.Items.Add (part);
  233. }
  234. else if (memType == typeof(XmlTypeMapMemberAnyElement))
  235. {
  236. seq.Items.Add (GetSchemaArrayElement (schema, member.ElementInfo));
  237. }
  238. else if (memType == typeof(XmlTypeMapMemberElement))
  239. {
  240. seq.Items.Add (GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo [0], member.DefaultValue, true));
  241. }
  242. else
  243. {
  244. seq.Items.Add (GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo [0], true));
  245. }
  246. }
  247. }
  248. if (seq.Items.Count > 0)
  249. particle = seq;
  250. // Write attributes
  251. ICollection attributes = map.AttributeMembers;
  252. if (attributes != null)
  253. {
  254. foreach (XmlTypeMapMemberAttribute attr in attributes) {
  255. if (baseMap != null && DefinedInBaseMap (baseMap, attr)) continue;
  256. outAttributes.Add (GetSchemaAttribute (schema, attr, true));
  257. }
  258. }
  259. XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
  260. if (anyAttrMember != null)
  261. anyAttribute = new XmlSchemaAnyAttribute ();
  262. else
  263. anyAttribute = null;
  264. }
  265. XmlSchemaElement FindElement (XmlSchemaObjectCollection col, string name)
  266. {
  267. foreach (XmlSchemaObject ob in col)
  268. {
  269. XmlSchemaElement elem = ob as XmlSchemaElement;
  270. if (elem != null && elem.Name == name) return elem;
  271. }
  272. return null;
  273. }
  274. XmlSchemaComplexType FindComplexType (XmlSchemaObjectCollection col, string name)
  275. {
  276. foreach (XmlSchemaObject ob in col)
  277. {
  278. XmlSchemaComplexType ctype = ob as XmlSchemaComplexType;
  279. if (ctype != null && ctype.Name == name) return ctype;
  280. }
  281. return null;
  282. }
  283. XmlSchemaAttribute GetSchemaAttribute (XmlSchema currentSchema, XmlTypeMapMemberAttribute attinfo, bool isTypeMember)
  284. {
  285. XmlSchemaAttribute sat = new XmlSchemaAttribute ();
  286. if (attinfo.DefaultValue != System.DBNull.Value) sat.DefaultValue = XmlCustomFormatter.ToXmlString (attinfo.TypeData, attinfo.DefaultValue);
  287. ImportNamespace (currentSchema, attinfo.Namespace);
  288. XmlSchema memberSchema;
  289. if (attinfo.Namespace.Length == 0 && attinfo.Form != XmlSchemaForm.Qualified)
  290. memberSchema = currentSchema;
  291. else
  292. memberSchema = GetSchema (attinfo.Namespace);
  293. if (currentSchema == memberSchema || encodedFormat)
  294. {
  295. sat.Name = attinfo.AttributeName;
  296. if (isTypeMember) sat.Form = attinfo.Form;
  297. if (attinfo.TypeData.SchemaType == SchemaTypes.Enum)
  298. {
  299. ImportNamespace (currentSchema, attinfo.DataTypeNamespace);
  300. ExportEnumSchema (attinfo.MappedType);
  301. sat.SchemaTypeName = new XmlQualifiedName (attinfo.TypeData.XmlType, attinfo.DataTypeNamespace);;
  302. }
  303. else if (attinfo.TypeData.SchemaType == SchemaTypes.Array && TypeTranslator.IsPrimitive (attinfo.TypeData.ListItemType))
  304. {
  305. sat.SchemaType = GetSchemaSimpleListType (attinfo.TypeData);
  306. }
  307. else
  308. sat.SchemaTypeName = new XmlQualifiedName (attinfo.TypeData.XmlType, attinfo.DataTypeNamespace);;
  309. }
  310. else
  311. {
  312. sat.RefName = new XmlQualifiedName (attinfo.AttributeName, attinfo.Namespace);
  313. foreach (XmlSchemaObject ob in memberSchema.Items)
  314. if (ob is XmlSchemaAttribute && ((XmlSchemaAttribute)ob).Name == attinfo.AttributeName)
  315. return sat;
  316. memberSchema.Items.Add (GetSchemaAttribute (memberSchema, attinfo, false));
  317. }
  318. return sat;
  319. }
  320. XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, bool isTypeMember)
  321. {
  322. return GetSchemaElement (currentSchema, einfo, System.DBNull.Value, isTypeMember);
  323. }
  324. XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, object defaultValue, bool isTypeMember)
  325. {
  326. if (einfo.IsTextElement) return null;
  327. if (einfo.IsUnnamedAnyElement)
  328. {
  329. XmlSchemaAny any = new XmlSchemaAny ();
  330. any.MinOccurs = 0;
  331. any.MaxOccurs = 1;
  332. return any;
  333. }
  334. XmlSchemaElement selem = new XmlSchemaElement ();
  335. if (isTypeMember)
  336. {
  337. selem.MaxOccurs = 1;
  338. selem.MinOccurs = einfo.IsNullable ? 1 : 0;
  339. if ((einfo.TypeData.IsValueType && einfo.Member != null && !einfo.Member.IsOptionalValueType) || encodedFormat)
  340. selem.MinOccurs = 1;
  341. }
  342. XmlSchema memberSchema = null;
  343. if (!encodedFormat)
  344. {
  345. memberSchema = GetSchema (einfo.Namespace);
  346. ImportNamespace (currentSchema, einfo.Namespace);
  347. }
  348. if (currentSchema == memberSchema || encodedFormat || !isTypeMember)
  349. {
  350. if (isTypeMember) selem.IsNillable = einfo.IsNullable;
  351. selem.Name = einfo.ElementName;
  352. XmlQualifiedName typeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);
  353. if (defaultValue != System.DBNull.Value)
  354. selem.DefaultValue = XmlCustomFormatter.ToXmlString (einfo.TypeData, defaultValue);
  355. if (einfo.Form != XmlSchemaForm.Qualified)
  356. selem.Form = einfo.Form;
  357. switch (einfo.TypeData.SchemaType)
  358. {
  359. case SchemaTypes.XmlNode:
  360. selem.SchemaType = GetSchemaXmlNodeType ();
  361. break;
  362. case SchemaTypes.XmlSerializable:
  363. selem.SchemaType = GetSchemaXmlSerializableType ();
  364. break;
  365. case SchemaTypes.Enum:
  366. selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
  367. ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
  368. ExportEnumSchema (einfo.MappedType);
  369. break;
  370. case SchemaTypes.Array:
  371. XmlQualifiedName atypeName = ExportArraySchema (einfo.MappedType, currentSchema.TargetNamespace);
  372. selem.SchemaTypeName = atypeName;
  373. ImportNamespace (currentSchema, atypeName.Namespace);
  374. break;
  375. case SchemaTypes.Class:
  376. if (einfo.MappedType.TypeData.Type != typeof(object)) {
  377. selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
  378. ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
  379. }
  380. else if (encodedFormat)
  381. selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
  382. ExportClassSchema (einfo.MappedType);
  383. break;
  384. case SchemaTypes.Primitive:
  385. selem.SchemaTypeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);;
  386. break;
  387. }
  388. }
  389. else
  390. {
  391. selem.RefName = new XmlQualifiedName (einfo.ElementName, einfo.Namespace);
  392. foreach (XmlSchemaObject ob in memberSchema.Items)
  393. if (ob is XmlSchemaElement && ((XmlSchemaElement)ob).Name == einfo.ElementName)
  394. return selem;
  395. memberSchema.Items.Add (GetSchemaElement (memberSchema, einfo, defaultValue, false));
  396. }
  397. return selem;
  398. }
  399. void ImportNamespace (XmlSchema schema, string ns)
  400. {
  401. if (ns == "" || ns == schema.TargetNamespace || ns == XmlSchema.Namespace) return;
  402. foreach (XmlSchemaObject sob in schema.Includes)
  403. if ((sob is XmlSchemaImport) && ((XmlSchemaImport)sob).Namespace == ns) return;
  404. XmlSchemaImport imp = new XmlSchemaImport ();
  405. imp.Namespace = ns;
  406. schema.Includes.Add (imp);
  407. }
  408. bool DefinedInBaseMap (XmlTypeMapping map, XmlTypeMapMember member)
  409. {
  410. if (((ClassMap)map.ObjectMap).FindMember (member.Name) != null)
  411. return true;
  412. else if (map.BaseMap != null)
  413. return DefinedInBaseMap (map.BaseMap, member);
  414. else
  415. return false;
  416. }
  417. XmlSchemaType GetSchemaXmlNodeType ()
  418. {
  419. XmlSchemaComplexType stype = new XmlSchemaComplexType ();
  420. stype.IsMixed = true;
  421. XmlSchemaSequence seq = new XmlSchemaSequence ();
  422. seq.Items.Add (new XmlSchemaAny ());
  423. stype.Particle = seq;
  424. return stype;
  425. }
  426. XmlSchemaType GetSchemaXmlSerializableType ()
  427. {
  428. XmlSchemaComplexType stype = new XmlSchemaComplexType ();
  429. XmlSchemaSequence seq = new XmlSchemaSequence ();
  430. XmlSchemaElement selem = new XmlSchemaElement ();
  431. selem.RefName = new XmlQualifiedName ("schema",XmlSchema.Namespace);
  432. seq.Items.Add (selem);
  433. seq.Items.Add (new XmlSchemaAny ());
  434. stype.Particle = seq;
  435. return stype;
  436. }
  437. XmlSchemaSimpleType GetSchemaSimpleListType (TypeData typeData)
  438. {
  439. XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
  440. XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList ();
  441. TypeData itemTypeData = TypeTranslator.GetTypeData (typeData.ListItemType);
  442. list.ItemTypeName = new XmlQualifiedName (itemTypeData.XmlType, XmlSchema.Namespace);
  443. stype.Content = list;
  444. return stype;
  445. }
  446. XmlSchemaParticle GetSchemaArrayElement (XmlSchema currentSchema, XmlTypeMapElementInfoList infos)
  447. {
  448. int numInfos = infos.Count;
  449. if (numInfos > 0 && ((XmlTypeMapElementInfo)infos[0]).IsTextElement) numInfos--;
  450. if (numInfos == 0) return null;
  451. if (numInfos == 1)
  452. {
  453. XmlSchemaParticle selem = GetSchemaElement (currentSchema, (XmlTypeMapElementInfo) infos[infos.Count-1], true);
  454. selem.MinOccursString = "0";
  455. selem.MaxOccursString = "unbounded";
  456. return selem;
  457. }
  458. else
  459. {
  460. XmlSchemaChoice schoice = new XmlSchemaChoice ();
  461. schoice.MinOccursString = "0";
  462. schoice.MaxOccursString = "unbounded";
  463. foreach (XmlTypeMapElementInfo einfo in infos)
  464. {
  465. if (einfo.IsTextElement) continue;
  466. schoice.Items.Add (GetSchemaElement (currentSchema, einfo, true));
  467. }
  468. return schoice;
  469. }
  470. }
  471. void ExportEnumSchema (XmlTypeMapping map)
  472. {
  473. if (IsMapExported (map)) return;
  474. SetMapExported (map);
  475. XmlSchema schema = GetSchema (map.XmlTypeNamespace);
  476. XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
  477. stype.Name = map.ElementName;
  478. schema.Items.Add (stype);
  479. XmlSchemaSimpleTypeRestriction rest = new XmlSchemaSimpleTypeRestriction ();
  480. rest.BaseTypeName = new XmlQualifiedName ("string",XmlSchema.Namespace);
  481. EnumMap emap = (EnumMap) map.ObjectMap;
  482. foreach (EnumMap.EnumMapMember emem in emap.Members)
  483. {
  484. XmlSchemaEnumerationFacet ef = new XmlSchemaEnumerationFacet ();
  485. ef.Value = emem.XmlName;
  486. rest.Facets.Add (ef);
  487. }
  488. stype.Content = rest;
  489. }
  490. XmlQualifiedName ExportArraySchema (XmlTypeMapping map, string defaultNamespace)
  491. {
  492. ListMap lmap = (ListMap) map.ObjectMap;
  493. if (encodedFormat)
  494. {
  495. string name, ns, schemaNs;
  496. lmap.GetArrayType (-1, out name, out ns);
  497. if (ns == XmlSchema.Namespace) schemaNs = defaultNamespace;
  498. else schemaNs = ns;
  499. if (IsMapExported (map)) return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
  500. SetMapExported (map);
  501. XmlSchema schema = GetSchema (schemaNs);
  502. XmlSchemaComplexType stype = new XmlSchemaComplexType ();
  503. stype.Name = lmap.GetSchemaArrayName ();
  504. schema.Items.Add (stype);
  505. XmlSchemaComplexContent content = new XmlSchemaComplexContent();
  506. content.IsMixed = false;
  507. stype.ContentModel = content;
  508. XmlSchemaComplexContentRestriction rest = new XmlSchemaComplexContentRestriction ();
  509. content.Content = rest;
  510. rest.BaseTypeName = new XmlQualifiedName ("Array", XmlSerializer.EncodingNamespace);
  511. XmlSchemaAttribute at = new XmlSchemaAttribute ();
  512. rest.Attributes.Add (at);
  513. at.RefName = new XmlQualifiedName ("arrayType", XmlSerializer.EncodingNamespace);
  514. XmlAttribute arrayType = Document.CreateAttribute ("arrayType", XmlSerializer.WsdlNamespace);
  515. arrayType.Value = ns + (ns != "" ? ":" : "") + name;
  516. at.UnhandledAttributes = new XmlAttribute [] { arrayType };
  517. ImportNamespace (schema, XmlSerializer.WsdlNamespace);
  518. XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) lmap.ItemInfo[0];
  519. if (einfo.MappedType != null)
  520. {
  521. switch (einfo.TypeData.SchemaType)
  522. {
  523. case SchemaTypes.Enum:
  524. ExportEnumSchema (einfo.MappedType);
  525. break;
  526. case SchemaTypes.Array:
  527. ExportArraySchema (einfo.MappedType, schemaNs);
  528. break;
  529. case SchemaTypes.Class:
  530. ExportClassSchema (einfo.MappedType);
  531. break;
  532. }
  533. }
  534. return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
  535. }
  536. else
  537. {
  538. if (IsMapExported (map)) return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
  539. SetMapExported (map);
  540. XmlSchema schema = GetSchema (map.XmlTypeNamespace);
  541. XmlSchemaComplexType stype = new XmlSchemaComplexType ();
  542. stype.Name = map.ElementName;
  543. schema.Items.Add (stype);
  544. XmlSchemaParticle spart = GetSchemaArrayElement (schema, lmap.ItemInfo);
  545. if (spart is XmlSchemaChoice)
  546. stype.Particle = spart;
  547. else
  548. {
  549. XmlSchemaSequence seq = new XmlSchemaSequence ();
  550. seq.Items.Add (spart);
  551. stype.Particle = seq;
  552. }
  553. return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
  554. }
  555. }
  556. XmlDocument Document
  557. {
  558. get
  559. {
  560. if (xmlDoc == null) xmlDoc = new XmlDocument ();
  561. return xmlDoc;
  562. }
  563. }
  564. bool IsMapExported (XmlTypeMapping map)
  565. {
  566. if (exportedMaps.ContainsKey (GetMapKey(map))) return true;
  567. return false;
  568. }
  569. void SetMapExported (XmlTypeMapping map)
  570. {
  571. exportedMaps [GetMapKey(map)] = map;
  572. }
  573. bool IsElementExported (XmlTypeMapping map)
  574. {
  575. if (exportedElements.ContainsKey (GetMapKey(map))) return true;
  576. if (map.TypeData.Type == typeof(object)) return true;
  577. return false;
  578. }
  579. void SetElementExported (XmlTypeMapping map)
  580. {
  581. exportedElements [GetMapKey(map)] = map;
  582. }
  583. string GetMapKey (XmlTypeMapping map)
  584. {
  585. // Don't use type name for array types, since we can have different
  586. // classes that represent the same array type (for example
  587. // StringCollection and string[]).
  588. if (map.TypeData.IsListType)
  589. return GetArrayKeyName (map.TypeData) + " " + map.XmlType + " " + map.XmlTypeNamespace;
  590. else
  591. return map.TypeData.FullTypeName + " " + map.XmlType + " " + map.XmlTypeNamespace;
  592. }
  593. string GetArrayKeyName (TypeData td)
  594. {
  595. TypeData etd = td.ListItemTypeData;
  596. return "*arrayof*" + (etd.IsListType ? GetArrayKeyName (etd) : etd.FullTypeName);
  597. }
  598. void CompileSchemas ()
  599. {
  600. // foreach (XmlSchema sc in schemas)
  601. // sc.Compile (null);
  602. }
  603. XmlSchema GetSchema (string ns)
  604. {
  605. XmlSchema schema = schemas [ns];
  606. if (schema == null)
  607. {
  608. schema = new XmlSchema ();
  609. schema.TargetNamespace = ns;
  610. if (!encodedFormat)
  611. schema.ElementFormDefault = XmlSchemaForm.Qualified;
  612. schemas.Add (schema);
  613. }
  614. return schema;
  615. }
  616. #endregion // Methods
  617. }
  618. }