private XmlTypeMapMember CreateMapMember (Type declaringType, XmlReflectionMember rmember, string defaultNamespace) { XmlTypeMapMember mapMember; XmlAttributes atts = rmember.XmlAttributes; TypeData typeData = TypeTranslator.GetTypeData (rmember.MemberType); if (atts.XmlArray != null) { if (atts.XmlArray.Namespace != null && atts.XmlArray.Form == XmlSchemaForm.Unqualified) throw new InvalidOperationException ("XmlArrayAttribute.Form must not be Unqualified when it has an explicit Namespace value."); if (typeData.SchemaType != SchemaTypes.Array && !(typeData.SchemaType == SchemaTypes.Primitive && typeData.Type == typeof (byte []))) throw new InvalidOperationException ("XmlArrayAttribute can be applied to members of array or collection type."); } #if !MOONLIGHT if (atts.XmlAnyAttribute != null) { if ( (rmember.MemberType.FullName == "System.Xml.XmlAttribute[]") || (rmember.MemberType.FullName == "System.Xml.XmlNode[]") ) { mapMember = new XmlTypeMapMemberAnyAttribute(); } else throw new InvalidOperationException ("XmlAnyAttributeAttribute can only be applied to members of type XmlAttribute[] or XmlNode[]"); } else #endif if (atts.XmlAnyElements != null && atts.XmlAnyElements.Count > 0) { // no XmlNode type check is done here (seealso: bug #553032). XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement(); member.ElementInfo = ImportAnyElementInfo (defaultNamespace, rmember, member, atts); mapMember = member; } else if (atts.Xmlns) { XmlTypeMapMemberNamespaces mapNamespaces = new XmlTypeMapMemberNamespaces (); mapMember = mapNamespaces; } else if (atts.XmlAttribute != null) { // An attribute if (atts.XmlElements != null && atts.XmlElements.Count > 0) throw new Exception ("XmlAttributeAttribute and XmlElementAttribute cannot be applied to the same member"); XmlTypeMapMemberAttribute mapAttribute = new XmlTypeMapMemberAttribute (); if (atts.XmlAttribute.AttributeName.Length == 0) mapAttribute.AttributeName = rmember.MemberName; else mapAttribute.AttributeName = atts.XmlAttribute.AttributeName; mapAttribute.AttributeName = XmlConvert.EncodeLocalName (mapAttribute.AttributeName); if (typeData.IsComplexType) mapAttribute.MappedType = ImportTypeMapping (typeData.Type, null, defaultNamespace); if (atts.XmlAttribute.Namespace != null && atts.XmlAttribute.Namespace != defaultNamespace) { if (atts.XmlAttribute.Form == XmlSchemaForm.Unqualified) throw new InvalidOperationException ("The Form property may not be 'Unqualified' when an explicit Namespace property is present"); mapAttribute.Form = XmlSchemaForm.Qualified; mapAttribute.Namespace = atts.XmlAttribute.Namespace; } else { mapAttribute.Form = atts.XmlAttribute.Form; if (atts.XmlAttribute.Form == XmlSchemaForm.Qualified) mapAttribute.Namespace = defaultNamespace; else mapAttribute.Namespace = ""; } typeData = TypeTranslator.GetTypeData(rmember.MemberType, atts.XmlAttribute.DataType); mapMember = mapAttribute; } else if (typeData.SchemaType == SchemaTypes.Array) { // If the member has a single XmlElementAttribute and the type is the type of the member, // then it is not a flat list if (atts.XmlElements.Count > 1 || (atts.XmlElements.Count == 1 && atts.XmlElements[0].Type != typeData.Type) || (atts.XmlText != null)) { // A flat list // check that it does not have XmlArrayAttribute if (atts.XmlArray != null) throw new InvalidOperationException ("XmlArrayAttribute cannot be used with members which also attributed with XmlElementAttribute or XmlTextAttribute."); XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList (); member.ListMap = new ListMap (); member.ListMap.ItemInfo = ImportElementInfo (declaringType, XmlConvert.EncodeLocalName (rmember.MemberName), defaultNamespace, typeData.ListItemType, member, atts); member.ElementInfo = member.ListMap.ItemInfo; member.ListMap.ChoiceMember = member.ChoiceMember; mapMember = member; } else { // A list XmlTypeMapMemberList member = new XmlTypeMapMemberList (); // Creates an ElementInfo that identifies the array instance. member.ElementInfo = new XmlTypeMapElementInfoList(); XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (member, typeData); elem.ElementName = XmlConvert.EncodeLocalName((atts.XmlArray != null && atts.XmlArray.ElementName.Length != 0) ? atts.XmlArray.ElementName : rmember.MemberName); // note that it could be changed below (when Form is Unqualified) elem.Namespace = (atts.XmlArray != null && atts.XmlArray.Namespace != null) ? atts.XmlArray.Namespace : defaultNamespace; elem.MappedType = ImportListMapping (rmember.MemberType, null, elem.Namespace, atts, 0); elem.IsNullable = (atts.XmlArray != null) ? atts.XmlArray.IsNullable : false; elem.Form = (atts.XmlArray != null) ? atts.XmlArray.Form : XmlSchemaForm.Qualified; // This is a bit tricky, but is done // after filling descendant members, so // that array items could be serialized // with proper namespace. if (atts.XmlArray != null && atts.XmlArray.Form == XmlSchemaForm.Unqualified) elem.Namespace = String.Empty; member.ElementInfo.Add (elem); mapMember = member; } } else { // An element XmlTypeMapMemberElement member = new XmlTypeMapMemberElement (); member.ElementInfo = ImportElementInfo (declaringType, XmlConvert.EncodeLocalName(rmember.MemberName), defaultNamespace, rmember.MemberType, member, atts); mapMember = member; } mapMember.DefaultValue = GetDefaultValue (typeData, atts.XmlDefaultValue); mapMember.TypeData = typeData; mapMember.Name = rmember.MemberName; mapMember.IsReturnValue = rmember.IsReturnValue; return mapMember; }
void AddTextMember (XmlQualifiedName typeQName, ClassMap cmap, CodeIdentifiers classIds) { if (cmap.XmlTextCollector == null) { XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList (); member.Name = classIds.AddUnique ("Text", member); member.TypeData = TypeTranslator.GetTypeData (typeof(string[])); member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData.ListItemTypeData)); member.IsXmlTextCollector = true; member.ListMap = new ListMap (); member.ListMap.ItemInfo = member.ElementInfo; cmap.AddMember (member); } }
void ImportSequenceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection items, CodeIdentifiers classIds, bool multiValue, ref bool isMixed) { foreach (XmlSchemaObject item in items) { if (item is XmlSchemaElement) { string ns; XmlSchemaElement elem = (XmlSchemaElement) item; XmlTypeMapping emap; TypeData typeData = GetElementTypeData (typeQName, elem, null, out emap); XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns); if (elem.MaxOccurs == 1 && !multiValue) { XmlTypeMapMemberElement member = null; if (typeData.SchemaType != SchemaTypes.Array) { member = new XmlTypeMapMemberElement (); if (refElem.DefaultValue != null) member.DefaultValue = ImportDefaultValue (typeData, refElem.DefaultValue); } else if (GetTypeMapping (typeData).IsSimpleType) { // It is a simple list (space separated list). // Since this is not supported, map as a single item value member = new XmlTypeMapMemberElement (); #if NET_2_0 // In MS.NET those types are mapped to a string typeData = TypeTranslator.GetTypeData(typeof(string)); #else typeData = typeData.ListItemTypeData; #endif } else member = new XmlTypeMapMemberList (); if (elem.MinOccurs == 0 && typeData.IsValueType) member.IsOptionalValueType = true; member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member); member.Documentation = GetDocumentation (elem); member.TypeData = typeData; member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap, items.IndexOf (item))); cmap.AddMember (member); } else { XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList (); member.ListMap = new ListMap (); member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member); member.Documentation = GetDocumentation (elem); member.TypeData = typeData.ListTypeData; member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap, items.IndexOf (item))); member.ListMap.ItemInfo = member.ElementInfo; cmap.AddMember (member); } } else if (item is XmlSchemaAny) { XmlSchemaAny elem = (XmlSchemaAny) item; XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement (); member.Name = classIds.AddUnique ("Any", member); member.Documentation = GetDocumentation (elem); Type ctype; if (elem.MaxOccurs != 1 || multiValue) ctype = isMixed ? typeof(XmlNode[]) : typeof(XmlElement[]); else ctype = isMixed ? typeof(XmlNode) : typeof(XmlElement); member.TypeData = TypeTranslator.GetTypeData (ctype); XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, member.TypeData); einfo.IsUnnamedAnyElement = true; member.ElementInfo.Add (einfo); if (isMixed) { einfo = CreateTextElementInfo (typeQName.Namespace, member, member.TypeData); member.ElementInfo.Add (einfo); member.IsXmlTextCollector = true; isMixed = false; //Allow only one XmlTextAttribute } cmap.AddMember (member); } else if (item is XmlSchemaParticle) { ImportParticleContent (typeQName, cmap, (XmlSchemaParticle)item, classIds, multiValue, ref isMixed); } } }
private XmlTypeMapMember CreateMapMember(XmlReflectionMember rmember, string defaultNamespace) { XmlTypeMapMember mapMember; XmlAttributes atts = rmember.XmlAttributes; TypeData typeData = TypeTranslator.GetTypeData(rmember.MemberType); if (atts.XmlAnyAttribute != null) { if ((rmember.MemberType.FullName == "System.Xml.XmlAttribute[]") || (rmember.MemberType.FullName == "System.Xml.XmlNode[]")) { mapMember = new XmlTypeMapMemberAnyAttribute(); } else { throw new InvalidOperationException("XmlAnyAttributeAttribute can only be applied to members of type XmlAttribute[] or XmlNode[]"); } } else if (atts.XmlAnyElements != null && atts.XmlAnyElements.Count > 0) { if ((rmember.MemberType.FullName == "System.Xml.XmlElement[]") || (rmember.MemberType.FullName == "System.Xml.XmlNode[]") || (rmember.MemberType.FullName == "System.Xml.XmlElement")) { XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement(); member.ElementInfo = ImportAnyElementInfo(defaultNamespace, rmember, member, atts); mapMember = member; } else { throw new InvalidOperationException("XmlAnyElementAttribute can only be applied to members of type XmlElement, XmlElement[] or XmlNode[]"); } } else if (atts.Xmlns) { XmlTypeMapMemberNamespaces mapNamespaces = new XmlTypeMapMemberNamespaces(); mapMember = mapNamespaces; } else if (atts.XmlAttribute != null) { // An attribute if (atts.XmlElements != null && atts.XmlElements.Count > 0) { throw new Exception("XmlAttributeAttribute and XmlElementAttribute cannot be applied to the same member"); } XmlTypeMapMemberAttribute mapAttribute = new XmlTypeMapMemberAttribute(); if (atts.XmlAttribute.AttributeName == null) { mapAttribute.AttributeName = rmember.MemberName; } else { mapAttribute.AttributeName = atts.XmlAttribute.AttributeName; } if (typeData.IsComplexType) { mapAttribute.MappedType = ImportTypeMapping(typeData.Type, null, mapAttribute.Namespace); } if (atts.XmlAttribute.Namespace != null && atts.XmlAttribute.Namespace != defaultNamespace) { if (atts.XmlAttribute.Form == XmlSchemaForm.Unqualified) { throw new InvalidOperationException("The Form property may not be 'Unqualified' when an explicit Namespace property is present"); } mapAttribute.Form = XmlSchemaForm.Qualified; mapAttribute.Namespace = atts.XmlAttribute.Namespace; } else { mapAttribute.Form = atts.XmlAttribute.Form; if (atts.XmlAttribute.Form == XmlSchemaForm.Qualified) { mapAttribute.Namespace = defaultNamespace; } else { mapAttribute.Namespace = ""; } } typeData = TypeTranslator.GetTypeData(rmember.MemberType, atts.XmlAttribute.DataType); mapMember = mapAttribute; } else if (typeData.SchemaType == SchemaTypes.Array) { // If the member has a single XmlElementAttribute and the type is the type of the member, // then it is not a flat list if (atts.XmlElements.Count > 1 || (atts.XmlElements.Count == 1 && atts.XmlElements[0].Type != typeData.Type) || (atts.XmlText != null)) { // A flat list // TODO: check that it does not have XmlArrayAttribute XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList(); member.ListMap = new ListMap(); member.ListMap.ItemInfo = ImportElementInfo(rmember.MemberName, defaultNamespace, typeData.ListItemType, member, atts); member.ElementInfo = member.ListMap.ItemInfo; mapMember = member; } else { // A list XmlTypeMapMemberList member = new XmlTypeMapMemberList(); // Creates an ElementInfo that identifies the array instance. member.ElementInfo = new XmlTypeMapElementInfoList(); XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo(member, typeData); elem.ElementName = (atts.XmlArray != null && atts.XmlArray.ElementName != null) ? atts.XmlArray.ElementName : rmember.MemberName; elem.Namespace = (atts.XmlArray != null && atts.XmlArray.Namespace != null) ? atts.XmlArray.Namespace : defaultNamespace; elem.MappedType = ImportListMapping(rmember.MemberType, null, elem.Namespace, atts, 0); elem.IsNullable = (atts.XmlArray != null) ? atts.XmlArray.IsNullable : false; elem.Form = (atts.XmlArray != null) ? atts.XmlArray.Form : XmlSchemaForm.Qualified; member.ElementInfo.Add(elem); mapMember = member; } } else { // An element XmlTypeMapMemberElement member = new XmlTypeMapMemberElement(); member.ElementInfo = ImportElementInfo(rmember.MemberName, defaultNamespace, rmember.MemberType, member, atts); mapMember = member; } mapMember.DefaultValue = atts.XmlDefaultValue; mapMember.TypeData = typeData; mapMember.Name = rmember.MemberName; mapMember.IsReturnValue = rmember.IsReturnValue; return(mapMember); }
void ImportChoiceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaChoice choice, CodeIdentifiers classIds, bool multiValue) { XmlTypeMapElementInfoList choices = new XmlTypeMapElementInfoList (); multiValue = ImportChoices (typeQName, null, choices, choice.Items) || multiValue; if (choices.Count == 0) return; if (choice.MaxOccurs > 1) multiValue = true; XmlTypeMapMemberElement member; if (multiValue) { member = new XmlTypeMapMemberFlatList (); member.Name = classIds.AddUnique ("Items", member); ListMap listMap = new ListMap (); listMap.ItemInfo = choices; ((XmlTypeMapMemberFlatList)member).ListMap = listMap; } else { member = new XmlTypeMapMemberElement (); member.Name = classIds.AddUnique ("Item", member); } // If all choices have the same type, use that type for the member. // If not use System.Object. // If there are at least two choices with the same type, use a choice // identifier attribute TypeData typeData = null; bool twoEqual = false; bool allEqual = true; Hashtable types = new Hashtable (); for (int n = choices.Count - 1; n >= 0; n--) { XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) choices [n]; // In some complex schemas, we may end up with several options // with the same name. It is better to ignore the extra options // than to crash. It's the best we can do, and btw it works // better than in MS.NET. if (cmap.GetElement (einfo.ElementName, einfo.Namespace, einfo.ExplicitOrder) != null || choices.IndexOfElement (einfo.ElementName, einfo.Namespace) != n) { choices.RemoveAt (n); continue; } if (types.ContainsKey (einfo.TypeData)) twoEqual = true; else types.Add (einfo.TypeData, einfo); TypeData choiceType = einfo.TypeData; if (choiceType.SchemaType == SchemaTypes.Class) { // When comparing class types, use the most generic class in the // inheritance hierarchy XmlTypeMapping choiceMap = GetTypeMapping (choiceType); BuildPendingMap (choiceMap); while (choiceMap.BaseMap != null) { choiceMap = choiceMap.BaseMap; BuildPendingMap (choiceMap); choiceType = choiceMap.TypeData; } } if (typeData == null) typeData = choiceType; else if (typeData != choiceType) allEqual = false; } if (!allEqual) typeData = TypeTranslator.GetTypeData (typeof(object)); if (twoEqual) { // Create the choice member XmlTypeMapMemberElement choiceMember = new XmlTypeMapMemberElement (); choiceMember.Ignore = true; choiceMember.Name = classIds.AddUnique (member.Name + "ElementName", choiceMember); member.ChoiceMember = choiceMember.Name; // Create the choice enum XmlTypeMapping enumMap = CreateTypeMapping (new XmlQualifiedName (member.Name + "ChoiceType", typeQName.Namespace), SchemaTypes.Enum, null); enumMap.IncludeInSchema = false; CodeIdentifiers codeIdents = new CodeIdentifiers (); EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [choices.Count]; for (int n=0; n<choices.Count; n++) { XmlTypeMapElementInfo it =(XmlTypeMapElementInfo) choices[n]; bool extraNs = (it.Namespace != null && it.Namespace != "" && it.Namespace != typeQName.Namespace); string xmlName = extraNs ? it.Namespace + ":" + it.ElementName : it.ElementName; string enumName = codeIdents.AddUnique (CodeIdentifier.MakeValid (it.ElementName), it); members [n] = new EnumMap.EnumMapMember (xmlName, enumName); } enumMap.ObjectMap = new EnumMap (members, false); choiceMember.TypeData = multiValue ? enumMap.TypeData.ListTypeData : enumMap.TypeData; choiceMember.ElementInfo.Add (CreateElementInfo (typeQName.Namespace, choiceMember, choiceMember.Name, choiceMember.TypeData, false, XmlSchemaForm.None, -1)); cmap.AddMember (choiceMember); } if (typeData == null) return; if (multiValue) typeData = typeData.ListTypeData; member.ElementInfo = choices; member.Documentation = GetDocumentation (choice); member.TypeData = typeData; cmap.AddMember (member); }
void ReadMembers(ClassMap map, object ob, bool isValueList, bool readBySoapOrder) { // 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 = -1; int maxInd; if (readBySoapOrder) { if (map.ElementMembers != null) { maxInd = map.ElementMembers.Count; } else { maxInd = -1; } } 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); } XmlTypeMapMember previousMember = null; while (Reader.NodeType != System.Xml.XmlNodeType.EndElement && (ind < maxInd - 1)) { if (Reader.NodeType == System.Xml.XmlNodeType.Element) { XmlTypeMapElementInfo info; if (readBySoapOrder) { info = map.GetElement(Reader.LocalName, Reader.NamespaceURI, ind); } else if (hasAnyReturnMember) { info = (XmlTypeMapElementInfo)((XmlTypeMapMemberElement)map.ReturnMember).ElementInfo[0]; hasAnyReturnMember = false; } else { if (map.IsOrderDependentMap) { info = map.GetElement(Reader.LocalName, Reader.NamespaceURI, ind); } else { info = map.GetElement(Reader.LocalName, Reader.NamespaceURI); } } if (info != null && !readFlag[info.Member.Index]) { if (info.Member != previousMember) { ind = info.ExplicitOrder + 1; // If the member is a flat list don't increase the index, since the next element may // be another item of the list. This is a fix for Xamarin bug #9193. if (info.Member is XmlTypeMapMemberFlatList) { ind--; } previousMember = info.Member; } 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); }
void ImportParticleComplexContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool isMixed) { ImportParticleContent (typeQName, cmap, particle, classIds, false, ref isMixed); if (isMixed && cmap.XmlTextCollector == null) { XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList (); member.Name = classIds.AddUnique ("Text", member); member.TypeData = TypeTranslator.GetTypeData (typeof(string[])); member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData.ListItemTypeData)); member.IsXmlTextCollector = true; member.ListMap = new ListMap (); member.ListMap.ItemInfo = member.ElementInfo; cmap.AddMember (member); } }
private void ReadMembers(ClassMap map, object ob, bool isValueList, bool readByOrder) { this.ReadAttributeMembers(map, ob, isValueList); if (!isValueList) { base.Reader.MoveToElement(); if (base.Reader.IsEmptyElement) { this.SetListMembersDefaults(map, ob, isValueList); return; } base.Reader.ReadStartElement(); } bool[] array = new bool[(map.ElementMembers == null) ? 0 : map.ElementMembers.Count]; bool flag = isValueList && this._format == SerializationFormat.Encoded && map.ReturnMember != null; base.Reader.MoveToContent(); int[] array2 = null; object[] array3 = null; object[] array4 = null; XmlSerializationReader.Fixup fixup = null; int num = 0; int num2; if (readByOrder) { if (map.ElementMembers != null) { num2 = map.ElementMembers.Count; } else { num2 = 0; } } else { num2 = int.MaxValue; } if (map.FlatLists != null) { array2 = new int[map.FlatLists.Count]; array3 = new object[map.FlatLists.Count]; foreach (object obj in map.FlatLists) { XmlTypeMapMemberExpandable xmlTypeMapMemberExpandable = (XmlTypeMapMemberExpandable)obj; if (this.IsReadOnly(xmlTypeMapMemberExpandable, xmlTypeMapMemberExpandable.TypeData, ob, isValueList)) { array3[xmlTypeMapMemberExpandable.FlatArrayIndex] = xmlTypeMapMemberExpandable.GetValue(ob); } else if (xmlTypeMapMemberExpandable.TypeData.Type.IsArray) { array3[xmlTypeMapMemberExpandable.FlatArrayIndex] = this.InitializeList(xmlTypeMapMemberExpandable.TypeData); } else { object obj2 = xmlTypeMapMemberExpandable.GetValue(ob); if (obj2 == null) { obj2 = this.InitializeList(xmlTypeMapMemberExpandable.TypeData); this.SetMemberValue(xmlTypeMapMemberExpandable, ob, obj2, isValueList); } array3[xmlTypeMapMemberExpandable.FlatArrayIndex] = obj2; } if (xmlTypeMapMemberExpandable.ChoiceMember != null) { if (array4 == null) { array4 = new object[map.FlatLists.Count]; } array4[xmlTypeMapMemberExpandable.FlatArrayIndex] = this.InitializeList(xmlTypeMapMemberExpandable.ChoiceTypeData); } } } if (this._format == SerializationFormat.Encoded && map.ElementMembers != null) { XmlSerializationReaderInterpreter.FixupCallbackInfo @object = new XmlSerializationReaderInterpreter.FixupCallbackInfo(this, map, isValueList); fixup = new XmlSerializationReader.Fixup(ob, new XmlSerializationFixupCallback(@object.FixupMembers), map.ElementMembers.Count); base.AddFixup(fixup); } while (base.Reader.NodeType != XmlNodeType.EndElement && num < num2) { if (base.Reader.NodeType == XmlNodeType.Element) { XmlTypeMapElementInfo xmlTypeMapElementInfo; if (readByOrder) { xmlTypeMapElementInfo = map.GetElement(num++); } else if (flag) { xmlTypeMapElementInfo = (XmlTypeMapElementInfo)((XmlTypeMapMemberElement)map.ReturnMember).ElementInfo[0]; flag = false; } else { xmlTypeMapElementInfo = map.GetElement(base.Reader.LocalName, base.Reader.NamespaceURI); } if (xmlTypeMapElementInfo != null && !array[xmlTypeMapElementInfo.Member.Index]) { if (xmlTypeMapElementInfo.Member.GetType() == typeof(XmlTypeMapMemberList)) { if (this._format == SerializationFormat.Encoded && xmlTypeMapElementInfo.MultiReferenceType) { object obj3 = base.ReadReferencingElement(out fixup.Ids[xmlTypeMapElementInfo.Member.Index]); if (fixup.Ids[xmlTypeMapElementInfo.Member.Index] == null) { if (this.IsReadOnly(xmlTypeMapElementInfo.Member, xmlTypeMapElementInfo.TypeData, ob, isValueList)) { throw base.CreateReadOnlyCollectionException(xmlTypeMapElementInfo.TypeData.FullTypeName); } this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj3, isValueList); } else if (!xmlTypeMapElementInfo.MappedType.TypeData.Type.IsArray) { if (this.IsReadOnly(xmlTypeMapElementInfo.Member, xmlTypeMapElementInfo.TypeData, ob, isValueList)) { obj3 = this.GetMemberValue(xmlTypeMapElementInfo.Member, ob, isValueList); } else { obj3 = this.CreateList(xmlTypeMapElementInfo.MappedType.TypeData.Type); this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj3, isValueList); } base.AddFixup(new XmlSerializationReader.CollectionFixup(obj3, new XmlSerializationCollectionFixupCallback(this.FillList), fixup.Ids[xmlTypeMapElementInfo.Member.Index])); fixup.Ids[xmlTypeMapElementInfo.Member.Index] = null; } } else if (this.IsReadOnly(xmlTypeMapElementInfo.Member, xmlTypeMapElementInfo.TypeData, ob, isValueList)) { this.ReadListElement(xmlTypeMapElementInfo.MappedType, xmlTypeMapElementInfo.IsNullable, this.GetMemberValue(xmlTypeMapElementInfo.Member, ob, isValueList), false); } else if (xmlTypeMapElementInfo.MappedType.TypeData.Type.IsArray) { object obj4 = this.ReadListElement(xmlTypeMapElementInfo.MappedType, xmlTypeMapElementInfo.IsNullable, null, true); if (obj4 != null || xmlTypeMapElementInfo.IsNullable) { this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj4, isValueList); } } else { object obj5 = this.GetMemberValue(xmlTypeMapElementInfo.Member, ob, isValueList); if (obj5 == null) { obj5 = this.CreateList(xmlTypeMapElementInfo.MappedType.TypeData.Type); this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj5, isValueList); } this.ReadListElement(xmlTypeMapElementInfo.MappedType, xmlTypeMapElementInfo.IsNullable, obj5, true); } array[xmlTypeMapElementInfo.Member.Index] = true; } else if (xmlTypeMapElementInfo.Member.GetType() == typeof(XmlTypeMapMemberFlatList)) { XmlTypeMapMemberFlatList xmlTypeMapMemberFlatList = (XmlTypeMapMemberFlatList)xmlTypeMapElementInfo.Member; this.AddListValue(xmlTypeMapMemberFlatList.TypeData, ref array3[xmlTypeMapMemberFlatList.FlatArrayIndex], array2[xmlTypeMapMemberFlatList.FlatArrayIndex]++, this.ReadObjectElement(xmlTypeMapElementInfo), !this.IsReadOnly(xmlTypeMapElementInfo.Member, xmlTypeMapElementInfo.TypeData, ob, isValueList)); if (xmlTypeMapMemberFlatList.ChoiceMember != null) { this.AddListValue(xmlTypeMapMemberFlatList.ChoiceTypeData, ref array4[xmlTypeMapMemberFlatList.FlatArrayIndex], array2[xmlTypeMapMemberFlatList.FlatArrayIndex] - 1, xmlTypeMapElementInfo.ChoiceValue, true); } } else if (xmlTypeMapElementInfo.Member.GetType() == typeof(XmlTypeMapMemberAnyElement)) { XmlTypeMapMemberAnyElement xmlTypeMapMemberAnyElement = (XmlTypeMapMemberAnyElement)xmlTypeMapElementInfo.Member; if (xmlTypeMapMemberAnyElement.TypeData.IsListType) { this.AddListValue(xmlTypeMapMemberAnyElement.TypeData, ref array3[xmlTypeMapMemberAnyElement.FlatArrayIndex], array2[xmlTypeMapMemberAnyElement.FlatArrayIndex]++, this.ReadXmlNode(xmlTypeMapMemberAnyElement.TypeData.ListItemTypeData, false), true); } else { this.SetMemberValue(xmlTypeMapMemberAnyElement, ob, this.ReadXmlNode(xmlTypeMapMemberAnyElement.TypeData, false), isValueList); } } else { if (xmlTypeMapElementInfo.Member.GetType() != typeof(XmlTypeMapMemberElement)) { throw new InvalidOperationException("Unknown member type"); } array[xmlTypeMapElementInfo.Member.Index] = true; if (this._format == SerializationFormat.Encoded) { object obj6; if (xmlTypeMapElementInfo.Member.TypeData.SchemaType != SchemaTypes.Primitive) { obj6 = base.ReadReferencingElement(out fixup.Ids[xmlTypeMapElementInfo.Member.Index]); } else { obj6 = base.ReadReferencingElement(xmlTypeMapElementInfo.Member.TypeData.XmlType, "http://www.w3.org/2001/XMLSchema", out fixup.Ids[xmlTypeMapElementInfo.Member.Index]); } if (xmlTypeMapElementInfo.MultiReferenceType) { if (fixup.Ids[xmlTypeMapElementInfo.Member.Index] == null) { this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj6, isValueList); } } else if (obj6 != null) { this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj6, isValueList); } } else { this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, this.ReadObjectElement(xmlTypeMapElementInfo), isValueList); if (xmlTypeMapElementInfo.ChoiceValue != null) { XmlTypeMapMemberElement xmlTypeMapMemberElement = (XmlTypeMapMemberElement)xmlTypeMapElementInfo.Member; xmlTypeMapMemberElement.SetChoice(ob, xmlTypeMapElementInfo.ChoiceValue); } } } } else if (map.DefaultAnyElementMember != null) { XmlTypeMapMemberAnyElement defaultAnyElementMember = map.DefaultAnyElementMember; if (defaultAnyElementMember.TypeData.IsListType) { this.AddListValue(defaultAnyElementMember.TypeData, ref array3[defaultAnyElementMember.FlatArrayIndex], array2[defaultAnyElementMember.FlatArrayIndex]++, this.ReadXmlNode(defaultAnyElementMember.TypeData.ListItemTypeData, false), true); } else { this.SetMemberValue(defaultAnyElementMember, ob, this.ReadXmlNode(defaultAnyElementMember.TypeData, false), isValueList); } } else { this.ProcessUnknownElement(ob); } } else if ((base.Reader.NodeType == XmlNodeType.Text || base.Reader.NodeType == XmlNodeType.CDATA) && map.XmlTextCollector != null) { if (map.XmlTextCollector is XmlTypeMapMemberExpandable) { XmlTypeMapMemberExpandable xmlTypeMapMemberExpandable2 = (XmlTypeMapMemberExpandable)map.XmlTextCollector; XmlTypeMapMemberFlatList xmlTypeMapMemberFlatList2 = xmlTypeMapMemberExpandable2 as XmlTypeMapMemberFlatList; TypeData typeData = (xmlTypeMapMemberFlatList2 != null) ? xmlTypeMapMemberFlatList2.ListMap.FindTextElement().TypeData : xmlTypeMapMemberExpandable2.TypeData.ListItemTypeData; object value = (typeData.Type != typeof(string)) ? this.ReadXmlNode(typeData, false) : base.Reader.ReadString(); this.AddListValue(xmlTypeMapMemberExpandable2.TypeData, ref array3[xmlTypeMapMemberExpandable2.FlatArrayIndex], array2[xmlTypeMapMemberExpandable2.FlatArrayIndex]++, value, true); } else { XmlTypeMapMemberElement xmlTypeMapMemberElement2 = (XmlTypeMapMemberElement)map.XmlTextCollector; XmlTypeMapElementInfo xmlTypeMapElementInfo2 = (XmlTypeMapElementInfo)xmlTypeMapMemberElement2.ElementInfo[0]; if (xmlTypeMapElementInfo2.TypeData.Type == typeof(string)) { this.SetMemberValue(xmlTypeMapMemberElement2, ob, base.ReadString((string)this.GetMemberValue(xmlTypeMapMemberElement2, ob, isValueList)), isValueList); } else { this.SetMemberValue(xmlTypeMapMemberElement2, ob, this.GetValueFromXmlString(base.Reader.ReadString(), xmlTypeMapElementInfo2.TypeData, xmlTypeMapElementInfo2.MappedType), isValueList); } } } else { base.UnknownNode(ob); } base.Reader.MoveToContent(); } if (array3 != null) { foreach (object obj7 in map.FlatLists) { XmlTypeMapMemberExpandable xmlTypeMapMemberExpandable3 = (XmlTypeMapMemberExpandable)obj7; object obj8 = array3[xmlTypeMapMemberExpandable3.FlatArrayIndex]; if (xmlTypeMapMemberExpandable3.TypeData.Type.IsArray) { obj8 = base.ShrinkArray((Array)obj8, array2[xmlTypeMapMemberExpandable3.FlatArrayIndex], xmlTypeMapMemberExpandable3.TypeData.Type.GetElementType(), true); } if (!this.IsReadOnly(xmlTypeMapMemberExpandable3, xmlTypeMapMemberExpandable3.TypeData, ob, isValueList) && xmlTypeMapMemberExpandable3.TypeData.Type.IsArray) { this.SetMemberValue(xmlTypeMapMemberExpandable3, ob, obj8, isValueList); } } } if (array4 != null) { foreach (object obj9 in map.FlatLists) { XmlTypeMapMemberExpandable xmlTypeMapMemberExpandable4 = (XmlTypeMapMemberExpandable)obj9; object obj10 = array4[xmlTypeMapMemberExpandable4.FlatArrayIndex]; if (obj10 != null) { obj10 = base.ShrinkArray((Array)obj10, array2[xmlTypeMapMemberExpandable4.FlatArrayIndex], xmlTypeMapMemberExpandable4.ChoiceTypeData.Type.GetElementType(), true); XmlTypeMapMember.SetValue(ob, xmlTypeMapMemberExpandable4.ChoiceMember, obj10); } } } this.SetListMembersDefaults(map, ob, isValueList); }
private XmlTypeMapMember CreateMapMember (XmlReflectionMember rmember, string defaultNamespace) { XmlTypeMapMember mapMember; XmlAttributes atts = rmember.XmlAttributes; TypeData typeData = TypeTranslator.GetTypeData (rmember.MemberType); if (atts.XmlAnyAttribute != null) { if ( (rmember.MemberType.FullName == "System.Xml.XmlAttribute[]") || (rmember.MemberType.FullName == "System.Xml.XmlNode[]") ) { mapMember = new XmlTypeMapMemberAnyAttribute(); } else throw new InvalidOperationException ("XmlAnyAttributeAttribute can only be applied to members of type XmlAttribute[] or XmlNode[]"); } else if (atts.XmlAnyElements != null && atts.XmlAnyElements.Count > 0) { if ( (rmember.MemberType.FullName == "System.Xml.XmlElement[]") || (rmember.MemberType.FullName == "System.Xml.XmlNode[]") || (rmember.MemberType.FullName == "System.Xml.XmlElement")) { XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement(); member.ElementInfo = ImportAnyElementInfo (defaultNamespace, rmember, member, atts); mapMember = member; } else throw new InvalidOperationException ("XmlAnyElementAttribute can only be applied to members of type XmlElement, XmlElement[] or XmlNode[]"); } else if (atts.Xmlns) { XmlTypeMapMemberNamespaces mapNamespaces = new XmlTypeMapMemberNamespaces (); mapMember = mapNamespaces; } else if (atts.XmlAttribute != null) { // An attribute if (atts.XmlElements != null && atts.XmlElements.Count > 0) throw new Exception ("XmlAttributeAttribute and XmlElementAttribute cannot be applied to the same member"); XmlTypeMapMemberAttribute mapAttribute = new XmlTypeMapMemberAttribute (); if (atts.XmlAttribute.AttributeName == null) mapAttribute.AttributeName = rmember.MemberName; else mapAttribute.AttributeName = atts.XmlAttribute.AttributeName; if (typeData.IsComplexType) mapAttribute.MappedType = ImportTypeMapping (typeData.Type, null, mapAttribute.Namespace); if (atts.XmlAttribute.Namespace != null && atts.XmlAttribute.Namespace != defaultNamespace) { if (atts.XmlAttribute.Form == XmlSchemaForm.Unqualified) throw new InvalidOperationException ("The Form property may not be 'Unqualified' when an explicit Namespace property is present"); mapAttribute.Form = XmlSchemaForm.Qualified; mapAttribute.Namespace = atts.XmlAttribute.Namespace; } else { mapAttribute.Form = atts.XmlAttribute.Form; if (atts.XmlAttribute.Form == XmlSchemaForm.Qualified) mapAttribute.Namespace = defaultNamespace; else mapAttribute.Namespace = ""; } typeData = TypeTranslator.GetTypeData(rmember.MemberType, atts.XmlAttribute.DataType); mapMember = mapAttribute; } else if (typeData.SchemaType == SchemaTypes.Array) { // If the member has a single XmlElementAttribute and the type is the type of the member, // then it is not a flat list if (atts.XmlElements.Count > 1 || (atts.XmlElements.Count == 1 && atts.XmlElements[0].Type != typeData.Type) || (atts.XmlText != null)) { // A flat list // TODO: check that it does not have XmlArrayAttribute XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList (); member.ListMap = new ListMap (); member.ListMap.ItemInfo = ImportElementInfo (rmember.MemberName, defaultNamespace, typeData.ListItemType, member, atts); member.ElementInfo = member.ListMap.ItemInfo; mapMember = member; } else { // A list XmlTypeMapMemberList member = new XmlTypeMapMemberList (); // Creates an ElementInfo that identifies the array instance. member.ElementInfo = new XmlTypeMapElementInfoList(); XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (member, typeData); elem.ElementName = (atts.XmlArray != null && atts.XmlArray.ElementName != null) ? atts.XmlArray.ElementName : rmember.MemberName; elem.Namespace = (atts.XmlArray != null && atts.XmlArray.Namespace != null) ? atts.XmlArray.Namespace : defaultNamespace; elem.MappedType = ImportListMapping (rmember.MemberType, null, elem.Namespace, atts, 0); elem.IsNullable = (atts.XmlArray != null) ? atts.XmlArray.IsNullable : false; elem.Form = (atts.XmlArray != null) ? atts.XmlArray.Form : XmlSchemaForm.Qualified; member.ElementInfo.Add (elem); mapMember = member; } } else { // An element XmlTypeMapMemberElement member = new XmlTypeMapMemberElement (); member.ElementInfo = ImportElementInfo (rmember.MemberName, defaultNamespace, rmember.MemberType, member, atts); mapMember = member; } mapMember.DefaultValue = atts.XmlDefaultValue; mapMember.TypeData = typeData; mapMember.Name = rmember.MemberName; mapMember.IsReturnValue = rmember.IsReturnValue; return mapMember; }
void ReadMembers(ClassMap map, object ob, bool isValueList, bool readByOrder) { // Set the default values of the members if (map.MembersWithDefault != null) { ArrayList members = map.MembersWithDefault; for (int n = 0; n < members.Count; n++) { XmlTypeMapMember mem = (XmlTypeMapMember)members[n]; SetMemberValueFromAttr(mem, ob, mem.DefaultValue, isValueList); } } // Reads attributes XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember; int anyAttributeIndex = 0; object anyAttributeArray = null; while (Reader.MoveToNextAttribute()) { XmlTypeMapMemberAttribute member = map.GetAttribute(Reader.LocalName, Reader.NamespaceURI); if (member != null) { SetMemberValue(member, ob, GetValueFromXmlString(Reader.Value, member.TypeData, member.MappedType), isValueList); } else if (IsXmlnsAttribute(Reader.Name)) { // If the map has NamespaceDeclarations, // then store this xmlns to the given member. // If the instance doesn't exist, then create. if (map.NamespaceDeclarations != null) { XmlSerializerNamespaces nss = this.GetMemberValue(map.NamespaceDeclarations, ob, isValueList) as XmlSerializerNamespaces; if (nss == null) { nss = new XmlSerializerNamespaces(); SetMemberValue(map.NamespaceDeclarations, ob, nss, isValueList); } if (Reader.Prefix == "xmlns") { nss.Add(Reader.LocalName, Reader.Value); } else { nss.Add("", Reader.Value); } } } else if (anyAttrMember != null) { XmlAttribute attr = (XmlAttribute)Document.ReadNode(Reader); ParseWsdlArrayType(attr); AddListValue(anyAttrMember.TypeData, ref anyAttributeArray, anyAttributeIndex++, attr, true); } else { ProcessUnknownAttribute(ob); } } if (anyAttrMember != null) { anyAttributeArray = ShrinkArray((Array)anyAttributeArray, anyAttributeIndex, anyAttrMember.TypeData.Type.GetElementType(), true); SetMemberValue(anyAttrMember, ob, anyAttributeArray, 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); }