private void WriteMembers(ref object o, Member[] members, UnknownNodeAction elementElseAction, UnknownNodeAction elseAction, Member anyElement, Member anyText) { Reader.MoveToContent(); var collectionMemberToBeSet = new HashSet <Member>(); while (Reader.NodeType != XmlNodeType.EndElement && Reader.NodeType != XmlNodeType.None) { object value = null; Member member; WriteMemberElements(ref value, null, out member, members, elementElseAction, elseAction, anyElement, anyText, masterObject: o); if (member != null) { PropertyInfo pi = member.Mapping.MemberInfo as PropertyInfo; if (pi != null && typeof(IList).IsAssignableFrom(pi.PropertyType) && (pi.SetMethod == null || !pi.SetMethod.IsPublic)) { var getOnlyList = (IList)pi.GetValue(o); var valueList = value as IList; if (valueList != null) { foreach (var i in valueList) { getOnlyList.Add(i); } } else { getOnlyList.Add(value); } } else if (member.Collection != null) { member.Collection.Add(value); collectionMemberToBeSet.Add(member); } else { SetMemberValue(o, value, member.Mapping.Name); } } Reader.MoveToContent(); } foreach (var member in collectionMemberToBeSet) { if (member.Collection != null) { MemberInfo[] memberInfos = o.GetType().GetMember(member.Mapping.Name); var memberInfo = memberInfos[0]; object collection = null; SetCollectionObjectWithCollectionMember(ref collection, member.Collection, member.Mapping.TypeDesc.Type); SetMemberValue(o, collection, memberInfo); } } }
private void ProcessUnknownNode(UnknownNodeAction action) { if (UnknownNodeAction.ReadUnknownNode == action) { UnknownNode(null); } else { CreateUnknownNodeException(); } }
private void WriteArray(ref object o, ArrayMapping arrayMapping, bool readOnly, bool isNullable, string defaultNamespace) { if (arrayMapping.IsSoap) { throw new PlatformNotSupportedException("arrayMapping.IsSoap"); } else { if (!ReadNull()) { MemberMapping memberMapping = new MemberMapping(); memberMapping.Elements = arrayMapping.Elements; memberMapping.TypeDesc = arrayMapping.TypeDesc; memberMapping.ReadOnly = readOnly; Type collectionType = memberMapping.TypeDesc.Type; if (o == null) { o = ReflectionCreateObject(memberMapping.TypeDesc.Type); } if (memberMapping.ChoiceIdentifier != null) { // #10588: To Support ArrayMapping Types Having ChoiceIdentifier throw new NotImplementedException("memberMapping.ChoiceIdentifier != null"); } var collectionMember = new CollectionMember(); if ((readOnly && o == null) || Reader.IsEmptyElement) { Reader.Skip(); } else { Reader.ReadStartElement(); Reader.MoveToContent(); UnknownNodeAction unknownNode = UnknownNodeAction.ReadUnknownNode; while (Reader.NodeType != XmlNodeType.EndElement && Reader.NodeType != XmlNodeType.None) { Member temp; WriteMemberElements(ref o, collectionMember, out temp, new Member[] { new Member(memberMapping) }, unknownNode, unknownNode, null, null); Reader.MoveToContent(); } ReadEndElement(); } SetCollectionObjectWithCollectionMember(ref o, collectionMember, collectionType); } } }
private object GenerateTypeElement(XmlTypeMapping xmlTypeMapping) { ElementAccessor element = xmlTypeMapping.Accessor; TypeMapping mapping = element.Mapping; Reader.MoveToContent(); MemberMapping member = new MemberMapping(); member.TypeDesc = mapping.TypeDesc; member.Elements = new ElementAccessor[] { element }; UnknownNodeAction elementElseAction = UnknownNodeAction.CreateUnknownNodeException; UnknownNodeAction elseAction = UnknownNodeAction.ReadUnknownNode; object o = null; Member tempMember = null; var currentMember = new Member(member); WriteMemberElements(ref o, null /*collectionMember*/, out tempMember, new Member[] { currentMember }, elementElseAction, elseAction, element.Any ? currentMember : null, null, xmlTypeMapping); return(o); }
private void WriteMemberElements(ref object o, CollectionMember collectionMember, out Member member, Member[] expectedMembers, UnknownNodeAction elementElseAction, UnknownNodeAction elseAction, Member anyElement, Member anyText, object masterObject = null) { if (Reader.NodeType == XmlNodeType.Element) { WriteMemberElementsIf(ref o, collectionMember, out member, expectedMembers, anyElement, elementElseAction, masterObject); } else if (anyText != null && anyText.Mapping != null && WriteMemberText(out o, anyText)) { member = anyText; } else { member = null; ProcessUnknownNode(elseAction); } }
private object WriteLiteralStructMethod(StructMapping structMapping, bool isNullable, bool checkType, string defaultNamespace) { XmlQualifiedName xsiType = checkType ? GetXsiType() : null; bool isNull = false; if (isNullable) { isNull = ReadNull(); } if (checkType) { if (structMapping.TypeDesc.IsRoot && isNull) { if (xsiType != null) { return(ReadTypedNull(xsiType)); } else { if (structMapping.TypeDesc.IsValueType) { return(ReflectionCreateObject(structMapping.TypeDesc.Type)); } else { return(null); } } } object o = null; if (xsiType == null || (!structMapping.TypeDesc.IsRoot && QNameEqual(xsiType, structMapping.TypeName, structMapping.Namespace, defaultNamespace))) { if (structMapping.TypeDesc.IsRoot) { return(ReadTypedPrimitive(new XmlQualifiedName(Soap.UrType, XmlSchemaConstants.Namespace))); } } else if (WriteDerivedTypes(out o, structMapping, xsiType, defaultNamespace, checkType, isNullable)) { return(o); } else if (structMapping.TypeDesc.IsRoot && WriteEnumAndArrayTypes(out o, structMapping, xsiType, defaultNamespace)) { return(o); } else { if (structMapping.TypeDesc.IsRoot) { return(ReadTypedPrimitive(xsiType)); } else { throw CreateUnknownTypeException(xsiType); } } } if (structMapping.TypeDesc.IsNullable && isNull) { return(null); } else if (structMapping.TypeDesc.IsAbstract) { throw CreateAbstractTypeException(structMapping.TypeName, structMapping.Namespace); } else { if (structMapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(structMapping.TypeDesc.Type)) { // #10589: To Support Serializing XmlSchemaObject throw new NotImplementedException("typeof(XmlSchemaObject)"); } object o = ReflectionCreateObject(structMapping.TypeDesc.Type); MemberMapping[] mappings = TypeScope.GetSettableMembers(structMapping); MemberMapping anyText = null; MemberMapping anyElement = null; MemberMapping anyAttribute = null; Member anyElementMember = null; Member anyTextMember = null; bool isSequence = structMapping.HasExplicitSequence(); if (isSequence) { // #10586: Currently the reflection based method treat this kind of type as normal types. // But potentially we can do some optimization for types that have ordered properties. } var allMembersList = new List <Member>(mappings.Length); var allMemberMappingList = new List <MemberMapping>(mappings.Length); for (int i = 0; i < mappings.Length; i++) { MemberMapping mapping = mappings[i]; if (mapping.Text != null) { anyText = mapping; } if (mapping.Attribute != null && mapping.Attribute.Any) { anyAttribute = mapping; } if (!isSequence) { // find anyElement if present. for (int j = 0; j < mapping.Elements.Length; j++) { if (mapping.Elements[j].Any && (mapping.Elements[j].Name == null || mapping.Elements[j].Name.Length == 0)) { anyElement = mapping; break; } } } else if (mapping.IsParticle && !mapping.IsSequence) { StructMapping declaringMapping; structMapping.FindDeclaringMapping(mapping, out declaringMapping, structMapping.TypeName); throw new InvalidOperationException(SR.Format(SR.XmlSequenceHierarchy, structMapping.TypeDesc.FullName, mapping.Name, declaringMapping.TypeDesc.FullName, "Order")); } var member = new Member(mapping); if (mapping.TypeDesc.IsArrayLike) { if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)) { member.Collection = new CollectionMember(); } else if (!mapping.TypeDesc.IsArray) { } } allMemberMappingList.Add(mapping); allMembersList.Add(member); if (mapping == anyElement) { anyElementMember = member; } else if (mapping == anyText) { anyTextMember = member; } } var allMembers = allMembersList.ToArray(); var allMemberMappings = allMemberMappingList.ToArray(); Action <object> unknownNodeAction = (n) => UnknownNode(n); WriteAttributes(allMemberMappings, anyAttribute, unknownNodeAction, ref o); Reader.MoveToElement(); if (Reader.IsEmptyElement) { Reader.Skip(); return(o); } Reader.ReadStartElement(); bool IsSequenceAllMembers = IsSequence(allMembers); if (IsSequenceAllMembers) { // #10586: Currently the reflection based method treat this kind of type as normal types. // But potentially we can do some optimization for types that have ordered properties. } UnknownNodeAction unknownNode = UnknownNodeAction.ReadUnknownNode; WriteMembers(ref o, allMembers, unknownNode, unknownNode, anyElementMember, anyTextMember); ReadEndElement(); return(o); } }
private void WriteMemberElementsIf(ref object o, CollectionMember collectionMember, out Member member, Member[] expectedMembers, Member anyElementMember, UnknownNodeAction elementElseAction, object masterObject = null) { bool isSequence = IsSequence(expectedMembers); if (isSequence) { // #10586: Currently the reflection based method treat this kind of type as normal types. // But potentially we can do some optimization for types that have ordered properties. } ElementAccessor e = null; member = null; bool foundElement = false; foreach (var m in expectedMembers) { if (m.Mapping.Xmlns != null) { continue; } if (m.Mapping.Ignore) { continue; } if (isSequence && (m.Mapping.IsText || m.Mapping.IsAttribute)) { continue; } foreach (var ele in m.Mapping.Elements) { if (ele.Name == Reader.LocalName && ele.Namespace == Reader.NamespaceURI) { e = ele; member = m; foundElement = true; break; } } if (foundElement) { break; } } if (foundElement) { ChoiceIdentifierAccessor choice = member.Mapping.ChoiceIdentifier; string ns = e.Form == XmlSchemaForm.Qualified ? e.Namespace : ""; bool isList = member.Mapping.TypeDesc.IsArrayLike && !member.Mapping.TypeDesc.IsArray; WriteElement(ref o, collectionMember, e, choice, member.Mapping.CheckSpecified == SpecifiedAccessor.ReadWrite, isList && member.Mapping.TypeDesc.IsNullable, member.Mapping.ReadOnly, ns, masterObject); } else { if (anyElementMember != null && anyElementMember.Mapping != null) { var anyElement = anyElementMember.Mapping; member = anyElementMember; ChoiceIdentifierAccessor choice = member.Mapping.ChoiceIdentifier; ElementAccessor[] elements = anyElement.Elements; for (int i = 0; i < elements.Length; i++) { ElementAccessor element = elements[i]; if (element.Any && element.Name.Length == 0) { string ns = element.Form == XmlSchemaForm.Qualified ? element.Namespace : ""; WriteElement(ref o, collectionMember, element, choice, anyElement.CheckSpecified == SpecifiedAccessor.ReadWrite, false, false, ns, masterObject: masterObject); break; } } } else { member = null; ProcessUnknownNode(elementElseAction); } } }