| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- //
- // System.Xml.Serialization.XmlSchemaExporter
- //
- // Author:
- // Tim Coleman ([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;
- #endregion
- #region Constructors
- public XmlSchemaExporter (XmlSchemas schemas)
- {
- this.schemas = schemas;
- }
- #endregion // Constructors
- #region Methods
- [MonoTODO]
- public string ExportAnyType (string ns)
- {
- throw new NotImplementedException ();
- }
- public void ExportMembersMapping (XmlMembersMapping xmlMembersMapping)
- {
- exportedMaps = new Hashtable ();
- XmlSchema schema = GetSchema (xmlMembersMapping.Namespace);
- XmlSchemaElement selem = new XmlSchemaElement ();
- selem.Name = xmlMembersMapping.ElementName;
- schema.Items.Add (selem);
- XmlSchemaComplexType stype = new XmlSchemaComplexType ();
- XmlSchemaSequence particle;
- XmlSchemaAnyAttribute anyAttribute;
- ExportMembersMapSchema (schema, (ClassMap)xmlMembersMapping.ObjectMap, null, stype.Attributes, out particle, out anyAttribute);
- stype.Particle = particle;
- stype.AnyAttribute = anyAttribute;
- selem.SchemaType = stype;
- CompileSchemas ();
- }
- [MonoTODO]
- public XmlQualifiedName ExportTypeMapping (XmlMembersMapping xmlMembersMapping)
- {
- throw new NotImplementedException ();
- }
- public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping)
- {
- exportedMaps = new Hashtable ();
- XmlSchema schema = GetSchema (null);
- XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (null, xmlTypeMapping.TypeData);
- einfo.Namespace = "";
- einfo.ElementName = xmlTypeMapping.ElementName;
- einfo.MappedType = xmlTypeMapping;
- einfo.IsNullable = false;
- AddSchemaElement (schema.Items, schema, einfo, false);
- CompileSchemas ();
- }
- void ExportClassSchema (XmlTypeMapping map)
- {
- if (IsMapExported (map)) return;
- SetMapExported (map);
- XmlSchema schema = GetSchema (map.Namespace);
- XmlSchemaComplexType stype = new XmlSchemaComplexType ();
- stype.Name = map.ElementName;
- schema.Items.Add (stype);
- if (map.BaseMap != null)
- {
- XmlSchemaComplexContent cstype = new XmlSchemaComplexContent ();
- cstype.IsMixed = true;
- XmlSchemaComplexContentExtension ext = new XmlSchemaComplexContentExtension ();
- ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.Namespace);
- cstype.Content = ext;
- stype.ContentModel = cstype;
- XmlSchemaSequence particle;
- XmlSchemaAnyAttribute anyAttribute;
- ExportMembersMapSchema (schema, (ClassMap)map.ObjectMap, 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, (ClassMap)map.ObjectMap, map.BaseMap, stype.Attributes, out particle, out anyAttribute);
- stype.Particle = particle;
- stype.AnyAttribute = anyAttribute;
- stype.IsMixed = true;
- }
- }
- 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(XmlTypeMapMemberAnyAttribute))
- {
- // Ignore
- }
- else if (memType == typeof(XmlTypeMapMemberElement))
- {
- XmlSchemaElement selem = (XmlSchemaElement) AddSchemaElement (seq.Items, schema, (XmlTypeMapElementInfo) member.ElementInfo [0], true);
- if (selem != null && member.DefaultValue != System.DBNull.Value)
- selem.DefaultValue = XmlCustomFormatter.ToXmlString (member.TypeData, member.DefaultValue);
- }
- 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)
- 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)
- {
- sat.Name = attinfo.AttributeName;
- if (attinfo.TypeData.SchemaType == SchemaTypes.Enum)
- {
- 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)
- {
- 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)
- selem.MinOccurs = 1;
- }
- XmlSchema memberSchema = GetSchema (einfo.Namespace);
- ImportNamespace (currentSchema, einfo.Namespace);
- if (currentSchema == memberSchema)
- {
- if (isTypeMember) selem.IsNillable = einfo.IsNullable;
- selem.Name = einfo.ElementName;
- XmlQualifiedName typeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);
- 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.Namespace);
- ImportNamespace (currentSchema, einfo.MappedType.Namespace);
- ExportEnumSchema (einfo.MappedType);
- break;
- case SchemaTypes.Array:
- selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.Namespace);;
- ImportNamespace (currentSchema, einfo.MappedType.Namespace);
- ExportArraySchema (einfo.MappedType);
- break;
- case SchemaTypes.Class:
- if (einfo.MappedType.TypeData.Type != typeof(object)) {
- selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.Namespace);;
- ImportNamespace (currentSchema, einfo.MappedType.Namespace);
- ExportClassSchema (einfo.MappedType);
- }
- 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, false);
- }
- return selem;
- }
- void ImportNamespace (XmlSchema schema, string ns)
- {
- if (ns == "" || ns == schema.TargetNamespace) 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, XmlTypeMapMemberElement 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);
- if (selem.MinOccursString == string.Empty) selem.MinOccursString = "0";
- if (selem.MaxOccursString == string.Empty) 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;
- }
- void ExportArraySchema (XmlTypeMapping map)
- {
- if (IsMapExported (map)) return;
- SetMapExported (map);
- XmlSchema schema = GetSchema (map.Namespace);
- XmlSchemaComplexType stype = new XmlSchemaComplexType ();
- stype.IsMixed = true;
- stype.Name = map.ElementName;
- schema.Items.Add (stype);
- ListMap lmap = (ListMap) map.ObjectMap;
- XmlSchemaSequence seq = new XmlSchemaSequence ();
- XmlSchemaParticle spart = AddSchemaArrayElement (seq.Items, schema, lmap.ItemInfo);
- if (spart is XmlSchemaChoice)
- stype.Particle = spart;
- else
- stype.Particle = seq;
- }
- bool IsMapExported (XmlTypeMapping map)
- {
- if (exportedMaps.Contains (map)) return true;
- if (map.TypeData.Type == typeof(object)) return true;
- return false;
- }
- void SetMapExported (XmlTypeMapping map)
- {
- exportedMaps.Add (map,map);
- }
- 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;
- schema.ElementFormDefault = XmlSchemaForm.Qualified;
- schemas.Add (schema);
- }
- return schema;
- }
- #endregion // Methods
- }
- }
|