\r
using System.CodeDom;\r
using System.Collections;\r
+using System.Xml.Schema;\r
\r
namespace System.Xml.Serialization {\r
public class XmlCodeExporter {\r
CodeCompileUnit codeCompileUnit;\r
CodeAttributeDeclarationCollection includeMetadata;\r
\r
- Hashtable exportedMaps;\r
+ Hashtable exportedMaps = new Hashtable ();\r
\r
#endregion\r
\r
throw new NotImplementedException ();\r
}\r
\r
- [MonoTODO]\r
public void ExportMembersMapping (XmlMembersMapping xmlMembersMapping)\r
{\r
- throw new NotImplementedException ();\r
+ CodeTypeDeclaration dummyClass = new CodeTypeDeclaration ();\r
+ ExportMembersMapCode (dummyClass, (ClassMap)xmlMembersMapping.ObjectMap, xmlMembersMapping.Namespace, null);\r
}\r
\r
public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping)\r
{\r
- exportedMaps = new Hashtable ();\r
ExportMapCode (xmlTypeMapping, true);\r
}\r
\r
CodeTypeDeclaration codeClass = new CodeTypeDeclaration (map.TypeData.TypeName);\r
codeClass.Attributes = MemberAttributes.Public;\r
\r
- CodeAttributeDeclaration att = new CodeAttributeDeclaration (isRoot ? "XmlRoot" : "XmlTypeAttribute");\r
- if (map.ElementName != map.TypeData.TypeName) att.Arguments.Add (GetArg ("Name", map.ElementName));\r
- if (map.Namespace != "") att.Arguments.Add (GetArg ("Namespace", map.Namespace));\r
+ CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlType");\r
+ if (map.XmlType != map.TypeData.TypeName) att.Arguments.Add (GetArg (map.XmlType));\r
+ if (map.XmlTypeNamespace != "") att.Arguments.Add (GetArg ("Namespace", map.XmlTypeNamespace));\r
AddCustomAttribute (codeClass, att, false);\r
\r
+ if (isRoot) {\r
+ CodeAttributeDeclaration ratt = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlRoot");\r
+ if (map.ElementName != map.TypeData.TypeName) ratt.Arguments.Add (GetArg (map.ElementName));\r
+ if (map.Namespace != "") ratt.Arguments.Add (GetArg ("Namespace", map.Namespace));\r
+ AddCustomAttribute (codeClass, ratt, false);\r
+ }\r
+ \r
if (map.BaseMap != null)\r
{\r
CodeTypeReference ctr = new CodeTypeReference (map.BaseMap.TypeData.FullTypeName);\r
codeClass.BaseTypes.Add (ctr);\r
+ ExportMapCode (map.BaseMap, false);\r
}\r
\r
foreach (XmlTypeMapping tm in map.DerivedTypes)\r
{\r
- CodeAttributeDeclaration iatt = new CodeAttributeDeclaration ("XmlInclude");\r
+ CodeAttributeDeclaration iatt = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlInclude");\r
iatt.Arguments.Add (new CodeAttributeArgument (new CodeTypeOfExpression(tm.TypeData.FullTypeName)));\r
AddCustomAttribute (codeClass, iatt, true);\r
+ ExportMapCode (tm, false);\r
}\r
\r
AddCodeType (codeClass);\r
ICollection attributes = map.AttributeMembers;\r
if (attributes != null)\r
{\r
- foreach (XmlTypeMapMemberAttribute attr in attributes)\r
+ foreach (XmlTypeMapMemberAttribute attr in attributes) {\r
+ if (baseMap != null && DefinedInBaseMap (baseMap, attr)) continue;\r
AddAttributeFieldMember (codeClass, attr, defaultNamespace);\r
+ }\r
}\r
\r
XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;\r
if (anyAttrMember != null)\r
{\r
CodeMemberField codeField = new CodeMemberField (anyAttrMember.TypeData.FullTypeName, anyAttrMember.Name);\r
+ codeField.Comments.Add (new CodeCommentStatement ("<remarks/>", true));\r
codeField.Attributes = MemberAttributes.Public;\r
- AddCustomAttribute (codeField, "XmlAnyAttribute");\r
+ AddCustomAttribute (codeField, "System.Xml.Serialization.XmlAnyAttribute");\r
codeClass.Members.Add (codeField);\r
}\r
}\r
{\r
CodeMemberField codeField = new CodeMemberField (type, name);\r
codeField.Attributes = MemberAttributes.Public;\r
+ codeField.Comments.Add (new CodeCommentStatement ("<remarks/>", true));\r
\r
if (defaultValue != System.DBNull.Value)\r
{\r
CodeMemberField codeField = CreateFieldMember (attinfo.TypeData.FullTypeName, attinfo.Name, attinfo.DefaultValue);\r
codeClass.Members.Add (codeField);\r
\r
- CodeAttributeDeclaration att = new CodeAttributeDeclaration ("XmlAttribute");\r
- if (attinfo.Name != attinfo.AttributeName) att.Arguments.Add (GetArg ("Name", attinfo.AttributeName));\r
+ CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlAttribute");\r
+ if (attinfo.Name != attinfo.AttributeName) att.Arguments.Add (GetArg (attinfo.AttributeName));\r
if (attinfo.Namespace != defaultNamespace) att.Arguments.Add (GetArg ("Namespace", attinfo.Namespace));\r
+ if (attinfo.Form != XmlSchemaForm.None) att.Arguments.Add (GetArg ("Form",attinfo.Form));\r
AddCustomAttribute (codeField, att, true);\r
\r
if (attinfo.MappedType != null)\r
\r
void AddElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)\r
{\r
+ if (member.TypeData == null) Console.WriteLine ("NN:" + member.Name);\r
CodeMemberField codeField = CreateFieldMember (member.TypeData.FullTypeName, member.Name, member.DefaultValue);\r
codeClass.Members.Add (codeField);\r
TypeData defaultType = member.TypeData;\r
\r
foreach (XmlTypeMapElementInfo einfo in member.ElementInfo)\r
{\r
- if (einfo.IsTextElement) {\r
- CodeAttributeDeclaration uatt = new CodeAttributeDeclaration ("XmlText");\r
- if (einfo.TypeData.FullTypeName != defaultType.FullTypeName) uatt.Arguments.Add (GetTypeArg ("Type", einfo.TypeData.FullTypeName));\r
- AddCustomAttribute (codeField, uatt, true);\r
- continue;\r
- }\r
-\r
- if (einfo.IsUnnamedAnyElement) {\r
- CodeAttributeDeclaration uatt = new CodeAttributeDeclaration ("XmlAnyElement");\r
- if (einfo.Namespace != defaultNamespace) uatt.Arguments.Add (GetArg ("Namespace", einfo.Namespace));\r
- AddCustomAttribute (codeField, uatt, true);\r
+ if (ExportExtraElementAttributes (codeField, einfo, defaultNamespace, defaultType))\r
continue;\r
- }\r
\r
- CodeAttributeDeclaration att = new CodeAttributeDeclaration ("XmlElement");\r
- if (einfo.ElementName != member.Name) att.Arguments.Add (GetArg ("ElementName", einfo.ElementName));\r
+ CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlElement");\r
+ if (einfo.ElementName != member.Name) att.Arguments.Add (GetArg (einfo.ElementName));\r
if (einfo.TypeData.FullTypeName != defaultType.FullTypeName) att.Arguments.Add (GetTypeArg ("Type", einfo.TypeData.FullTypeName));\r
if (einfo.Namespace != defaultNamespace) att.Arguments.Add (GetArg ("Namespace", einfo.Namespace));\r
if (einfo.IsNullable) att.Arguments.Add (GetArg ("IsNullable", true));\r
\r
if (einfo.MappedType != null) ExportMapCode (einfo.MappedType, false);\r
}\r
+\r
+ if (member.ChoiceMember != null)\r
+ AddCustomAttribute (codeField, "System.Xml.Serialization.XmlChoiceIdentifier", GetArg(member.ChoiceMember));\r
}\r
\r
void AddAnyElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)\r
\r
foreach (XmlTypeMapElementInfo einfo in member.ElementInfo)\r
{\r
- CodeAttributeDeclaration att = new CodeAttributeDeclaration ("XmlAnyElement");\r
- if (!einfo.IsUnnamedAnyElement) att.Arguments.Add (GetArg ("Name", einfo.ElementName));\r
- if (einfo.Namespace != defaultNamespace) att.Arguments.Add (GetArg ("Namespace", einfo.Namespace));\r
- AddCustomAttribute (codeField, att, true);\r
+ ExportExtraElementAttributes (codeField, einfo, defaultNamespace, einfo.TypeData);\r
}\r
}\r
\r
- bool DefinedInBaseMap (XmlTypeMapping map, XmlTypeMapMemberElement member)\r
+ bool DefinedInBaseMap (XmlTypeMapping map, XmlTypeMapMember member)\r
{\r
if (((ClassMap)map.ObjectMap).FindMember (member.Name) != null)\r
return true;\r
void AddArrayElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberList member, string defaultNamespace)\r
{\r
CodeMemberField codeField = new CodeMemberField (member.TypeData.FullTypeName, member.Name);\r
+ codeField.Comments.Add (new CodeCommentStatement ("<remarks/>", true));\r
codeField.Attributes = MemberAttributes.Public;\r
codeClass.Members.Add (codeField);\r
XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) member.ElementInfo[0];\r
\r
- CodeAttributeDeclaration att = new CodeAttributeDeclaration ("XmlArray");\r
+ CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlArray");\r
if (einfo.ElementName != member.Name) att.Arguments.Add (GetArg ("ElementName", einfo.ElementName));\r
if (einfo.Namespace != defaultNamespace) att.Arguments.Add (GetArg ("Namespace", einfo.Namespace));\r
if (einfo.IsNullable) att.Arguments.Add (GetArg ("IsNullable", true));\r
bool needsType = (listMap.ItemInfo.Count > 1) ||\r
(ainfo.TypeData.FullTypeName != type.FullTypeName && !listMap.IsMultiArray);\r
\r
- CodeAttributeDeclaration att = new CodeAttributeDeclaration ("XmlArrayItem");\r
+ CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlArrayItem");\r
if (ainfo.ElementName != defaultName) att.Arguments.Add (GetArg ("ElementName", ainfo.ElementName));\r
- if (ainfo.Namespace != defaultNamespace) att.Arguments.Add (GetArg ("Namespace", ainfo.Namespace));\r
+ if (ainfo.Namespace != defaultNamespace && ainfo.Namespace != XmlSchema.Namespace) att.Arguments.Add (GetArg ("Namespace", ainfo.Namespace));\r
if (needsType) att.Arguments.Add (GetTypeArg ("Type", ainfo.TypeData.FullTypeName));\r
if (ainfo.IsNullable) att.Arguments.Add (GetArg ("IsNullable", true));\r
if (att.Arguments.Count > 0 && nestingLevel > 0) att.Arguments.Add (GetArg ("NestingLevel", nestingLevel));\r
if (ainfo.MappedType != null) ExportMapCode (ainfo.MappedType, false);\r
}\r
}\r
- \r
+\r
+ bool ExportExtraElementAttributes (CodeMemberField codeField, XmlTypeMapElementInfo einfo, string defaultNamespace, TypeData defaultType)\r
+ {\r
+ if (einfo.IsTextElement) {\r
+ CodeAttributeDeclaration uatt = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlText");\r
+ if (einfo.TypeData.FullTypeName != defaultType.FullTypeName) uatt.Arguments.Add (GetTypeArg ("Type", einfo.TypeData.FullTypeName));\r
+ AddCustomAttribute (codeField, uatt, true);\r
+ return true;\r
+ }\r
+ else if (einfo.IsUnnamedAnyElement) {\r
+ CodeAttributeDeclaration uatt = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlAnyElement");\r
+ if (!einfo.IsUnnamedAnyElement) uatt.Arguments.Add (GetArg ("Name", einfo.ElementName));\r
+ if (einfo.Namespace != defaultNamespace) uatt.Arguments.Add (GetArg ("Namespace", einfo.Namespace));\r
+ AddCustomAttribute (codeField, uatt, true);\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
void ExportEnumCode (XmlTypeMapping map)\r
{\r
if (IsMapExported (map)) return;\r
codeEnum.IsEnum = true;\r
AddCodeType (codeEnum);\r
\r
- CodeAttributeDeclaration att = new CodeAttributeDeclaration ("XmlTypeAttribute");\r
+ CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlTypeAttribute");\r
if (map.ElementName != map.TypeData.TypeName) att.Arguments.Add (GetArg ("Name", map.ElementName));\r
if (map.Namespace != "") att.Arguments.Add (GetArg ("Namespace", map.Namespace));\r
AddCustomAttribute (codeEnum, att, false);\r
foreach (EnumMap.EnumMapMember emem in emap.Members)\r
{\r
CodeMemberField codeField = new CodeMemberField ("", emem.EnumName);\r
+ codeField.Comments.Add (new CodeCommentStatement ("<remarks/>", true));\r
+\r
if (emem.EnumName != emem.XmlName)\r
{\r
- CodeAttributeDeclaration xatt = new CodeAttributeDeclaration ("XmlEnum");\r
+ CodeAttributeDeclaration xatt = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlEnum");\r
xatt.Arguments.Add (GetArg ("Name", emem.XmlName));\r
+\r
AddCustomAttribute (codeField, xatt, true);\r
}\r
codeEnum.Members.Add (codeField);\r
\r
void AddCodeType (CodeTypeDeclaration type)\r
{\r
+ type.Comments.Add (new CodeCommentStatement ("<remarks/>", true));\r
codeNamespace.Types.Add (type);\r
}\r
\r
// \r
-// System.Xml.Serialization.XmlSchemaImporter \r
+// System.Xml.Serialization.XmlSchemaImporter\r
//\r
// Author:\r
// Tim Coleman (tim@timcoleman.com)\r
//\r
\r
using System.Xml;\r
+using System.Xml.Schema;\r
+using System.Collections;\r
\r
namespace System.Xml.Serialization {\r
public class XmlSchemaImporter {\r
\r
XmlSchemas schemas;\r
CodeIdentifiers typeIdentifiers;\r
+ CodeIdentifiers elemIdentifiers = new CodeIdentifiers ();\r
+ Hashtable mappedTypes = new Hashtable ();\r
+ Hashtable dataMappedTypes = new Hashtable ();\r
+ Queue pendingMaps = new Queue ();\r
+\r
+ static readonly XmlQualifiedName anyType = new XmlQualifiedName ("anyType",XmlSchema.Namespace);\r
+ XmlSchemaElement anyElement = null;\r
+\r
+ class MapFixup\r
+ {\r
+ public XmlTypeMapping Map;\r
+ public XmlSchemaComplexType SchemaType;\r
+ public XmlQualifiedName TypeName;\r
+ }\r
\r
#endregion\r
\r
public XmlSchemaImporter (XmlSchemas schemas)\r
{\r
this.schemas = schemas;\r
+ typeIdentifiers = new CodeIdentifiers ();\r
}\r
\r
public XmlSchemaImporter (XmlSchemas schemas, CodeIdentifiers typeIdentifiers)\r
throw new NotImplementedException ();\r
}\r
\r
- [MonoTODO]\r
public XmlTypeMapping ImportTypeMapping (XmlQualifiedName name)\r
{\r
- throw new NotImplementedException ();\r
+ XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));\r
+ if (elem == null) return null;\r
+\r
+ // The root element must be an element with complex type\r
+\r
+ XmlQualifiedName qname;\r
+ XmlSchemaType stype;\r
+ if (elem.SchemaType != null)\r
+ {\r
+ stype = elem.SchemaType;\r
+ qname = name;\r
+ }\r
+ else\r
+ {\r
+ if (elem.SchemaTypeName.IsEmpty) return null;\r
+ if (elem.SchemaTypeName.Namespace == XmlSchema.Namespace) return null;\r
+ object type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaComplexType));\r
+ if (type == null) type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaSimpleType));\r
+ if (type == null) throw new InvalidOperationException ("Schema type '" + elem.SchemaTypeName + "' not found");\r
+ stype = (XmlSchemaType) type;\r
+ qname = stype.QualifiedName;\r
+ }\r
+\r
+ if (stype is XmlSchemaSimpleType) return null;\r
+\r
+ XmlTypeMapping map = ImportType (qname, (XmlSchemaComplexType)stype, name);\r
+ BuildPendingMaps ();\r
+ return map;\r
+ }\r
+\r
+ public XmlTypeMapping ImportType (XmlQualifiedName name, XmlQualifiedName root)\r
+ {\r
+ XmlTypeMapping map = GetRegisteredTypeMapping (name);\r
+ if (map != null) return map;\r
+\r
+ XmlSchemaType type = (XmlSchemaType) schemas.Find (name, typeof (XmlSchemaComplexType));\r
+ if (type == null) type = (XmlSchemaType) schemas.Find (name, typeof (XmlSchemaSimpleType));\r
+\r
+ return ImportType (name, type, root);\r
+ }\r
+\r
+ XmlTypeMapping ImportType (XmlQualifiedName name, XmlSchemaType stype, XmlQualifiedName root)\r
+ {\r
+ XmlTypeMapping map = GetRegisteredTypeMapping (name);\r
+ if (map != null) return map;\r
+\r
+ if (stype is XmlSchemaComplexType)\r
+ return ImportClassComplexType (name, (XmlSchemaComplexType) stype, root);\r
+ else if (stype is XmlSchemaSimpleType)\r
+ return ImportClassSimpleType (name, (XmlSchemaSimpleType) stype, root);\r
+\r
+ throw new NotSupportedException ("Schema type not supported: " + stype.GetType ());\r
+ }\r
+\r
+ XmlTypeMapping ImportClassComplexType (XmlQualifiedName typeQName, XmlSchemaComplexType stype, XmlQualifiedName root)\r
+ {\r
+// if (root != null) typeQName = root;\r
+\r
+ XmlTypeMapping map;\r
+\r
+ // The need for fixups: If the complex type is an array, then to get the type of the\r
+ // array we need first to get the type of the items of the array.\r
+ // But if one of the item types or its children has a referece to this type array,\r
+ // then we enter in an infinite loop. This does not happen with class types because\r
+ // the class map is registered before parsing the children. We can't do the same\r
+ // with the array type because to register the array map we need the type of the array.\r
+\r
+ if (root == null && CanBeArray (typeQName, stype))\r
+ {\r
+ TypeData typeData;\r
+ ListMap listMap = BuildArrayMap (typeQName, stype, out typeData);\r
+ if (listMap != null)\r
+ {\r
+ map = CreateArrayTypeMapping (typeQName, typeData);\r
+ map.ObjectMap = listMap;\r
+ return map;\r
+ }\r
+\r
+ // After all, it is not an array. Create a class map then.\r
+ }\r
+ else if (CanBeAnyElement (stype))\r
+ {\r
+ return GetTypeMapping (TypeTranslator.GetTypeData(typeof(XmlElement)));\r
+ }\r
+ else if (CanBeIXmlSerializable (stype))\r
+ {\r
+ return GetTypeMapping (TypeTranslator.GetTypeData(typeof(object)));\r
+ }\r
+\r
+ // Register the map right now but do not build it,\r
+ // This will avoid loops.\r
+\r
+ map = CreateTypeMapping (typeQName, SchemaTypes.Class, root);\r
+ RegisterMapFixup (map, typeQName, stype);\r
+ return map;\r
+ }\r
+\r
+ void RegisterMapFixup (XmlTypeMapping map, XmlQualifiedName typeQName, XmlSchemaComplexType stype)\r
+ {\r
+ MapFixup fixup = new MapFixup ();\r
+ fixup.Map = map;\r
+ fixup.SchemaType = stype;\r
+ fixup.TypeName = typeQName;\r
+ pendingMaps.Enqueue (fixup);\r
+ }\r
+\r
+ void BuildPendingMaps ()\r
+ {\r
+ while (pendingMaps.Count > 0) {\r
+ MapFixup fixup = (MapFixup) pendingMaps.Dequeue ();\r
+ if (fixup.Map.ObjectMap == null) {\r
+ BuildClassMap (fixup.Map, fixup.TypeName, fixup.SchemaType);\r
+ if (fixup.Map.ObjectMap == null) pendingMaps.Enqueue (fixup);\r
+ }\r
+ }\r
+ }\r
+\r
+ void BuildPendingMap (XmlTypeMapping map)\r
+ {\r
+ if (map.ObjectMap != null) return;\r
+\r
+ foreach (MapFixup fixup in pendingMaps)\r
+ {\r
+ if (fixup.Map == map) {\r
+ BuildClassMap (fixup.Map, fixup.TypeName, fixup.SchemaType);\r
+ return;\r
+ }\r
+ }\r
+ throw new InvalidOperationException ("Can't complete map of type " + map.XmlType + " : " + map.Namespace);\r
+ }\r
+\r
+ void BuildClassMap (XmlTypeMapping map, XmlQualifiedName typeQName, XmlSchemaComplexType stype)\r
+ {\r
+ CodeIdentifiers classIds = new CodeIdentifiers();\r
+ classIds.AddReserved (map.TypeData.TypeName);\r
+\r
+ ClassMap cmap = new ClassMap ();\r
+ map.ObjectMap = cmap;\r
+ bool isMixed = stype.IsMixed;\r
+\r
+ if (stype.Particle != null)\r
+ {\r
+ ImportParticleComplexContent (typeQName, cmap, stype.Particle, classIds, isMixed);\r
+ }\r
+ else\r
+ {\r
+ if (stype.ContentModel is XmlSchemaSimpleContent) {\r
+ ImportSimpleContent (typeQName, map, (XmlSchemaSimpleContent)stype.ContentModel, classIds, isMixed);\r
+ }\r
+ else if (stype.ContentModel is XmlSchemaComplexContent) {\r
+ ImportComplexContent (typeQName, map, (XmlSchemaComplexContent)stype.ContentModel, classIds, isMixed);\r
+ }\r
+ }\r
+\r
+ ImportAttributes (typeQName, cmap, stype.Attributes, stype.AnyAttribute, classIds);\r
+ }\r
+\r
+ void ImportAttributes (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection atts, XmlSchemaAnyAttribute anyat, CodeIdentifiers classIds)\r
+ {\r
+ if (anyat != null)\r
+ {\r
+ XmlTypeMapMemberAnyAttribute member = new XmlTypeMapMemberAnyAttribute ();\r
+ member.Name = classIds.AddUnique ("AnyAttribute", member);\r
+ member.TypeData = TypeTranslator.GetTypeData (typeof(XmlAttribute[]));\r
+ cmap.AddMember (member);\r
+ }\r
+ \r
+ foreach (XmlSchemaObject at in atts)\r
+ {\r
+ if (at is XmlSchemaAttribute)\r
+ {\r
+ string ns;\r
+ XmlSchemaAttribute attr = (XmlSchemaAttribute)at;\r
+ XmlSchemaAttribute refAttr = GetRefAttribute (typeQName, attr, out ns);\r
+ XmlTypeMapMemberAttribute member = new XmlTypeMapMemberAttribute ();\r
+ member.Name = classIds.AddUnique (CodeIdentifier.MakeValid (refAttr.Name), member);\r
+ member.AttributeName = refAttr.Name;\r
+ member.Namespace = ns;\r
+ member.Form = refAttr.Form;\r
+ member.TypeData = GetAttributeTypeData (typeQName, attr);\r
+ if (refAttr.DefaultValue != null) member.DefaultValue = refAttr.DefaultValue;\r
+ if (member.TypeData.IsComplexType)\r
+ member.MappedType = GetTypeMapping (member.TypeData);\r
+ cmap.AddMember (member);\r
+ }\r
+ else if (at is XmlSchemaAttributeGroupRef)\r
+ {\r
+ XmlSchemaAttributeGroupRef gref = (XmlSchemaAttributeGroupRef)at;\r
+ XmlSchemaAttributeGroup grp = (XmlSchemaAttributeGroup) schemas.Find (gref.RefName, typeof(XmlSchemaAttributeGroup));\r
+ ImportAttributes (typeQName, cmap, grp.Attributes, grp.AnyAttribute, classIds);\r
+ }\r
+ }\r
+ }\r
+\r
+ ListMap BuildArrayMap (XmlQualifiedName typeQName, XmlSchemaComplexType stype, out TypeData arrayTypeData)\r
+ {\r
+ ClassMap cmap = new ClassMap ();\r
+ CodeIdentifiers classIds = new CodeIdentifiers();\r
+ ImportParticleComplexContent (typeQName, cmap, stype.Particle, classIds, false);\r
+\r
+ XmlTypeMapMemberFlatList list = (cmap.AllMembers.Count == 1) ? cmap.AllMembers[0] as XmlTypeMapMemberFlatList : null;\r
+ if (list != null && list.ChoiceMember == null)\r
+ {\r
+ arrayTypeData = list.TypeData;\r
+ return list.ListMap;\r
+ }\r
+ else\r
+ {\r
+ arrayTypeData = null;\r
+ return null;\r
+ }\r
+ }\r
+\r
+ void ImportParticleComplexContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool isMixed)\r
+ {\r
+ ImportParticleContent (typeQName, cmap, particle, classIds, false, ref isMixed);\r
+ if (isMixed)\r
+ {\r
+ XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();\r
+ member.Name = classIds.AddUnique ("Text", member);\r
+ member.TypeData = TypeTranslator.GetTypeData (typeof(string[]));\r
+ member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData.ListItemTypeData));\r
+ member.IsXmlTextCollector = true;\r
+ member.ListMap = new ListMap ();\r
+ member.ListMap.ItemInfo = member.ElementInfo;\r
+ cmap.AddMember (member);\r
+ }\r
+ }\r
+ \r
+ void ImportParticleContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)\r
+ {\r
+ if (particle is XmlSchemaGroupRef)\r
+ particle = GetRefGroupParticle ((XmlSchemaGroupRef)particle);\r
+\r
+ if (particle.MaxOccurs > 1) multiValue = true;\r
+ \r
+ if (particle is XmlSchemaSequence) {\r
+ ImportSequenceContent (typeQName, cmap, ((XmlSchemaSequence)particle).Items, classIds, multiValue, ref isMixed);\r
+ }\r
+ else if (particle is XmlSchemaChoice) {\r
+ if (((XmlSchemaChoice)particle).Items.Count == 1)\r
+ ImportSequenceContent (typeQName, cmap, ((XmlSchemaChoice)particle).Items, classIds, multiValue, ref isMixed);\r
+ else\r
+ ImportChoiceContent (typeQName, cmap, (XmlSchemaChoice)particle, classIds, multiValue);\r
+ }\r
+ else if (particle is XmlSchemaAll) {\r
+ ImportSequenceContent (typeQName, cmap, ((XmlSchemaAll)particle).Items, classIds, multiValue, ref isMixed);\r
+ }\r
+ }\r
+\r
+ void ImportSequenceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection items, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)\r
+ {\r
+ foreach (XmlSchemaObject item in items)\r
+ {\r
+ XmlTypeMapMember mapMember;\r
+\r
+ if (item is XmlSchemaElement)\r
+ {\r
+ string ns;\r
+ XmlSchemaElement elem = (XmlSchemaElement) item;\r
+ TypeData typeData = GetElementTypeData (typeQName, elem);\r
+ XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);\r
+\r
+ if (elem.MaxOccurs == 1 && !multiValue)\r
+ {\r
+ XmlTypeMapMemberElement member = null;\r
+ if (typeData.SchemaType != SchemaTypes.Array)\r
+ {\r
+ member = new XmlTypeMapMemberElement ();\r
+ if (refElem.DefaultValue != null) member.DefaultValue = refElem.DefaultValue;\r
+ }\r
+ else if (GetTypeMapping (typeData).IsSimpleType)\r
+ {\r
+ // It is a simple list (space separated list).\r
+ // Since this is not supported, map as a single item value\r
+ // TODO: improve this\r
+ member = new XmlTypeMapMemberElement ();\r
+ typeData = typeData.ListItemTypeData;\r
+ }\r
+ else\r
+ member = new XmlTypeMapMemberList ();\r
+\r
+ member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);\r
+ member.TypeData = typeData;\r
+ member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable));\r
+ cmap.AddMember (member);\r
+ }\r
+ else\r
+ {\r
+ XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();\r
+ member.ListMap = new ListMap ();\r
+ member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);\r
+ member.TypeData = typeData.ListTypeData;\r
+ member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable));\r
+ member.ListMap.ItemInfo = member.ElementInfo;\r
+ cmap.AddMember (member);\r
+ }\r
+ }\r
+ else if (item is XmlSchemaAny)\r
+ {\r
+ XmlSchemaAny elem = (XmlSchemaAny) item;\r
+ XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement ();\r
+ member.Name = classIds.AddUnique ("Any", member);\r
+\r
+ Type ctype;\r
+ if (elem.MaxOccurs > 1 || multiValue)\r
+ ctype = isMixed ? typeof(XmlNode[]) : typeof(XmlElement[]);\r
+ else\r
+ ctype = isMixed ? typeof(XmlNode) : typeof(XmlElement);\r
+\r
+ member.TypeData = TypeTranslator.GetTypeData (ctype);\r
+ XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, member.TypeData);\r
+ einfo.IsUnnamedAnyElement = true;\r
+ member.ElementInfo.Add (einfo);\r
+\r
+ if (isMixed)\r
+ {\r
+ einfo = CreateTextElementInfo (typeQName.Namespace, member, member.TypeData);\r
+ member.ElementInfo.Add (einfo);\r
+ member.IsXmlTextCollector = true;\r
+ isMixed = false; //Allow only one XmlTextAttribute\r
+ }\r
+ \r
+ cmap.AddMember (member);\r
+ }\r
+ else if (item is XmlSchemaParticle) {\r
+ ImportParticleContent (typeQName, cmap, (XmlSchemaParticle)item, classIds, multiValue, ref isMixed);\r
+ }\r
+ }\r
+ }\r
+\r
+ void ImportChoiceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaChoice choice, CodeIdentifiers classIds, bool multiValue)\r
+ {\r
+ XmlTypeMapElementInfoList choices = new XmlTypeMapElementInfoList ();\r
+ multiValue = ImportChoices (typeQName, null, choices, choice.Items) || multiValue;\r
+ if (choices.Count == 0) return;\r
+\r
+ if (choice.MaxOccurs > 1) multiValue = true;\r
+\r
+ XmlTypeMapMemberElement member;\r
+ if (multiValue)\r
+ {\r
+ member = new XmlTypeMapMemberFlatList ();\r
+ member.Name = classIds.AddUnique ("Items", member);\r
+ ListMap listMap = new ListMap ();\r
+ listMap.ItemInfo = choices;\r
+ ((XmlTypeMapMemberFlatList)member).ListMap = listMap;\r
+ }\r
+ else\r
+ {\r
+ member = new XmlTypeMapMemberElement ();\r
+ member.Name = classIds.AddUnique ("Item", member);\r
+ }\r
+ \r
+ // If all choices have the same type, use that type for the member.\r
+ // If not use System.Object.\r
+ // If there are at least two choices with the same type, use a choice\r
+ // identifier attribute\r
+\r
+ TypeData typeData = null;\r
+ bool twoEqual = false;\r
+ bool allEqual = true;\r
+ Hashtable types = new Hashtable ();\r
+ foreach (XmlTypeMapElementInfo einfo in choices)\r
+ {\r
+ if (types.ContainsKey (einfo.TypeData)) twoEqual = true;\r
+ else types.Add (einfo.TypeData, einfo);\r
+\r
+ TypeData choiceType = einfo.TypeData;\r
+ if (choiceType.SchemaType == SchemaTypes.Class)\r
+ {\r
+ // When comparing class types, use the most generic class in the\r
+ // inheritance hierarchy\r
+\r
+ XmlTypeMapping choiceMap = GetTypeMapping (choiceType);\r
+ BuildPendingMap (choiceMap);\r
+ while (choiceMap.BaseMap != null) {\r
+ choiceMap = choiceMap.BaseMap;\r
+ BuildPendingMap (choiceMap);\r
+ choiceType = choiceMap.TypeData;\r
+ }\r
+ }\r
+ \r
+ if (typeData == null) typeData = choiceType;\r
+ else if (typeData != choiceType) allEqual = false;\r
+ }\r
+\r
+ if (!allEqual)\r
+ typeData = TypeTranslator.GetTypeData (typeof(object));\r
+\r
+ if (twoEqual)\r
+ {\r
+ // Create the choice member\r
+ XmlTypeMapMemberElement choiceMember = new XmlTypeMapMemberElement ();\r
+ choiceMember.Name = classIds.AddUnique (member.Name + "ElementName", choiceMember);\r
+ member.ChoiceMember = choiceMember.Name;\r
+\r
+ // Create the choice enum\r
+ XmlTypeMapping enumMap = CreateTypeMapping (new XmlQualifiedName (member.Name + "ChoiceType", typeQName.Namespace), SchemaTypes.Enum, null);\r
+ CodeIdentifiers codeIdents = new CodeIdentifiers ();\r
+ EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [choices.Count];\r
+ for (int n=0; n<choices.Count; n++)\r
+ {\r
+ XmlTypeMapElementInfo it =(XmlTypeMapElementInfo) choices[n];\r
+ string xmlName = (it.Namespace != null && it.Namespace != "") ? it.Namespace + ":" + it.ElementName : it.ElementName;\r
+ string enumName = codeIdents.AddUnique (CodeIdentifier.MakeValid (it.ElementName), it);\r
+ members [n] = new EnumMap.EnumMapMember (xmlName, enumName);\r
+ }\r
+ enumMap.ObjectMap = new EnumMap (members, false);\r
+\r
+ choiceMember.TypeData = multiValue ? enumMap.TypeData.ListTypeData : enumMap.TypeData;\r
+ choiceMember.ElementInfo.Add (CreateElementInfo (typeQName.Namespace, choiceMember, choiceMember.Name, choiceMember.TypeData, false));\r
+ cmap.AddMember (choiceMember);\r
+ }\r
+\r
+ if (multiValue)\r
+ typeData = typeData.ListTypeData;\r
+\r
+ member.ElementInfo = choices;\r
+ member.TypeData = typeData;\r
+ cmap.AddMember (member);\r
+ }\r
+\r
+ bool ImportChoices (XmlQualifiedName typeQName, XmlTypeMapMember member, XmlTypeMapElementInfoList choices, XmlSchemaObjectCollection items)\r
+ {\r
+ bool multiValue = false;\r
+ foreach (XmlSchemaObject titem in items)\r
+ {\r
+ XmlSchemaObject item = titem;\r
+ if (item is XmlSchemaGroupRef)\r
+ item = GetRefGroupParticle ((XmlSchemaGroupRef)item);\r
+\r
+ if (item is XmlSchemaElement)\r
+ {\r
+ string ns;\r
+ XmlSchemaElement elem = (XmlSchemaElement) item;\r
+ TypeData typeData = GetElementTypeData (typeQName, elem);\r
+ XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);\r
+ choices.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable));\r
+ if (elem.MaxOccurs > 1) multiValue = true;\r
+ }\r
+ else if (item is XmlSchemaAny)\r
+ {\r
+ XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, TypeTranslator.GetTypeData(typeof(XmlElement)));\r
+ einfo.IsUnnamedAnyElement = true;\r
+ choices.Add (einfo);\r
+ }\r
+ else if (item is XmlSchemaChoice) {\r
+ multiValue = ImportChoices (typeQName, member, choices, ((XmlSchemaChoice)item).Items) || multiValue;\r
+ }\r
+ else if (item is XmlSchemaSequence) {\r
+ multiValue = ImportChoices (typeQName, member, choices, ((XmlSchemaSequence)item).Items) || multiValue;\r
+ }\r
+ }\r
+ return multiValue;\r
+ }\r
+\r
+ void ImportSimpleContent (XmlQualifiedName typeQName, XmlTypeMapping map, XmlSchemaSimpleContent content, CodeIdentifiers classIds, bool isMixed)\r
+ {\r
+ ClassMap cmap = (ClassMap)map.ObjectMap;\r
+ \r
+ XmlQualifiedName qname = GetContentBaseType (content.Content);\r
+\r
+ XmlTypeMapMemberElement member = new XmlTypeMapMemberElement ();\r
+ member.Name = classIds.AddUnique("Value", member);\r
+ member.TypeData = FindBuiltInType (qname);\r
+ member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData));\r
+ member.IsXmlTextCollector = true;\r
+ cmap.AddMember (member);\r
+\r
+ XmlSchemaSimpleContentExtension ext = content.Content as XmlSchemaSimpleContentExtension;\r
+ if (ext != null)\r
+ ImportAttributes (typeQName, cmap, ext.Attributes, ext.AnyAttribute, classIds);\r
+ }\r
+\r
+ TypeData FindBuiltInType (XmlQualifiedName qname)\r
+ {\r
+ if (qname.Namespace == XmlSchema.Namespace)\r
+ return TypeTranslator.GetPrimitiveTypeData (qname.Name);\r
+\r
+ XmlSchemaComplexType ct = (XmlSchemaComplexType) schemas.Find (qname, typeof(XmlSchemaComplexType));\r
+ if (ct != null)\r
+ {\r
+ XmlSchemaSimpleContent sc = ct.ContentModel as XmlSchemaSimpleContent;\r
+ if (sc == null) throw new InvalidOperationException ("Invalid schema");\r
+ return FindBuiltInType (GetContentBaseType (sc.Content));\r
+ }\r
+ \r
+ XmlSchemaSimpleType st = (XmlSchemaSimpleType) schemas.Find (qname, typeof(XmlSchemaSimpleType));\r
+ if (st != null)\r
+ return FindBuiltInType (qname, st);\r
+\r
+ throw new InvalidOperationException ("Definition of type " + qname + " not found");\r
+ }\r
+\r
+ TypeData FindBuiltInType (XmlQualifiedName qname, XmlSchemaSimpleType st)\r
+ {\r
+ if (CanBeEnum (st))\r
+ return ImportType (qname, null).TypeData;\r
+\r
+ if (st.Content is XmlSchemaSimpleTypeRestriction) {\r
+ return FindBuiltInType (GetContentBaseType (st.Content));\r
+ }\r
+ else if (st.Content is XmlSchemaSimpleTypeList) {\r
+ return FindBuiltInType (GetContentBaseType (st.Content)).ListTypeData;\r
+ }\r
+ else if (st.Content is XmlSchemaSimpleTypeUnion)\r
+ {\r
+ // Check if all types of the union are equal. If not, then will use anyType.\r
+ XmlSchemaSimpleTypeUnion uni = (XmlSchemaSimpleTypeUnion) st.Content;\r
+ TypeData utype = null;\r
+\r
+ // Anonymous types are unique\r
+ if (uni.BaseTypes.Count != 0 && uni.MemberTypes.Length != 0)\r
+ return FindBuiltInType (anyType);\r
+\r
+ foreach (XmlQualifiedName mt in uni.MemberTypes)\r
+ {\r
+ TypeData qn = FindBuiltInType (mt);\r
+ if (utype != null && qn != utype) return FindBuiltInType (anyType);\r
+ else utype = qn;\r
+ }\r
+ return utype;\r
+ }\r
+ else\r
+ return null;\r
+ }\r
+\r
+ XmlQualifiedName GetContentBaseType (XmlSchemaObject ob)\r
+ {\r
+ if (ob is XmlSchemaSimpleContentExtension)\r
+ return ((XmlSchemaSimpleContentExtension)ob).BaseTypeName;\r
+ else if (ob is XmlSchemaSimpleContentRestriction)\r
+ return ((XmlSchemaSimpleContentRestriction)ob).BaseTypeName;\r
+ else if (ob is XmlSchemaSimpleTypeRestriction)\r
+ return ((XmlSchemaSimpleTypeRestriction)ob).BaseTypeName;\r
+ else if (ob is XmlSchemaSimpleTypeList)\r
+ return ((XmlSchemaSimpleTypeList)ob).ItemTypeName;\r
+ else\r
+ return null;\r
+ }\r
+\r
+ void ImportComplexContent (XmlQualifiedName typeQName, XmlTypeMapping map, XmlSchemaComplexContent content, CodeIdentifiers classIds, bool isMixed)\r
+ {\r
+ XmlSchemaComplexContentExtension ext = content.Content as XmlSchemaComplexContentExtension;\r
+\r
+ ClassMap cmap = (ClassMap)map.ObjectMap;\r
+ XmlQualifiedName qname;\r
+\r
+ if (ext != null) qname = ext.BaseTypeName;\r
+ else qname = ((XmlSchemaComplexContentRestriction)content.Content).BaseTypeName;\r
+ \r
+ // Add base map members to this map\r
+\r
+ XmlTypeMapping baseMap = ImportType (qname, null);\r
+ BuildPendingMap (baseMap);\r
+ ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;\r
+\r
+ foreach (XmlTypeMapMember member in baseClassMap.AllMembers)\r
+ cmap.AddMember (member);\r
+\r
+ if (baseClassMap.XmlTextCollector != null) isMixed = false;\r
+ else if (content.IsMixed) isMixed = true;\r
+\r
+ map.BaseMap = baseMap;\r
+ baseMap.DerivedTypes.Add (map);\r
+\r
+ if (ext != null) {\r
+ // Add the members of this map\r
+ ImportParticleComplexContent (typeQName, cmap, ext.Particle, classIds, isMixed);\r
+ ImportAttributes (typeQName, cmap, ext.Attributes, ext.AnyAttribute, classIds);\r
+ }\r
+ else {\r
+ if (isMixed) ImportParticleComplexContent (typeQName, cmap, null, classIds, true);\r
+ }\r
+ }\r
+\r
+ XmlTypeMapping ImportClassSimpleType (XmlQualifiedName typeQName, XmlSchemaSimpleType stype, XmlQualifiedName root)\r
+ {\r
+ if (CanBeEnum (stype))\r
+ {\r
+ // Create an enum map\r
+\r
+ CodeIdentifiers codeIdents = new CodeIdentifiers ();\r
+ XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction)stype.Content;\r
+\r
+ XmlTypeMapping enumMap = CreateTypeMapping (typeQName, SchemaTypes.Enum, null);\r
+ codeIdents.AddReserved (enumMap.TypeData.TypeName);\r
+\r
+ EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [rest.Facets.Count];\r
+ for (int n=0; n<rest.Facets.Count; n++)\r
+ {\r
+ XmlSchemaEnumerationFacet enu = (XmlSchemaEnumerationFacet) rest.Facets[n];\r
+ string enumName = codeIdents.AddUnique(CodeIdentifier.MakeValid (enu.Value), enu);\r
+ members [n] = new EnumMap.EnumMapMember (enu.Value, enumName);\r
+ }\r
+ enumMap.ObjectMap = new EnumMap (members, false);\r
+ enumMap.IsSimpleType = true;\r
+ return enumMap;\r
+ }\r
+\r
+ if (stype.Content is XmlSchemaSimpleTypeList)\r
+ {\r
+ XmlSchemaSimpleTypeList slist = (XmlSchemaSimpleTypeList)stype.Content;\r
+ TypeData arrayTypeData = FindBuiltInType (slist.ItemTypeName, stype);\r
+\r
+ ListMap listMap = new ListMap ();\r
+ listMap.ItemInfo = new XmlTypeMapElementInfoList ();\r
+ listMap.ItemInfo.Add (CreateElementInfo (typeQName.Namespace, null, "Item", arrayTypeData.ListItemTypeData, false));\r
+\r
+ XmlTypeMapping map = CreateArrayTypeMapping (typeQName, arrayTypeData);\r
+ map.ObjectMap = listMap;\r
+ map.IsSimpleType = true;\r
+ return map;\r
+ }\r
+\r
+ // It is an extension of a primitive or known type\r
+ \r
+ TypeData typeData = FindBuiltInType (typeQName, stype);\r
+ return GetTypeMapping (typeData);\r
+ }\r
+\r
+ bool CanBeEnum (XmlSchemaSimpleType stype)\r
+ {\r
+ if (stype.Content is XmlSchemaSimpleTypeRestriction)\r
+ {\r
+ XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction)stype.Content;\r
+ foreach (object ob in rest.Facets)\r
+ if (!(ob is XmlSchemaEnumerationFacet)) return false;\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ bool CanBeArray (XmlQualifiedName typeQName, XmlSchemaComplexType stype)\r
+ {\r
+ return !stype.IsMixed && CanBeArray (typeQName, stype.Particle, false);\r
+ }\r
+\r
+ bool CanBeArray (XmlQualifiedName typeQName, XmlSchemaParticle particle, bool multiValue)\r
+ {\r
+ // To be an array, there can't be a direct child of type typeQName\r
+\r
+ if (particle == null) return false;\r
+\r
+ multiValue = multiValue || particle.MaxOccurs > 1;\r
+\r
+ if (particle is XmlSchemaGroupRef)\r
+ return CanBeArray (typeQName, GetRefGroupParticle ((XmlSchemaGroupRef)particle), multiValue);\r
+\r
+ if (particle is XmlSchemaElement)\r
+ {\r
+ XmlSchemaElement elem = (XmlSchemaElement)particle;\r
+ if (!elem.RefName.IsEmpty)\r
+ return CanBeArray (typeQName, FindRefElement (elem), multiValue);\r
+ else\r
+ return multiValue && !typeQName.Equals (((XmlSchemaElement)particle).SchemaTypeName);\r
+ }\r
+\r
+ if (particle is XmlSchemaAny)\r
+ return multiValue;\r
+\r
+ if (particle is XmlSchemaSequence)\r
+ {\r
+ XmlSchemaSequence seq = particle as XmlSchemaSequence;\r
+ if (seq.Items.Count != 1) return false;\r
+ return CanBeArray (typeQName, (XmlSchemaParticle)seq.Items[0], multiValue);\r
+ }\r
+\r
+ if (particle is XmlSchemaChoice)\r
+ {\r
+ // Can be array if all choices have different types\r
+ ArrayList types = new ArrayList ();\r
+ if(!CheckChoiceType (typeQName, particle, types, ref multiValue)) return false;\r
+ return multiValue;\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ bool CheckChoiceType (XmlQualifiedName typeQName, XmlSchemaParticle particle, ArrayList types, ref bool multiValue)\r
+ {\r
+ XmlQualifiedName type = null;\r
+\r
+ multiValue = multiValue || particle.MaxOccurs > 1;\r
+\r
+ if (particle is XmlSchemaGroupRef)\r
+ return CheckChoiceType (typeQName, GetRefGroupParticle ((XmlSchemaGroupRef)particle), types, ref multiValue);\r
+\r
+ if (particle is XmlSchemaElement) {\r
+ string ns;\r
+ XmlSchemaElement elem = (XmlSchemaElement)particle;\r
+ XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);\r
+ if (refElem.SchemaType != null) return true;\r
+ type = refElem.SchemaTypeName;\r
+ }\r
+ else if (particle is XmlSchemaAny) {\r
+ type = anyType;\r
+ }\r
+ else if (particle is XmlSchemaSequence)\r
+ {\r
+ XmlSchemaSequence seq = particle as XmlSchemaSequence;\r
+ foreach (XmlSchemaParticle par in seq.Items)\r
+ if (!CheckChoiceType (typeQName, par, types, ref multiValue)) return false;\r
+ return true;\r
+ }\r
+ else if (particle is XmlSchemaChoice)\r
+ {\r
+ foreach (XmlSchemaParticle choice in ((XmlSchemaChoice)particle).Items)\r
+ if (!CheckChoiceType (typeQName, choice, types, ref multiValue)) return false;\r
+ return true;\r
+ }\r
+\r
+ if (typeQName.Equals (type)) return false;\r
+\r
+ // For primitive types, compare using CLR types, since several\r
+ // xml types can be mapped to a single CLR type\r
+\r
+ string t;\r
+ if (type.Namespace == XmlSchema.Namespace)\r
+ t = TypeTranslator.GetPrimitiveTypeData (type.Name).FullTypeName + ":" + type.Namespace;\r
+\r
+ else\r
+ t = type.Name + ":" + type.Namespace;\r
+\r
+ if (types.Contains (t)) return false;\r
+ types.Add (t);\r
+ return true;\r
+ }\r
+ \r
+ bool CanBeAnyElement (XmlSchemaComplexType stype)\r
+ {\r
+ XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;\r
+ return (seq != null) && (seq.Items.Count == 1) && (seq.Items[0] is XmlSchemaAny);\r
+ }\r
+\r
+ bool CanBeIXmlSerializable (XmlSchemaComplexType stype)\r
+ {\r
+ XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;\r
+ if (seq == null) return false;\r
+ if (seq.Items.Count != 2) return false;\r
+ XmlSchemaElement elem = seq.Items[0] as XmlSchemaElement;\r
+ if (elem == null) return false;\r
+ if (elem.RefName != new XmlQualifiedName ("schema",XmlSchema.Namespace)) return false;\r
+ return (seq.Items[1] is XmlSchemaAny);\r
+ }\r
+\r
+ XmlTypeMapElementInfo CreateElementInfo (string ns, XmlTypeMapMember member, string name, TypeData typeData, bool isNillable)\r
+ {\r
+ XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, typeData);\r
+ einfo.ElementName = name;\r
+ einfo.Namespace = ns;\r
+ einfo.IsNullable = isNillable;\r
+ if (einfo.TypeData.IsComplexType)\r
+ einfo.MappedType = GetTypeMapping (typeData);\r
+ return einfo;\r
+ }\r
+\r
+ XmlTypeMapElementInfo CreateTextElementInfo (string ns, XmlTypeMapMember member, TypeData typeData)\r
+ {\r
+ XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, typeData);\r
+ einfo.IsTextElement = true;\r
+ einfo.WrappedElement = false;\r
+ if (typeData.IsComplexType)\r
+ einfo.MappedType = GetTypeMapping (typeData);\r
+ return einfo;\r
+ }\r
+\r
+ XmlTypeMapping CreateTypeMapping (XmlQualifiedName typeQName, SchemaTypes schemaType, XmlQualifiedName root)\r
+ {\r
+ string typeName = CodeIdentifier.MakeValid (typeQName.Name);\r
+ typeName = typeIdentifiers.AddUnique (typeName, null);\r
+\r
+ TypeData typeData = new TypeData (typeName, typeName, typeName, schemaType, null);\r
+\r
+ XmlQualifiedName elemName = (root != null) ? root : typeQName;\r
+ \r
+ XmlTypeMapping map = new XmlTypeMapping (elemName.Name, elemName.Namespace, typeData, typeQName.Name, typeQName.Namespace);\r
+ mappedTypes [typeQName] = map;\r
+ dataMappedTypes [typeData] = map;\r
+\r
+ return map;\r
+ }\r
+\r
+ XmlTypeMapping CreateArrayTypeMapping (XmlQualifiedName typeQName, TypeData arrayTypeData)\r
+ {\r
+ XmlTypeMapping map = new XmlTypeMapping (arrayTypeData.XmlType, typeQName.Namespace, arrayTypeData, arrayTypeData.XmlType, typeQName.Namespace);\r
+ mappedTypes [typeQName] = map;\r
+ dataMappedTypes [arrayTypeData] = map;\r
+\r
+ return map;\r
+ }\r
+\r
+ XmlSchemaElement GetRefElement (XmlQualifiedName typeQName, XmlSchemaElement elem, out string ns)\r
+ {\r
+ if (!elem.RefName.IsEmpty)\r
+ {\r
+ ns = elem.RefName.Namespace;\r
+ return FindRefElement (elem);\r
+ }\r
+ else\r
+ {\r
+ ns = typeQName.Namespace;\r
+ return elem;\r
+ }\r
+ }\r
+\r
+ XmlSchemaAttribute GetRefAttribute (XmlQualifiedName typeQName, XmlSchemaAttribute attr, out string ns)\r
+ {\r
+ if (!attr.RefName.IsEmpty)\r
+ {\r
+ ns = attr.RefName.Namespace;\r
+ return (XmlSchemaAttribute) schemas.Find (attr.RefName, typeof(XmlSchemaAttribute));\r
+ }\r
+ else\r
+ {\r
+ ns = typeQName.Namespace;\r
+ return attr;\r
+ }\r
+ }\r
+\r
+ TypeData GetElementTypeData (XmlQualifiedName typeQName, XmlSchemaElement elem)\r
+ {\r
+ if (!elem.RefName.IsEmpty) {\r
+ XmlSchemaElement refElem = FindRefElement (elem);\r
+ if (refElem == null) throw new InvalidOperationException ("Ref type not found: " + elem.RefName);\r
+ return GetElementTypeData (typeQName, refElem);\r
+ }\r
+ \r
+ if (!elem.SchemaTypeName.IsEmpty) return GetTypeData (elem.SchemaTypeName);\r
+ else if (elem.SchemaType == null) return TypeTranslator.GetTypeData (typeof(object));\r
+ else return GetTypeData (elem.SchemaType, typeQName, elem.Name);\r
+ }\r
+\r
+ TypeData GetAttributeTypeData (XmlQualifiedName typeQName, XmlSchemaAttribute attr)\r
+ {\r
+ if (!attr.RefName.IsEmpty)\r
+ return GetAttributeTypeData (typeQName, (XmlSchemaAttribute)schemas.Find (attr.RefName, typeof (XmlSchemaAttribute)));\r
+\r
+ if (!attr.SchemaTypeName.IsEmpty) return GetTypeData (attr.SchemaTypeName);\r
+ else return GetTypeData (attr.SchemaType, typeQName, attr.Name);\r
+ }\r
+\r
+ TypeData GetTypeData (XmlQualifiedName typeQName)\r
+ {\r
+ if (typeQName.Namespace == XmlSchema.Namespace)\r
+ return TypeTranslator.GetPrimitiveTypeData (typeQName.Name);\r
+\r
+ return ImportType (typeQName, null).TypeData;\r
+ }\r
+\r
+ TypeData GetTypeData (XmlSchemaType stype, XmlQualifiedName typeQNname, string propertyName)\r
+ {\r
+ string baseName = typeQNname.Name + typeIdentifiers.MakeRightCase (propertyName);\r
+ baseName = elemIdentifiers.AddUnique (baseName, stype);\r
+ \r
+ XmlQualifiedName newName;\r
+ newName = new XmlQualifiedName (baseName, typeQNname.Namespace);\r
+\r
+ XmlTypeMapping map = ImportType (newName, stype, null);\r
+ return map.TypeData;\r
+ }\r
+\r
+ XmlTypeMapping GetTypeMapping (TypeData typeData)\r
+ {\r
+ XmlTypeMapping map = (XmlTypeMapping) dataMappedTypes [typeData];\r
+ if (map != null) return map;\r
+ \r
+ if (map == null && typeData.IsListType)\r
+ {\r
+ // Create an array map for the type\r
+\r
+ XmlTypeMapping itemMap = GetTypeMapping (typeData.ListItemTypeData);\r
+ \r
+ map = new XmlTypeMapping (typeData.XmlType, itemMap.Namespace, typeData, typeData.XmlType, itemMap.Namespace);\r
+ ListMap listMap = new ListMap ();\r
+ listMap.ItemInfo = new XmlTypeMapElementInfoList();\r
+ listMap.ItemInfo.Add (CreateElementInfo (itemMap.Namespace, null, typeData.ListItemTypeData.XmlType, typeData.ListItemTypeData, false));\r
+ map.ObjectMap = listMap;\r
+ \r
+ mappedTypes [new XmlQualifiedName(map.ElementName, map.Namespace)] = map;\r
+ dataMappedTypes [typeData] = map;\r
+ return map;\r
+ }\r
+ else if (typeData.SchemaType == SchemaTypes.Primitive || typeData.Type == typeof(object) || typeof(XmlNode).IsAssignableFrom(typeData.Type))\r
+ {\r
+ map = new XmlTypeMapping (typeData.XmlType, XmlSchema.Namespace, typeData, typeData.XmlType, XmlSchema.Namespace);\r
+ dataMappedTypes [typeData] = map;\r
+ return map;\r
+ }\r
+ \r
+ throw new InvalidOperationException ("Map for type " + typeData.TypeName + " not found");\r
+ }\r
+\r
+ XmlTypeMapping GetRegisteredTypeMapping (XmlQualifiedName typeQName)\r
+ {\r
+ return (XmlTypeMapping) mappedTypes [typeQName];\r
+ }\r
+\r
+ XmlSchemaParticle GetRefGroupParticle (XmlSchemaGroupRef refGroup)\r
+ {\r
+ XmlSchemaGroup grp = (XmlSchemaGroup) schemas.Find (refGroup.RefName, typeof (XmlSchemaGroup));\r
+ return grp.Particle;\r
+ }\r
+\r
+ XmlSchemaElement FindRefElement (XmlSchemaElement elem)\r
+ {\r
+ if (elem.RefName.Namespace == XmlSchema.Namespace)\r
+ {\r
+ if (anyElement != null) return anyElement;\r
+ anyElement = new XmlSchemaElement ();\r
+ anyElement.Name = "any";\r
+ anyElement.SchemaTypeName = anyType;\r
+ return anyElement;\r
+ }\r
+ return (XmlSchemaElement) schemas.Find (elem.RefName, typeof(XmlSchemaElement));\r
}\r
\r
#endregion // Methods\r