| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623 |
- //
- // System.Xml.Serialization.XmlSchemaExporter
- //
- // Author:
- // Tim Coleman ([email protected])
- // Lluis Sanchez Gual ([email protected])
- //
- // Copyright (C) Tim Coleman, 2002
- //
- using System.Xml;
- using System.Xml.Schema;
- using System.Collections;
- namespace System.Xml.Serialization {
- public class XmlSchemaExporter {
- #region Fields
- XmlSchemas schemas;
- Hashtable exportedMaps = new Hashtable();
- Hashtable exportedElements = new Hashtable();
- bool encodedFormat = false;
- XmlDocument xmlDoc;
-
- #endregion
- #region Constructors
- public XmlSchemaExporter (XmlSchemas schemas)
- {
- this.schemas = schemas;
- }
- internal XmlSchemaExporter (XmlSchemas schemas, bool encodedFormat)
- {
- this.encodedFormat = encodedFormat;
- this.schemas = schemas;
- }
- #endregion // Constructors
- #region Methods
- [MonoTODO]
- public string ExportAnyType (string ns)
- {
- throw new NotImplementedException ();
- }
- public void ExportMembersMapping (XmlMembersMapping xmlMembersMapping)
- {
- ExportMembersMapping (xmlMembersMapping, true);
- }
-
- internal void ExportMembersMapping (XmlMembersMapping xmlMembersMapping, bool exportEnclosingType)
- {
- XmlSchema schema = GetSchema (xmlMembersMapping.Namespace);
- ClassMap cmap = (ClassMap) xmlMembersMapping.ObjectMap;
- if (xmlMembersMapping.HasWrapperElement && exportEnclosingType)
- {
- XmlSchemaComplexType stype = new XmlSchemaComplexType ();
-
- XmlSchemaSequence particle;
- XmlSchemaAnyAttribute anyAttribute;
- ExportMembersMapSchema (schema, cmap, null, stype.Attributes, out particle, out anyAttribute);
- stype.Particle = particle;
- stype.AnyAttribute = anyAttribute;
-
- if (encodedFormat)
- {
- stype.Name = xmlMembersMapping.ElementName;
- schema.Items.Add (stype);
- }
- else
- {
- XmlSchemaElement selem = new XmlSchemaElement ();
- selem.Name = xmlMembersMapping.ElementName;
- selem.SchemaType = stype;
- schema.Items.Add (selem);
- }
- }
- else
- {
- ICollection members = cmap.ElementMembers;
- if (members != null)
- {
- XmlSchemaObjectCollection itemsCol = schema.Items;
-
- // In encoded format, the schema elements are not needed
- if (encodedFormat) itemsCol = new XmlSchemaObjectCollection ();
-
- foreach (XmlTypeMapMemberElement member in members)
- {
- Type memType = member.GetType();
- if (member is XmlTypeMapMemberFlatList)
- throw new InvalidOperationException ("Unwrapped arrays not supported as parameters");
- else if (memType == typeof(XmlTypeMapMemberElement))
- AddSchemaElement (itemsCol, schema, (XmlTypeMapElementInfo) member.ElementInfo [0], member.DefaultValue, false);
- else
- AddSchemaElement (itemsCol, schema, (XmlTypeMapElementInfo) member.ElementInfo [0], false);
- }
- }
- }
-
- if (encodedFormat)
- ImportNamespace (schema, XmlSerializer.EncodingNamespace);
-
- CompileSchemas ();
- }
- [MonoTODO]
- public XmlQualifiedName ExportTypeMapping (XmlMembersMapping xmlMembersMapping)
- {
- throw new NotImplementedException ();
- }
- public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping)
- {
- if (!xmlTypeMapping.IncludeInSchema) return;
- if (IsElementExported (xmlTypeMapping)) return;
-
- if (encodedFormat)
- {
- ExportClassSchema (xmlTypeMapping);
- XmlSchema schema = GetSchema (xmlTypeMapping.XmlTypeNamespace);
- ImportNamespace (schema, XmlSerializer.EncodingNamespace);
- }
- else
- {
- XmlSchema schema = GetSchema (xmlTypeMapping.Namespace);
- XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (null, xmlTypeMapping.TypeData);
- einfo.Namespace = xmlTypeMapping.Namespace;
- einfo.ElementName = xmlTypeMapping.ElementName;
- if (xmlTypeMapping.TypeData.IsComplexType)
- einfo.MappedType = xmlTypeMapping;
- einfo.IsNullable = false;
- AddSchemaElement (schema.Items, schema, einfo, false);
- SetElementExported (xmlTypeMapping);
- }
-
- CompileSchemas ();
- }
- void ExportClassSchema (XmlTypeMapping map)
- {
- if (IsMapExported (map)) return;
- SetMapExported (map);
- XmlSchema schema = GetSchema (map.XmlTypeNamespace);
- XmlSchemaComplexType stype = new XmlSchemaComplexType ();
- stype.Name = map.XmlType;
- schema.Items.Add (stype);
- ClassMap cmap = (ClassMap)map.ObjectMap;
- if (cmap.HasSimpleContent)
- {
- XmlSchemaSimpleContent simple = new XmlSchemaSimpleContent ();
- stype.ContentModel = simple;
- XmlSchemaSimpleContentExtension ext = new XmlSchemaSimpleContentExtension ();
- simple.Content = ext;
- XmlSchemaSequence particle;
- XmlSchemaAnyAttribute anyAttribute;
- ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
- ext.AnyAttribute = anyAttribute;
- if (map.BaseMap == null)
- ext.BaseTypeName = cmap.SimpleContentBaseType;
- else
- ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
- }
- else if (map.BaseMap != null && map.BaseMap.IncludeInSchema)
- {
- XmlSchemaComplexContent cstype = new XmlSchemaComplexContent ();
- XmlSchemaComplexContentExtension ext = new XmlSchemaComplexContentExtension ();
- ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
- cstype.Content = ext;
- stype.ContentModel = cstype;
- XmlSchemaSequence particle;
- XmlSchemaAnyAttribute anyAttribute;
- ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
- ext.Particle = particle;
- ext.AnyAttribute = anyAttribute;
- ImportNamespace (schema, map.BaseMap.Namespace);
- ExportClassSchema (map.BaseMap);
- }
- else
- {
- XmlSchemaSequence particle;
- XmlSchemaAnyAttribute anyAttribute;
- ExportMembersMapSchema (schema, cmap, map.BaseMap, stype.Attributes, out particle, out anyAttribute);
- stype.Particle = particle;
- stype.AnyAttribute = anyAttribute;
- stype.IsMixed = cmap.XmlTextCollector != null;
- }
-
- foreach (XmlTypeMapping dmap in map.DerivedTypes)
- if (dmap.TypeData.SchemaType == SchemaTypes.Class) ExportClassSchema (dmap);
- }
- void ExportMembersMapSchema (XmlSchema schema, ClassMap map, XmlTypeMapping baseMap, XmlSchemaObjectCollection outAttributes, out XmlSchemaSequence particle, out XmlSchemaAnyAttribute anyAttribute)
- {
- particle = null;
- XmlSchemaSequence seq = new XmlSchemaSequence ();
- ICollection members = map.ElementMembers;
- if (members != null)
- {
- foreach (XmlTypeMapMemberElement member in members)
- {
- if (baseMap != null && DefinedInBaseMap (baseMap, member)) continue;
- Type memType = member.GetType();
- if (memType == typeof(XmlTypeMapMemberFlatList))
- {
- AddSchemaArrayElement (seq.Items, schema, member.ElementInfo);
- }
- else if (memType == typeof(XmlTypeMapMemberAnyElement))
- {
- AddSchemaArrayElement (seq.Items, schema, member.ElementInfo);
- }
- else if (memType == typeof(XmlTypeMapMemberElement))
- {
- XmlSchemaElement selem = (XmlSchemaElement) AddSchemaElement (seq.Items, schema, (XmlTypeMapElementInfo) member.ElementInfo [0], member.DefaultValue, true);
- }
- else
- {
- AddSchemaElement (seq.Items, schema, (XmlTypeMapElementInfo) member.ElementInfo [0], true);
- }
- }
- }
- if (seq.Items.Count > 0)
- particle = seq;
- // Write attributes
- ICollection attributes = map.AttributeMembers;
- if (attributes != null)
- {
- foreach (XmlTypeMapMemberAttribute attr in attributes) {
- if (baseMap != null && DefinedInBaseMap (baseMap, attr)) continue;
- outAttributes.Add (GetSchemaAttribute (schema, attr));
- }
- }
- XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
- if (anyAttrMember != null)
- anyAttribute = new XmlSchemaAnyAttribute ();
- else
- anyAttribute = null;
- }
- XmlSchemaAttribute GetSchemaAttribute (XmlSchema currentSchema, XmlTypeMapMemberAttribute attinfo)
- {
- XmlSchemaAttribute sat = new XmlSchemaAttribute ();
- if (attinfo.DefaultValue != System.DBNull.Value) sat.DefaultValue = XmlCustomFormatter.ToXmlString (attinfo.TypeData, attinfo.DefaultValue);
- ImportNamespace (currentSchema, attinfo.Namespace);
- XmlSchema memberSchema = GetSchema (attinfo.Namespace);
- if (currentSchema == memberSchema || encodedFormat)
- {
- sat.Name = attinfo.AttributeName;
- if (attinfo.TypeData.SchemaType == SchemaTypes.Enum)
- {
- ImportNamespace (currentSchema, attinfo.DataTypeNamespace);
- ExportEnumSchema (attinfo.MappedType);
- sat.SchemaTypeName = new XmlQualifiedName (attinfo.TypeData.XmlType, attinfo.DataTypeNamespace);;
- }
- else if (attinfo.TypeData.SchemaType == SchemaTypes.Array && TypeTranslator.IsPrimitive (attinfo.TypeData.ListItemType))
- {
- sat.SchemaType = GetSchemaSimpleListType (attinfo.TypeData);
- }
- else
- sat.SchemaTypeName = new XmlQualifiedName (attinfo.TypeData.XmlType, attinfo.DataTypeNamespace);;
- }
- else
- {
- sat.RefName = new XmlQualifiedName (attinfo.AttributeName, attinfo.Namespace);
- memberSchema.Items.Add (GetSchemaAttribute (memberSchema, attinfo));
- }
- return sat;
- }
- XmlSchemaParticle AddSchemaElement (XmlSchemaObjectCollection destcol, XmlSchema currentSchema, XmlTypeMapElementInfo einfo, bool isTypeMember)
- {
- return AddSchemaElement (destcol, currentSchema, einfo, System.DBNull.Value, isTypeMember);
- }
-
- XmlSchemaParticle AddSchemaElement (XmlSchemaObjectCollection destcol, XmlSchema currentSchema, XmlTypeMapElementInfo einfo, object defaultValue, bool isTypeMember)
- {
- if (einfo.IsTextElement) return null;
- if (einfo.IsUnnamedAnyElement)
- {
- XmlSchemaAny any = new XmlSchemaAny ();
- any.MinOccurs = 0;
- any.MaxOccurs = 1;
- destcol.Add (any);
- return any;
- }
-
- XmlSchemaElement selem = new XmlSchemaElement ();
- destcol.Add (selem);
- if (isTypeMember)
- {
- selem.MaxOccurs = 1;
- selem.MinOccurs = einfo.IsNullable ? 1 : 0;
-
- if ((einfo.TypeData.Type.IsPrimitive && einfo.TypeData.Type != typeof(string)) ||
- einfo.TypeData.Type.IsEnum || encodedFormat)
- selem.MinOccurs = 1;
- }
- XmlSchema memberSchema = null;
-
- if (!encodedFormat)
- {
- memberSchema = GetSchema (einfo.Namespace);
- ImportNamespace (currentSchema, einfo.Namespace);
- }
- if (currentSchema == memberSchema || encodedFormat)
- {
- if (isTypeMember) selem.IsNillable = einfo.IsNullable;
- selem.Name = einfo.ElementName;
- XmlQualifiedName typeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);
- if (defaultValue != System.DBNull.Value)
- selem.DefaultValue = XmlCustomFormatter.ToXmlString (einfo.TypeData, defaultValue);
- switch (einfo.TypeData.SchemaType)
- {
- case SchemaTypes.XmlNode:
- selem.SchemaType = GetSchemaXmlNodeType ();
- break;
- case SchemaTypes.XmlSerializable:
- selem.SchemaType = GetSchemaXmlSerializableType ();
- break;
- case SchemaTypes.Enum:
- selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
- ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
- ExportEnumSchema (einfo.MappedType);
- break;
- case SchemaTypes.Array:
- XmlQualifiedName atypeName = ExportArraySchema (einfo.MappedType, currentSchema.TargetNamespace);
- selem.SchemaTypeName = atypeName;
- ImportNamespace (currentSchema, atypeName.Namespace);
- break;
- case SchemaTypes.Class:
- if (einfo.MappedType.TypeData.Type != typeof(object)) {
- selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
- ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
- ExportClassSchema (einfo.MappedType);
- }
- else if (encodedFormat)
- selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
- break;
- case SchemaTypes.Primitive:
- selem.SchemaTypeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);;
- break;
- }
- }
- else
- {
- selem.RefName = new XmlQualifiedName (einfo.ElementName, einfo.Namespace);
- AddSchemaElement (memberSchema.Items, memberSchema, einfo, defaultValue, false);
- }
- return selem;
- }
- void ImportNamespace (XmlSchema schema, string ns)
- {
- if (ns == "" || ns == schema.TargetNamespace || ns == XmlSchema.Namespace) return;
- foreach (XmlSchemaObject sob in schema.Includes)
- if ((sob is XmlSchemaImport) && ((XmlSchemaImport)sob).Namespace == ns) return;
- XmlSchemaImport imp = new XmlSchemaImport ();
- imp.Namespace = ns;
- schema.Includes.Add (imp);
- }
- bool DefinedInBaseMap (XmlTypeMapping map, XmlTypeMapMember member)
- {
- if (((ClassMap)map.ObjectMap).FindMember (member.Name) != null)
- return true;
- else if (map.BaseMap != null)
- return DefinedInBaseMap (map.BaseMap, member);
- else
- return false;
- }
- XmlSchemaType GetSchemaXmlNodeType ()
- {
- XmlSchemaComplexType stype = new XmlSchemaComplexType ();
- stype.IsMixed = true;
- XmlSchemaSequence seq = new XmlSchemaSequence ();
- seq.Items.Add (new XmlSchemaAny ());
- stype.Particle = seq;
- return stype;
- }
- XmlSchemaType GetSchemaXmlSerializableType ()
- {
- XmlSchemaComplexType stype = new XmlSchemaComplexType ();
- XmlSchemaSequence seq = new XmlSchemaSequence ();
- XmlSchemaElement selem = new XmlSchemaElement ();
- selem.RefName = new XmlQualifiedName ("schema",XmlSchema.Namespace);
- seq.Items.Add (selem);
- seq.Items.Add (new XmlSchemaAny ());
- stype.Particle = seq;
- return stype;
- }
- XmlSchemaSimpleType GetSchemaSimpleListType (TypeData typeData)
- {
- XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
- XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList ();
- TypeData itemTypeData = TypeTranslator.GetTypeData (typeData.ListItemType);
- list.ItemTypeName = new XmlQualifiedName (itemTypeData.XmlType, XmlSchema.Namespace);
- stype.Content = list;
- return stype;
- }
- XmlSchemaParticle AddSchemaArrayElement (XmlSchemaObjectCollection destcol, XmlSchema currentSchema, XmlTypeMapElementInfoList infos)
- {
- int numInfos = infos.Count;
- if (numInfos > 0 && ((XmlTypeMapElementInfo)infos[0]).IsTextElement) numInfos--;
- if (numInfos == 0) return null;
- if (numInfos == 1)
- {
- XmlSchemaParticle selem = AddSchemaElement (destcol, currentSchema, (XmlTypeMapElementInfo) infos[infos.Count-1], true);
- selem.MinOccursString = "0";
- selem.MaxOccursString = "unbounded";
- return selem;
- }
- else
- {
- XmlSchemaChoice schoice = new XmlSchemaChoice ();
- destcol.Add (schoice);
- schoice.MinOccursString = "0";
- schoice.MaxOccursString = "unbounded";
- foreach (XmlTypeMapElementInfo einfo in infos)
- {
- if (einfo.IsTextElement) continue;
- AddSchemaElement (schoice.Items, currentSchema, einfo, true);
- }
- return schoice;
- }
- }
- void ExportEnumSchema (XmlTypeMapping map)
- {
- if (IsMapExported (map)) return;
- SetMapExported (map);
- XmlSchema schema = GetSchema (map.Namespace);
- XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
- stype.Name = map.ElementName;
- schema.Items.Add (stype);
- XmlSchemaSimpleTypeRestriction rest = new XmlSchemaSimpleTypeRestriction ();
- rest.BaseTypeName = new XmlQualifiedName ("string",XmlSchema.Namespace);
- EnumMap emap = (EnumMap) map.ObjectMap;
- foreach (EnumMap.EnumMapMember emem in emap.Members)
- {
- XmlSchemaEnumerationFacet ef = new XmlSchemaEnumerationFacet ();
- ef.Value = emem.XmlName;
- rest.Facets.Add (ef);
- }
- stype.Content = rest;
- }
- XmlQualifiedName ExportArraySchema (XmlTypeMapping map, string defaultNamespace)
- {
- ListMap lmap = (ListMap) map.ObjectMap;
- if (encodedFormat)
- {
- string name, ns, schemaNs;
- lmap.GetArrayType (-1, out name, out ns);
- if (ns == XmlSchema.Namespace) schemaNs = defaultNamespace;
- else schemaNs = ns;
- if (IsMapExported (map)) return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
- SetMapExported (map);
- XmlSchema schema = GetSchema (schemaNs);
- XmlSchemaComplexType stype = new XmlSchemaComplexType ();
- stype.Name = lmap.GetSchemaArrayName ();
- schema.Items.Add (stype);
-
- XmlSchemaComplexContent content = new XmlSchemaComplexContent();
- content.IsMixed = false;
- stype.ContentModel = content;
-
- XmlSchemaComplexContentRestriction rest = new XmlSchemaComplexContentRestriction ();
- content.Content = rest;
- rest.BaseTypeName = new XmlQualifiedName ("Array", XmlSerializer.EncodingNamespace);
- XmlSchemaAttribute at = new XmlSchemaAttribute ();
- rest.Attributes.Add (at);
- at.RefName = new XmlQualifiedName ("arrayType", XmlSerializer.EncodingNamespace);
-
- XmlAttribute arrayType = Document.CreateAttribute ("arrayType", XmlSerializer.WsdlNamespace);
- arrayType.Value = ns + (ns != "" ? ":" : "") + name;
- at.UnhandledAttributes = new XmlAttribute [] { arrayType };
- ImportNamespace (schema, XmlSerializer.WsdlNamespace);
-
- XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) lmap.ItemInfo[0];
- if (einfo.MappedType != null)
- {
- switch (einfo.TypeData.SchemaType)
- {
- case SchemaTypes.Enum:
- ExportEnumSchema (einfo.MappedType);
- break;
- case SchemaTypes.Array:
- ExportArraySchema (einfo.MappedType, schemaNs);
- break;
- case SchemaTypes.Class:
- if (einfo.MappedType.TypeData.Type != typeof(object))
- ExportClassSchema (einfo.MappedType);
- break;
- }
- }
-
- return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
- }
- else
- {
- if (IsMapExported (map)) return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
-
- SetMapExported (map);
- XmlSchema schema = GetSchema (map.Namespace);
- XmlSchemaComplexType stype = new XmlSchemaComplexType ();
- stype.Name = map.ElementName;
- schema.Items.Add (stype);
- XmlSchemaSequence seq = new XmlSchemaSequence ();
- XmlSchemaParticle spart = AddSchemaArrayElement (seq.Items, schema, lmap.ItemInfo);
- if (spart is XmlSchemaChoice)
- stype.Particle = spart;
- else
- stype.Particle = seq;
-
- return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
- }
- }
-
- XmlDocument Document
- {
- get
- {
- if (xmlDoc == null) xmlDoc = new XmlDocument ();
- return xmlDoc;
- }
- }
- bool IsMapExported (XmlTypeMapping map)
- {
- if (exportedMaps.ContainsKey (GetMapKey(map))) return true;
- if (map.TypeData.Type == typeof(object)) return true;
- return false;
- }
- void SetMapExported (XmlTypeMapping map)
- {
- exportedMaps [GetMapKey(map)] = map;
- }
- bool IsElementExported (XmlTypeMapping map)
- {
- if (exportedElements.ContainsKey (GetMapKey(map))) return true;
- if (map.TypeData.Type == typeof(object)) return true;
- return false;
- }
- void SetElementExported (XmlTypeMapping map)
- {
- exportedElements [GetMapKey(map)] = map;
- }
-
- string GetMapKey (XmlTypeMapping map)
- {
- return map.TypeData.FullTypeName + " " + map.Namespace;
- }
- void CompileSchemas ()
- {
- // foreach (XmlSchema sc in schemas)
- // sc.Compile (null);
- }
- XmlSchema GetSchema (string ns)
- {
- XmlSchema schema = schemas [ns];
- if (schema == null)
- {
- schema = new XmlSchema ();
- schema.TargetNamespace = ns;
- if (!encodedFormat)
- schema.ElementFormDefault = XmlSchemaForm.Qualified;
- schemas.Add (schema);
- }
- return schema;
- }
- #endregion // Methods
- }
- }
|