System.Xml.Serialization.XmlSchemaImporter.ImportChoiceGroup C# (CSharp) Method

ImportChoiceGroup() private method

private ImportChoiceGroup ( XmlSchemaGroupBase group, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, INameScope elementsScope, string ns, bool groupRepeats, bool &needExplicitOrder, bool allowDuplicates ) : MemberMapping
group System.Xml.Schema.XmlSchemaGroupBase
identifier string
members CodeIdentifiers
membersScope CodeIdentifiers
elementsScope INameScope
ns string
groupRepeats bool
needExplicitOrder bool
allowDuplicates bool
return MemberMapping
        private MemberMapping ImportChoiceGroup(XmlSchemaGroupBase group, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, INameScope elementsScope, string ns, bool groupRepeats, ref bool needExplicitOrder, bool allowDuplicates)
        {
            NameTable choiceElements = new NameTable();
            if (GatherGroupChoices(group, choiceElements, identifier, ns, ref needExplicitOrder, allowDuplicates))
                groupRepeats = true;
            MemberMapping member = new MemberMapping();
            member.Elements = (ElementAccessor[])choiceElements.ToArray(typeof(ElementAccessor));
            Array.Sort(member.Elements, new ElementComparer());

            AddScopeElements(elementsScope, member.Elements, ref needExplicitOrder, allowDuplicates);
            bool duplicateTypes = false;
            bool nullableMismatch = false;
            Hashtable uniqueTypeDescs = new Hashtable(member.Elements.Length);

            for (int i = 0; i < member.Elements.Length; i++)
            {
                ElementAccessor element = member.Elements[i];
                string tdFullName = element.Mapping.TypeDesc.FullName;
                object val = uniqueTypeDescs[tdFullName];
                if (val != null)
                {
                    duplicateTypes = true;
                    ElementAccessor existingElement = (ElementAccessor)val;
                    if (!nullableMismatch && existingElement.IsNullable != element.IsNullable)
                        nullableMismatch = true;
                }
                else
                {
                    uniqueTypeDescs.Add(tdFullName, element);
                }

                ArrayMapping arrayMapping = element.Mapping as ArrayMapping;
                if (arrayMapping != null)
                {
                    if (IsNeedXmlSerializationAttributes(arrayMapping))
                    {
                        // we cannot use ArrayMapping in choice if additional custom 
                        // serialization attributes are needed to serialize it
                        element.Mapping = arrayMapping.TopLevelMapping;
                        element.Mapping.ReferencedByTopLevelElement = false;
                        element.Mapping.ReferencedByElement = true;
                    }
                }
            }
            if (nullableMismatch)
                member.TypeDesc = Scope.GetTypeDesc(typeof(object));
            else
            {
                TypeDesc[] typeDescs = new TypeDesc[uniqueTypeDescs.Count];
                IEnumerator enumerator = uniqueTypeDescs.Values.GetEnumerator();
                for (int i = 0; i < typeDescs.Length; i++)
                {
                    if (!enumerator.MoveNext())
                        break;
                    typeDescs[i] = ((ElementAccessor)enumerator.Current).Mapping.TypeDesc;
                }
                member.TypeDesc = TypeDesc.FindCommonBaseTypeDesc(typeDescs);
                if (member.TypeDesc == null) member.TypeDesc = Scope.GetTypeDesc(typeof(object));
            }

            if (groupRepeats)
                member.TypeDesc = member.TypeDesc.CreateArrayTypeDesc();

            if (membersScope != null)
            {
                member.Name = membersScope.AddUnique(groupRepeats ? "Items" : "Item", member);
                if (members != null)
                {
                    members.Add(member.Name, member);
                }
            }

            if (duplicateTypes)
            {
                member.ChoiceIdentifier = new ChoiceIdentifierAccessor();
                member.ChoiceIdentifier.MemberName = member.Name + "ElementName";
                // we need to create the EnumMapping to store all of the element names
                member.ChoiceIdentifier.Mapping = ImportEnumeratedChoice(member.Elements, ns, member.Name + "ChoiceType");
                member.ChoiceIdentifier.MemberIds = new string[member.Elements.Length];
                ConstantMapping[] constants = ((EnumMapping)member.ChoiceIdentifier.Mapping).Constants;
                for (int i = 0; i < member.Elements.Length; i++)
                {
                    member.ChoiceIdentifier.MemberIds[i] = constants[i].Name;
                }
                MemberMapping choiceIdentifier = new MemberMapping();
                choiceIdentifier.Ignore = true;
                choiceIdentifier.Name = member.ChoiceIdentifier.MemberName;
                if (groupRepeats)
                {
                    choiceIdentifier.TypeDesc = member.ChoiceIdentifier.Mapping.TypeDesc.CreateArrayTypeDesc();
                }
                else
                {
                    choiceIdentifier.TypeDesc = member.ChoiceIdentifier.Mapping.TypeDesc;
                }

                // create element accessor for the choiceIdentifier

                ElementAccessor choiceAccessor = new ElementAccessor();
                choiceAccessor.Name = choiceIdentifier.Name;
                choiceAccessor.Namespace = ns;
                choiceAccessor.Mapping = member.ChoiceIdentifier.Mapping;
                choiceIdentifier.Elements = new ElementAccessor[] { choiceAccessor };

                if (membersScope != null)
                {
                    choiceAccessor.Name = choiceIdentifier.Name = member.ChoiceIdentifier.MemberName = membersScope.AddUnique(member.ChoiceIdentifier.MemberName, choiceIdentifier);
                    if (members != null)
                    {
                        members.Add(choiceAccessor.Name, choiceIdentifier);
                    }
                }
            }
            return member;
        }