void ExportMembersMapping(XmlMembersMapping xmlMembersMapping, bool exportEnclosingType) { ClassMap cmap = (ClassMap)xmlMembersMapping.ObjectMap; if (xmlMembersMapping.HasWrapperElement && exportEnclosingType) { XmlSchema schema = GetSchema(xmlMembersMapping.Namespace); 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) { foreach (XmlTypeMapMemberElement member in members) { if (member is XmlTypeMapMemberAnyElement && member.TypeData.IsListType) { XmlSchema mschema = GetSchema(xmlMembersMapping.Namespace); XmlSchemaParticle par = GetSchemaArrayElement(mschema, member.ElementInfo); if (par is XmlSchemaAny) { XmlSchemaComplexType ct = FindComplexType(mschema.Items, "any"); if (ct != null) { continue; } ct = new XmlSchemaComplexType(); ct.Name = "any"; ct.IsMixed = true; XmlSchemaSequence seq = new XmlSchemaSequence(); ct.Particle = seq; seq.Items.Add(par); mschema.Items.Add(ct); continue; } } XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo)member.ElementInfo [0]; XmlSchema schema; if (encodedFormat) { schema = GetSchema(xmlMembersMapping.Namespace); ImportNamespace(schema, XmlSerializer.EncodingNamespace); } else { schema = GetSchema(einfo.Namespace); } XmlSchemaElement exe = FindElement(schema.Items, einfo.ElementName); XmlSchemaElement elem; XmlSchemaObjectContainer container = null; // In encoded format, the schema elements are not needed if (!encodedFormat) { container = new XmlSchemaObjectContainer(schema); } Type memType = member.GetType(); if (member is XmlTypeMapMemberFlatList) { throw new InvalidOperationException("Unwrapped arrays not supported as parameters"); } else if (memType == typeof(XmlTypeMapMemberElement)) { elem = (XmlSchemaElement)GetSchemaElement(schema, einfo, member.DefaultValue, false, container); } else { elem = (XmlSchemaElement)GetSchemaElement(schema, einfo, false, container); } if (exe != null) { if (exe.SchemaTypeName.Equals(elem.SchemaTypeName)) { schema.Items.Remove(elem); } else { string s = "The XML element named '" + einfo.ElementName + "' "; s += "from namespace '" + schema.TargetNamespace + "' references distinct types " + elem.SchemaTypeName.Name + " and " + exe.SchemaTypeName.Name + ". "; s += "Use XML attributes to specify another XML name or namespace for the element or types."; throw new InvalidOperationException(s); } } } } } CompileSchemas(); }
bool HasMixedContent(XmlTypeMapping map) { ClassMap cmap = (ClassMap)map.ObjectMap; return(cmap.XmlTextCollector != null && (map.BaseMap == null || !DefinedInBaseMap(map.BaseMap, cmap.XmlTextCollector))); }
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 && !map.HasSimpleContent) { foreach (XmlTypeMapMemberElement member in members) { if (baseMap != null && DefinedInBaseMap(baseMap, member)) { continue; } Type memType = member.GetType(); if (memType == typeof(XmlTypeMapMemberFlatList)) { XmlSchemaParticle part = GetSchemaArrayElement(schema, member.ElementInfo); if (part != null) { seq.Items.Add(part); } } else if (memType == typeof(XmlTypeMapMemberAnyElement)) { seq.Items.Add(GetSchemaArrayElement(schema, member.ElementInfo)); } else if (memType == typeof(XmlTypeMapMemberElement)) { GetSchemaElement(schema, (XmlTypeMapElementInfo)member.ElementInfo [0], member.DefaultValue, true, new XmlSchemaObjectContainer(seq)); } else { GetSchemaElement(schema, (XmlTypeMapElementInfo)member.ElementInfo[0], true, new XmlSchemaObjectContainer(seq)); } } } 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, true)); } } XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember; if (anyAttrMember != null) { anyAttribute = new XmlSchemaAnyAttribute(); } else { anyAttribute = null; } }
void WriteMembers(ClassMap map, object ob, bool isValueList) { WriteAttributeMembers(map, ob, isValueList); WriteElementMembers(map, ob, isValueList); }
void ExportClassSchema(XmlTypeMapping map) { if (IsMapExported(map)) { return; } SetMapExported(map); if (map.TypeData.Type == typeof(object)) { foreach (XmlTypeMapping dmap in map.DerivedTypes) { if (dmap.TypeData.SchemaType == SchemaTypes.Class) { ExportClassSchema(dmap); } } return; } 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); ImportNamespace(schema, map.BaseMap.XmlTypeNamespace); ExportClassSchema(map.BaseMap); } } 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; stype.IsMixed = HasMixedContent(map); cstype.IsMixed = BaseHasMixedContent(map); ImportNamespace(schema, map.BaseMap.XmlTypeNamespace); 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); } } }
protected virtual void WriteObjectElementElements(XmlTypeMapping typeMap, object ob) { ClassMap map = (ClassMap)typeMap.ObjectMap; WriteElementMembers(map, ob, false); }
void ReadMembers(ClassMap map, object ob, bool isValueList, bool readByOrder) { // Reads attributes ReadAttributeMembers(map, ob, isValueList); if (!isValueList) { Reader.MoveToElement(); if (Reader.IsEmptyElement) { SetListMembersDefaults(map, ob, isValueList); return; } Reader.ReadStartElement(); } // Reads elements bool[] readFlag = new bool[(map.ElementMembers != null) ? map.ElementMembers.Count : 0]; bool hasAnyReturnMember = (isValueList && _format == SerializationFormat.Encoded && map.ReturnMember != null); Reader.MoveToContent(); int[] indexes = null; object[] flatLists = null; object[] flatListsChoices = null; Fixup fixup = null; int ind = 0; int maxInd; if (readByOrder) { if (map.ElementMembers != null) { maxInd = map.ElementMembers.Count; } else { maxInd = 0; } } else { maxInd = int.MaxValue; } if (map.FlatLists != null) { indexes = new int[map.FlatLists.Count]; flatLists = new object[map.FlatLists.Count]; foreach (XmlTypeMapMemberExpandable mem in map.FlatLists) { if (IsReadOnly(mem, mem.TypeData, ob, isValueList)) { flatLists [mem.FlatArrayIndex] = mem.GetValue(ob); } else if (mem.TypeData.Type.IsArray) { flatLists [mem.FlatArrayIndex] = InitializeList(mem.TypeData); } else { object list = mem.GetValue(ob); if (list == null) { list = InitializeList(mem.TypeData); SetMemberValue(mem, ob, list, isValueList); } flatLists [mem.FlatArrayIndex] = list; } if (mem.ChoiceMember != null) { if (flatListsChoices == null) { flatListsChoices = new object [map.FlatLists.Count]; } flatListsChoices [mem.FlatArrayIndex] = InitializeList(mem.ChoiceTypeData); } } } if (_format == SerializationFormat.Encoded && map.ElementMembers != null) { FixupCallbackInfo info = new FixupCallbackInfo(this, map, isValueList); fixup = new Fixup(ob, new XmlSerializationFixupCallback(info.FixupMembers), map.ElementMembers.Count); AddFixup(fixup); } while (Reader.NodeType != System.Xml.XmlNodeType.EndElement && (ind < maxInd)) { if (Reader.NodeType == System.Xml.XmlNodeType.Element) { XmlTypeMapElementInfo info; if (readByOrder) { info = map.GetElement(ind++); } else if (hasAnyReturnMember) { info = (XmlTypeMapElementInfo)((XmlTypeMapMemberElement)map.ReturnMember).ElementInfo[0]; hasAnyReturnMember = false; } else { info = map.GetElement(Reader.LocalName, Reader.NamespaceURI); } if (info != null && !readFlag[info.Member.Index]) { if (info.Member.GetType() == typeof(XmlTypeMapMemberList)) { if (_format == SerializationFormat.Encoded && info.MultiReferenceType) { object list = ReadReferencingElement(out fixup.Ids[info.Member.Index]); if (fixup.Ids[info.Member.Index] == null) // Already read { if (IsReadOnly(info.Member, info.TypeData, ob, isValueList)) { throw CreateReadOnlyCollectionException(info.TypeData.FullTypeName); } else { SetMemberValue(info.Member, ob, list, isValueList); } } else if (!info.MappedType.TypeData.Type.IsArray) { if (IsReadOnly(info.Member, info.TypeData, ob, isValueList)) { list = GetMemberValue(info.Member, ob, isValueList); } else { list = CreateList(info.MappedType.TypeData.Type); SetMemberValue(info.Member, ob, list, isValueList); } AddFixup(new CollectionFixup(list, new XmlSerializationCollectionFixupCallback(FillList), fixup.Ids[info.Member.Index])); fixup.Ids[info.Member.Index] = null; // The member already has the value, no further fix needed. } } else { if (IsReadOnly(info.Member, info.TypeData, ob, isValueList)) { ReadListElement(info.MappedType, info.IsNullable, GetMemberValue(info.Member, ob, isValueList), false); } else if (info.MappedType.TypeData.Type.IsArray) { object list = ReadListElement(info.MappedType, info.IsNullable, null, true); if (list != null || info.IsNullable) { SetMemberValue(info.Member, ob, list, isValueList); } } else { // If the member already has a list, reuse that list. No need to create a new one. object list = GetMemberValue(info.Member, ob, isValueList); if (list == null) { list = CreateList(info.MappedType.TypeData.Type); SetMemberValue(info.Member, ob, list, isValueList); } ReadListElement(info.MappedType, info.IsNullable, list, true); } } readFlag[info.Member.Index] = true; } else if (info.Member.GetType() == typeof(XmlTypeMapMemberFlatList)) { XmlTypeMapMemberFlatList mem = (XmlTypeMapMemberFlatList)info.Member; AddListValue(mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, ReadObjectElement(info), !IsReadOnly(info.Member, info.TypeData, ob, isValueList)); if (mem.ChoiceMember != null) { AddListValue(mem.ChoiceTypeData, ref flatListsChoices [mem.FlatArrayIndex], indexes[mem.FlatArrayIndex] - 1, info.ChoiceValue, true); } } else if (info.Member.GetType() == typeof(XmlTypeMapMemberAnyElement)) { XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement)info.Member; if (mem.TypeData.IsListType) { AddListValue(mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, ReadXmlNode(mem.TypeData.ListItemTypeData, false), true); } else { SetMemberValue(mem, ob, ReadXmlNode(mem.TypeData, false), isValueList); } } else if (info.Member.GetType() == typeof(XmlTypeMapMemberElement)) { object val; readFlag[info.Member.Index] = true; if (_format == SerializationFormat.Encoded) { if (info.Member.TypeData.SchemaType != SchemaTypes.Primitive) { val = ReadReferencingElement(out fixup.Ids[info.Member.Index]); } else { val = ReadReferencingElement(info.Member.TypeData.XmlType, System.Xml.Schema.XmlSchema.Namespace, out fixup.Ids[info.Member.Index]); } if (info.MultiReferenceType) { if (fixup.Ids[info.Member.Index] == null) // already read { SetMemberValue(info.Member, ob, val, isValueList); } } else if (val != null) { SetMemberValue(info.Member, ob, val, isValueList); } } else { SetMemberValue(info.Member, ob, ReadObjectElement(info), isValueList); if (info.ChoiceValue != null) { XmlTypeMapMemberElement imem = (XmlTypeMapMemberElement)info.Member; imem.SetChoice(ob, info.ChoiceValue); } } } else { throw new InvalidOperationException("Unknown member type"); } } else if (map.DefaultAnyElementMember != null) { XmlTypeMapMemberAnyElement mem = map.DefaultAnyElementMember; if (mem.TypeData.IsListType) { AddListValue(mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, ReadXmlNode(mem.TypeData.ListItemTypeData, false), true); } else { SetMemberValue(mem, ob, ReadXmlNode(mem.TypeData, false), isValueList); } } else { ProcessUnknownElement(ob); } } else if ((Reader.NodeType == System.Xml.XmlNodeType.Text || Reader.NodeType == System.Xml.XmlNodeType.CDATA) && map.XmlTextCollector != null) { if (map.XmlTextCollector is XmlTypeMapMemberExpandable) { XmlTypeMapMemberExpandable mem = (XmlTypeMapMemberExpandable)map.XmlTextCollector; XmlTypeMapMemberFlatList flatl = mem as XmlTypeMapMemberFlatList; TypeData itype = (flatl == null) ? mem.TypeData.ListItemTypeData : flatl.ListMap.FindTextElement().TypeData; object val = (itype.Type == typeof(string)) ? (object)Reader.ReadString() : (object)ReadXmlNode(itype, false); AddListValue(mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, val, true); } else { XmlTypeMapMemberElement mem = (XmlTypeMapMemberElement)map.XmlTextCollector; XmlTypeMapElementInfo info = (XmlTypeMapElementInfo)mem.ElementInfo [0]; if (info.TypeData.Type == typeof(string)) { SetMemberValue(mem, ob, ReadString((string)GetMemberValue(mem, ob, isValueList)), isValueList); } else { SetMemberValue(mem, ob, GetValueFromXmlString(Reader.ReadString(), info.TypeData, info.MappedType), isValueList); } } } else { UnknownNode(ob); } Reader.MoveToContent(); } if (flatLists != null) { foreach (XmlTypeMapMemberExpandable mem in map.FlatLists) { Object list = flatLists[mem.FlatArrayIndex]; if (mem.TypeData.Type.IsArray) { list = ShrinkArray((Array)list, indexes[mem.FlatArrayIndex], mem.TypeData.Type.GetElementType(), true); } if (!IsReadOnly(mem, mem.TypeData, ob, isValueList) && mem.TypeData.Type.IsArray) { SetMemberValue(mem, ob, list, isValueList); } } } if (flatListsChoices != null) { foreach (XmlTypeMapMemberExpandable mem in map.FlatLists) { Object list = flatListsChoices[mem.FlatArrayIndex]; if (list == null) { continue; } list = ShrinkArray((Array)list, indexes[mem.FlatArrayIndex], mem.ChoiceTypeData.Type.GetElementType(), true); XmlTypeMapMember.SetValue(ob, mem.ChoiceMember, list); } } SetListMembersDefaults(map, ob, isValueList); }
public FixupCallbackInfo(XmlSerializationReaderInterpreter sri, ClassMap map, bool isValueList) { _sri = sri; _map = map; _isValueList = isValueList; }
void ExportMembersMapCode(CodeTypeDeclaration codeClass, ClassMap map, string defaultNamespace, XmlTypeMapping baseMap) { ICollection attributes = map.AttributeMembers; ICollection members = map.ElementMembers; // collect names if (attributes != null) { foreach (XmlTypeMapMemberAttribute attr in attributes) { identifiers.AddUnique(attr.Name, attr); } } if (members != null) { foreach (XmlTypeMapMemberElement member in members) { identifiers.AddUnique(member.Name, member); } } // Write attributes if (attributes != null) { foreach (XmlTypeMapMemberAttribute attr in attributes) { if (baseMap != null && DefinedInBaseMap(baseMap, attr)) { continue; } AddAttributeFieldMember(codeClass, attr, defaultNamespace); } } 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(XmlTypeMapMemberList)) { AddArrayElementFieldMember(codeClass, (XmlTypeMapMemberList)member, defaultNamespace); } else if (memType == typeof(XmlTypeMapMemberFlatList)) { AddElementFieldMember(codeClass, member, defaultNamespace); } else if (memType == typeof(XmlTypeMapMemberAnyElement)) { AddAnyElementFieldMember(codeClass, member, defaultNamespace); } else if (memType == typeof(XmlTypeMapMemberElement)) { AddElementFieldMember(codeClass, member, defaultNamespace); } else { throw new InvalidOperationException("Member type " + memType + " not supported"); } } } XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember; if (anyAttrMember != null) { CodeTypeMember codeField = CreateFieldMember(codeClass, anyAttrMember.TypeData, anyAttrMember.Name); AddComments(codeField, anyAttrMember.Documentation); codeField.Attributes = MemberAttributes.Public; GenerateAnyAttribute(codeField); } }
XmlTypeMapping ImportClassMapping(TypeData typeData, string defaultNamespace) { Type type = typeData.Type; if (type.IsValueType) { throw CreateStructException(type); } if (type == typeof(object)) { defaultNamespace = XmlSchema.Namespace; } ReflectionHelper.CheckSerializableType(type, false); XmlTypeMapping map = helper.GetRegisteredClrType(type, GetTypeNamespace(typeData, defaultNamespace)); if (map != null) { return(map); } map = CreateTypeMapping(typeData, null, defaultNamespace); helper.RegisterClrType(map, type, map.Namespace); map.MultiReferenceType = true; ClassMap classMap = new ClassMap(); map.ObjectMap = classMap; // Import members ICollection members = GetReflectionMembers(type); foreach (XmlReflectionMember rmember in members) { if (rmember.SoapAttributes.SoapIgnore) { continue; } classMap.AddMember(CreateMapMember(rmember, defaultNamespace)); } // Import included classes SoapIncludeAttribute[] includes = (SoapIncludeAttribute[])type.GetCustomAttributes(typeof(SoapIncludeAttribute), false); for (int n = 0; n < includes.Length; n++) { Type includedType = includes[n].Type; ImportTypeMapping(includedType); } if (type == typeof(object) && includedTypes != null) { foreach (Type intype in includedTypes) { map.DerivedTypes.Add(ImportTypeMapping(intype)); } } // Register inheritance relations if (type.BaseType != null) { XmlTypeMapping bmap = ImportClassMapping(type.BaseType, defaultNamespace); if (type.BaseType != typeof(object)) { map.BaseMap = bmap; } // At this point, derived classes of this map must be already registered RegisterDerivedMap(bmap, map); } return(map); }