private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, string ns, Type choiceIdentifierType, bool rpc, bool openModel, RecursionLimiter limiter)
{
XmlSchemaForm elementFormDefault = XmlSchemaForm.Qualified;
int previousNestingLevel = _arrayNestingLevel;
int sequenceId = -1;
XmlArrayItemAttributes previousArrayItemAttributes = _savedArrayItemAttributes;
string previousArrayNamespace = _savedArrayNamespace;
_arrayNestingLevel = 0;
_savedArrayItemAttributes = null;
_savedArrayNamespace = null;
Type accessorType = model.FieldType;
string accessorName = model.Name;
ArrayList elementList = new ArrayList();
NameTable elements = new NameTable();
accessor.TypeDesc = _typeScope.GetTypeDesc(accessorType);
XmlAttributeFlags flags = a.XmlFlags;
accessor.Ignore = a.XmlIgnore;
if (rpc)
CheckTopLevelAttributes(a, accessorName);
else
CheckAmbiguousChoice(a, accessorType, accessorName);
XmlAttributeFlags elemFlags = XmlAttributeFlags.Elements | XmlAttributeFlags.Text | XmlAttributeFlags.AnyElements | XmlAttributeFlags.ChoiceIdentifier;
XmlAttributeFlags attrFlags = XmlAttributeFlags.Attribute | XmlAttributeFlags.AnyAttribute;
XmlAttributeFlags arrayFlags = XmlAttributeFlags.Array | XmlAttributeFlags.ArrayItems;
// special case for byte[]. It can be a primitive (base64Binary or hexBinary), or it can
// be an array of bytes. Our default is primitive; specify [XmlArray] to get array behavior.
if ((flags & arrayFlags) != 0 && accessorType == typeof(byte[]))
accessor.TypeDesc = _typeScope.GetArrayTypeDesc(accessorType);
if (a.XmlChoiceIdentifier != null)
{
accessor.ChoiceIdentifier = new ChoiceIdentifierAccessor();
accessor.ChoiceIdentifier.MemberName = a.XmlChoiceIdentifier.MemberName;
accessor.ChoiceIdentifier.MemberInfo = a.XmlChoiceIdentifier.MemberInfo;
accessor.ChoiceIdentifier.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(choiceIdentifierType), ns, ImportContext.Element, String.Empty, null, limiter);
CheckChoiceIdentifierMapping((EnumMapping)accessor.ChoiceIdentifier.Mapping);
}
if (accessor.TypeDesc.IsArrayLike)
{
Type arrayElementType = TypeScope.GetArrayElementType(accessorType, model.FieldTypeDesc.FullName + "." + model.Name);
if ((flags & attrFlags) != 0)
{
if ((flags & attrFlags) != flags)
throw new InvalidOperationException(SR.XmlIllegalAttributesArrayAttribute);
if (a.XmlAttribute != null && !accessor.TypeDesc.ArrayElementTypeDesc.IsPrimitive && !accessor.TypeDesc.ArrayElementTypeDesc.IsEnum)
{
if (accessor.TypeDesc.ArrayElementTypeDesc.Kind == TypeKind.Serializable)
{
throw new InvalidOperationException(SR.Format(SR.XmlIllegalAttrOrTextInterface, accessorName, accessor.TypeDesc.ArrayElementTypeDesc.FullName, typeof(IXmlSerializable).Name));
}
else
{
throw new InvalidOperationException(SR.Format(SR.XmlIllegalAttrOrText, accessorName, accessor.TypeDesc.ArrayElementTypeDesc.FullName));
}
}
bool isList = a.XmlAttribute != null && (accessor.TypeDesc.ArrayElementTypeDesc.IsPrimitive || accessor.TypeDesc.ArrayElementTypeDesc.IsEnum);
if (a.XmlAnyAttribute != null)
{
a.XmlAttribute = new XmlAttributeAttribute();
}
AttributeAccessor attribute = new AttributeAccessor();
Type targetType = a.XmlAttribute.Type == null ? arrayElementType : a.XmlAttribute.Type;
TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType);
attribute.Name = Accessor.EscapeQName(a.XmlAttribute.AttributeName.Length == 0 ? accessorName : a.XmlAttribute.AttributeName);
attribute.Namespace = a.XmlAttribute.Namespace == null ? ns : a.XmlAttribute.Namespace;
attribute.Form = a.XmlAttribute.Form;
if (attribute.Form == XmlSchemaForm.None && ns != attribute.Namespace)
{
attribute.Form = XmlSchemaForm.Qualified;
}
attribute.CheckSpecial();
CheckForm(attribute.Form, ns != attribute.Namespace);
attribute.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(targetType), ns, ImportContext.Attribute, a.XmlAttribute.DataType, null, isList, false, limiter);
attribute.IsList = isList;
attribute.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
attribute.Any = (a.XmlAnyAttribute != null);
if (attribute.Form == XmlSchemaForm.Qualified && attribute.Namespace != ns)
{
if (_xsdAttributes == null)
_xsdAttributes = new NameTable();
attribute = (AttributeAccessor)ReconcileAccessor(attribute, _xsdAttributes);
}
accessor.Attribute = attribute;
}
else if ((flags & elemFlags) != 0)
{
if ((flags & elemFlags) != flags)
throw new InvalidOperationException(SR.XmlIllegalElementsArrayAttribute);
if (a.XmlText != null)
{
TextAccessor text = new TextAccessor();
Type targetType = a.XmlText.Type == null ? arrayElementType : a.XmlText.Type;
TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType);
text.Name = accessorName; // unused except to make more helpful error messages
text.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(targetType), ns, ImportContext.Text, a.XmlText.DataType, null, true, false, limiter);
if (!(text.Mapping is SpecialMapping) && targetTypeDesc != _typeScope.GetTypeDesc(typeof(string)))
throw new InvalidOperationException(SR.Format(SR.XmlIllegalArrayTextAttribute, accessorName));
accessor.Text = text;
}
if (a.XmlText == null && a.XmlElements.Count == 0 && a.XmlAnyElements.Count == 0)
a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc));
for (int i = 0; i < a.XmlElements.Count; i++)
{
XmlElementAttribute xmlElement = a.XmlElements[i];
Type targetType = xmlElement.Type == null ? arrayElementType : xmlElement.Type;
TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType);
TypeModel typeModel = _modelScope.GetTypeModel(targetType);
ElementAccessor element = new ElementAccessor();
element.Namespace = rpc ? null : xmlElement.Namespace == null ? ns : xmlElement.Namespace;
element.Mapping = ImportTypeMapping(typeModel, rpc ? ns : element.Namespace, ImportContext.Element, xmlElement.DataType, null, limiter);
if (a.XmlElements.Count == 1)
{
element.Name = XmlConvert.EncodeLocalName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName);
//element.IsUnbounded = element.Mapping is ArrayMapping;
}
else
{
element.Name = xmlElement.ElementName.Length == 0 ? element.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(xmlElement.ElementName);
}
element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
if (xmlElement.IsNullableSpecified && !xmlElement.IsNullable && typeModel.TypeDesc.IsOptionalValue)
//XmlInvalidNotNullable=IsNullable may not be set to 'false' for a Nullable<{0}> type. Consider using '{0}' type or removing the IsNullable property from the XmlElement attribute.
throw new InvalidOperationException(SR.Format(SR.XmlInvalidNotNullable, typeModel.TypeDesc.BaseTypeDesc.FullName, "XmlElement"));
element.IsNullable = xmlElement.IsNullableSpecified ? xmlElement.IsNullable : typeModel.TypeDesc.IsOptionalValue;
element.Form = rpc ? XmlSchemaForm.Unqualified : xmlElement.Form == XmlSchemaForm.None ? elementFormDefault : xmlElement.Form;
CheckNullable(element.IsNullable, targetTypeDesc, element.Mapping);
if (!rpc)
{
CheckForm(element.Form, ns != element.Namespace);
element = ReconcileLocalAccessor(element, ns);
}
if (xmlElement.Order != -1)
{
if (xmlElement.Order != sequenceId && sequenceId != -1)
throw new InvalidOperationException(SR.Format(SR.XmlSequenceMatch, "Order"));
sequenceId = xmlElement.Order;
}
AddUniqueAccessor(elements, element);
elementList.Add(element);
}
NameTable anys = new NameTable();
for (int i = 0; i < a.XmlAnyElements.Count; i++)
{
XmlAnyElementAttribute xmlAnyElement = a.XmlAnyElements[i];
Type targetType = typeof(IXmlSerializable).IsAssignableFrom(arrayElementType) ? arrayElementType : typeof(XmlNode).IsAssignableFrom(arrayElementType) ? arrayElementType : typeof(XmlElement);
if (!arrayElementType.IsAssignableFrom(targetType))
throw new InvalidOperationException(SR.Format(SR.XmlIllegalAnyElement, arrayElementType.FullName));
string anyName = xmlAnyElement.Name.Length == 0 ? xmlAnyElement.Name : XmlConvert.EncodeLocalName(xmlAnyElement.Name);
string anyNs = xmlAnyElement.NamespaceSpecified ? xmlAnyElement.Namespace : null;
if (anys[anyName, anyNs] != null)
{
// ignore duplicate anys
continue;
}
anys[anyName, anyNs] = xmlAnyElement;
if (elements[anyName, (anyNs == null ? ns : anyNs)] != null)
{
throw new InvalidOperationException(SR.Format(SR.XmlAnyElementDuplicate, accessorName, xmlAnyElement.Name, xmlAnyElement.Namespace == null ? "null" : xmlAnyElement.Namespace));
}
ElementAccessor element = new ElementAccessor();
element.Name = anyName;
element.Namespace = anyNs == null ? ns : anyNs;
element.Any = true;
element.AnyNamespaces = anyNs;
TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType);
TypeModel typeModel = _modelScope.GetTypeModel(targetType);
if (element.Name.Length > 0)
typeModel.TypeDesc.IsMixed = true;
element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, String.Empty, null, limiter);
element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
element.IsNullable = false;
element.Form = elementFormDefault;
CheckNullable(element.IsNullable, targetTypeDesc, element.Mapping);
if (!rpc)
{
CheckForm(element.Form, ns != element.Namespace);
element = ReconcileLocalAccessor(element, ns);
}
elements.Add(element.Name, element.Namespace, element);
elementList.Add(element);
if (xmlAnyElement.Order != -1)
{
if (xmlAnyElement.Order != sequenceId && sequenceId != -1)
throw new InvalidOperationException(SR.Format(SR.XmlSequenceMatch, "Order"));
sequenceId = xmlAnyElement.Order;
}
}
}
else
{
if ((flags & arrayFlags) != 0)
{
if ((flags & arrayFlags) != flags)
throw new InvalidOperationException(SR.XmlIllegalArrayArrayAttribute);
}
TypeDesc arrayElementTypeDesc = _typeScope.GetTypeDesc(arrayElementType);
if (a.XmlArray == null)
a.XmlArray = CreateArrayAttribute(accessor.TypeDesc);
if (CountAtLevel(a.XmlArrayItems, _arrayNestingLevel) == 0)
a.XmlArrayItems.Add(CreateArrayItemAttribute(arrayElementTypeDesc, _arrayNestingLevel));
ElementAccessor arrayElement = new ElementAccessor();
arrayElement.Name = XmlConvert.EncodeLocalName(a.XmlArray.ElementName.Length == 0 ? accessorName : a.XmlArray.ElementName);
arrayElement.Namespace = rpc ? null : a.XmlArray.Namespace == null ? ns : a.XmlArray.Namespace;
_savedArrayItemAttributes = a.XmlArrayItems;
_savedArrayNamespace = arrayElement.Namespace;
ArrayMapping arrayMapping = ImportArrayLikeMapping(_modelScope.GetArrayModel(accessorType), ns, limiter);
arrayElement.Mapping = arrayMapping;
arrayElement.IsNullable = a.XmlArray.IsNullable;
arrayElement.Form = rpc ? XmlSchemaForm.Unqualified : a.XmlArray.Form == XmlSchemaForm.None ? elementFormDefault : a.XmlArray.Form;
sequenceId = a.XmlArray.Order;
CheckNullable(arrayElement.IsNullable, accessor.TypeDesc, arrayElement.Mapping);
if (!rpc)
{
CheckForm(arrayElement.Form, ns != arrayElement.Namespace);
arrayElement = ReconcileLocalAccessor(arrayElement, ns);
}
_savedArrayItemAttributes = null;
_savedArrayNamespace = null;
AddUniqueAccessor(elements, arrayElement);
elementList.Add(arrayElement);
}
}
else if (!accessor.TypeDesc.IsVoid)
{
XmlAttributeFlags allFlags = XmlAttributeFlags.Elements | XmlAttributeFlags.Text | XmlAttributeFlags.Attribute | XmlAttributeFlags.AnyElements | XmlAttributeFlags.ChoiceIdentifier | XmlAttributeFlags.XmlnsDeclarations;
if ((flags & allFlags) != flags)
throw new InvalidOperationException(SR.XmlIllegalAttribute);
if (accessor.TypeDesc.IsPrimitive || accessor.TypeDesc.IsEnum)
{
if (a.XmlAnyElements.Count > 0) throw new InvalidOperationException(SR.Format(SR.XmlIllegalAnyElement, accessor.TypeDesc.FullName));
if (a.XmlAttribute != null)
{
if (a.XmlElements.Count > 0) throw new InvalidOperationException(SR.XmlIllegalAttribute);
if (a.XmlAttribute.Type != null) throw new InvalidOperationException(SR.Format(SR.XmlIllegalType, "XmlAttribute"));
AttributeAccessor attribute = new AttributeAccessor();
attribute.Name = Accessor.EscapeQName(a.XmlAttribute.AttributeName.Length == 0 ? accessorName : a.XmlAttribute.AttributeName);
attribute.Namespace = a.XmlAttribute.Namespace == null ? ns : a.XmlAttribute.Namespace;
attribute.Form = a.XmlAttribute.Form;
if (attribute.Form == XmlSchemaForm.None && ns != attribute.Namespace)
{
attribute.Form = XmlSchemaForm.Qualified;
}
attribute.CheckSpecial();
CheckForm(attribute.Form, ns != attribute.Namespace);
attribute.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(accessorType), ns, ImportContext.Attribute, a.XmlAttribute.DataType, null, limiter);
attribute.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
attribute.Any = a.XmlAnyAttribute != null;
if (attribute.Form == XmlSchemaForm.Qualified && attribute.Namespace != ns)
{
if (_xsdAttributes == null)
_xsdAttributes = new NameTable();
attribute = (AttributeAccessor)ReconcileAccessor(attribute, _xsdAttributes);
}
accessor.Attribute = attribute;
}
else
{
if (a.XmlText != null)
{
if (a.XmlText.Type != null && a.XmlText.Type != accessorType)
throw new InvalidOperationException(SR.Format(SR.XmlIllegalType, "XmlText"));
TextAccessor text = new TextAccessor();
text.Name = accessorName; // unused except to make more helpful error messages
text.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(accessorType), ns, ImportContext.Text, a.XmlText.DataType, null, limiter);
accessor.Text = text;
}
else if (a.XmlElements.Count == 0)
{
a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc));
}
for (int i = 0; i < a.XmlElements.Count; i++)
{
XmlElementAttribute xmlElement = a.XmlElements[i];
if (xmlElement.Type != null)
{
if (_typeScope.GetTypeDesc(xmlElement.Type) != accessor.TypeDesc)
throw new InvalidOperationException(SR.Format(SR.XmlIllegalType, "XmlElement"));
}
ElementAccessor element = new ElementAccessor();
element.Name = XmlConvert.EncodeLocalName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName);
element.Namespace = rpc ? null : xmlElement.Namespace == null ? ns : xmlElement.Namespace;
TypeModel typeModel = _modelScope.GetTypeModel(accessorType);
element.Mapping = ImportTypeMapping(typeModel, rpc ? ns : element.Namespace, ImportContext.Element, xmlElement.DataType, null, limiter);
if (element.Mapping.TypeDesc.Kind == TypeKind.Node)
{
element.Any = true;
}
element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
if (xmlElement.IsNullableSpecified && !xmlElement.IsNullable && typeModel.TypeDesc.IsOptionalValue)
//XmlInvalidNotNullable=IsNullable may not be set to 'false' for a Nullable<{0}> type. Consider using '{0}' type or removing the IsNullable property from the XmlElement attribute.
throw new InvalidOperationException(SR.Format(SR.XmlInvalidNotNullable, typeModel.TypeDesc.BaseTypeDesc.FullName, "XmlElement"));
element.IsNullable = xmlElement.IsNullableSpecified ? xmlElement.IsNullable : typeModel.TypeDesc.IsOptionalValue;
element.Form = rpc ? XmlSchemaForm.Unqualified : xmlElement.Form == XmlSchemaForm.None ? elementFormDefault : xmlElement.Form;
CheckNullable(element.IsNullable, accessor.TypeDesc, element.Mapping);
if (!rpc)
{
CheckForm(element.Form, ns != element.Namespace);
element = ReconcileLocalAccessor(element, ns);
}
if (xmlElement.Order != -1)
{
if (xmlElement.Order != sequenceId && sequenceId != -1)
throw new InvalidOperationException(SR.Format(SR.XmlSequenceMatch, "Order"));
sequenceId = xmlElement.Order;
}
AddUniqueAccessor(elements, element);
elementList.Add(element);
}
}
}
else if (a.Xmlns)
{
if (flags != XmlAttributeFlags.XmlnsDeclarations)
throw new InvalidOperationException(SR.XmlSoleXmlnsAttribute);
if (accessorType != typeof(XmlSerializerNamespaces))
{
throw new InvalidOperationException(SR.Format(SR.XmlXmlnsInvalidType, accessorName, accessorType.FullName, typeof(XmlSerializerNamespaces).FullName));
}
accessor.Xmlns = new XmlnsAccessor();
accessor.Ignore = true;
}
else
{
if (a.XmlAttribute != null || a.XmlText != null)
{
if (accessor.TypeDesc.Kind == TypeKind.Serializable)
{
throw new InvalidOperationException(SR.Format(SR.XmlIllegalAttrOrTextInterface, accessorName, accessor.TypeDesc.FullName, typeof(IXmlSerializable).Name));
}
else
{
throw new InvalidOperationException(SR.Format(SR.XmlIllegalAttrOrText, accessorName, accessor.TypeDesc));
}
}
if (a.XmlElements.Count == 0 && a.XmlAnyElements.Count == 0)
a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc));
for (int i = 0; i < a.XmlElements.Count; i++)
{
XmlElementAttribute xmlElement = a.XmlElements[i];
Type targetType = xmlElement.Type == null ? accessorType : xmlElement.Type;
TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType);
ElementAccessor element = new ElementAccessor();
TypeModel typeModel = _modelScope.GetTypeModel(targetType);
element.Namespace = rpc ? null : xmlElement.Namespace == null ? ns : xmlElement.Namespace;
element.Mapping = ImportTypeMapping(typeModel, rpc ? ns : element.Namespace, ImportContext.Element, xmlElement.DataType, null, false, openModel, limiter);
if (a.XmlElements.Count == 1)
{
element.Name = XmlConvert.EncodeLocalName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName);
}
else
{
element.Name = xmlElement.ElementName.Length == 0 ? element.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(xmlElement.ElementName);
}
element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
if (xmlElement.IsNullableSpecified && !xmlElement.IsNullable && typeModel.TypeDesc.IsOptionalValue)
//XmlInvalidNotNullable=IsNullable may not be set to 'false' for a Nullable<{0}> type. Consider using '{0}' type or removing the IsNullable property from the XmlElement attribute.
throw new InvalidOperationException(SR.Format(SR.XmlInvalidNotNullable, typeModel.TypeDesc.BaseTypeDesc.FullName, "XmlElement"));
element.IsNullable = xmlElement.IsNullableSpecified ? xmlElement.IsNullable : typeModel.TypeDesc.IsOptionalValue;
element.Form = rpc ? XmlSchemaForm.Unqualified : xmlElement.Form == XmlSchemaForm.None ? elementFormDefault : xmlElement.Form;
CheckNullable(element.IsNullable, targetTypeDesc, element.Mapping);
if (!rpc)
{
CheckForm(element.Form, ns != element.Namespace);
element = ReconcileLocalAccessor(element, ns);
}
if (xmlElement.Order != -1)
{
if (xmlElement.Order != sequenceId && sequenceId != -1)
throw new InvalidOperationException(SR.Format(SR.XmlSequenceMatch, "Order"));
sequenceId = xmlElement.Order;
}
AddUniqueAccessor(elements, element);
elementList.Add(element);
}
NameTable anys = new NameTable();
for (int i = 0; i < a.XmlAnyElements.Count; i++)
{
XmlAnyElementAttribute xmlAnyElement = a.XmlAnyElements[i];
Type targetType = typeof(IXmlSerializable).IsAssignableFrom(accessorType) ? accessorType : typeof(XmlNode).IsAssignableFrom(accessorType) ? accessorType : typeof(XmlElement);
if (!accessorType.IsAssignableFrom(targetType))
throw new InvalidOperationException(SR.Format(SR.XmlIllegalAnyElement, accessorType.FullName));
string anyName = xmlAnyElement.Name.Length == 0 ? xmlAnyElement.Name : XmlConvert.EncodeLocalName(xmlAnyElement.Name);
string anyNs = xmlAnyElement.NamespaceSpecified ? xmlAnyElement.Namespace : null;
if (anys[anyName, anyNs] != null)
{
// ignore duplicate anys
continue;
}
anys[anyName, anyNs] = xmlAnyElement;
if (elements[anyName, (anyNs == null ? ns : anyNs)] != null)
{
throw new InvalidOperationException(SR.Format(SR.XmlAnyElementDuplicate, accessorName, xmlAnyElement.Name, xmlAnyElement.Namespace == null ? "null" : xmlAnyElement.Namespace));
}
ElementAccessor element = new ElementAccessor();
element.Name = anyName;
element.Namespace = anyNs == null ? ns : anyNs;
element.Any = true;
element.AnyNamespaces = anyNs;
TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType);
TypeModel typeModel = _modelScope.GetTypeModel(targetType);
if (element.Name.Length > 0)
typeModel.TypeDesc.IsMixed = true;
element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, String.Empty, null, false, openModel, limiter);
element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
element.IsNullable = false;
element.Form = elementFormDefault;
CheckNullable(element.IsNullable, targetTypeDesc, element.Mapping);
if (!rpc)
{
CheckForm(element.Form, ns != element.Namespace);
element = ReconcileLocalAccessor(element, ns);
}
if (xmlAnyElement.Order != -1)
{
if (xmlAnyElement.Order != sequenceId && sequenceId != -1)
throw new InvalidOperationException(SR.Format(SR.XmlSequenceMatch, "Order"));
sequenceId = xmlAnyElement.Order;
}
elements.Add(element.Name, element.Namespace, element);
elementList.Add(element);
}
}
}
accessor.Elements = (ElementAccessor[])elementList.ToArray(typeof(ElementAccessor));
accessor.SequenceId = sequenceId;
if (rpc)
{
if (accessor.TypeDesc.IsArrayLike && accessor.Elements.Length > 0 && !(accessor.Elements[0].Mapping is ArrayMapping))
throw new InvalidOperationException(SR.Format(SR.XmlRpcLitArrayElement, accessor.Elements[0].Name));
if (accessor.Xmlns != null)
throw new InvalidOperationException(SR.Format(SR.XmlRpcLitXmlns, accessor.Name));
}
if (accessor.ChoiceIdentifier != null)
{
// find the enum value corresponding to each element
accessor.ChoiceIdentifier.MemberIds = new string[accessor.Elements.Length];
for (int i = 0; i < accessor.Elements.Length; i++)
{
bool found = false;
ElementAccessor element = accessor.Elements[i];
EnumMapping choiceMapping = (EnumMapping)accessor.ChoiceIdentifier.Mapping;
for (int j = 0; j < choiceMapping.Constants.Length; j++)
{
string xmlName = choiceMapping.Constants[j].XmlName;
if (element.Any && element.Name.Length == 0)
{
string anyNs = element.AnyNamespaces == null ? "##any" : element.AnyNamespaces;
if (xmlName.Substring(0, xmlName.Length - 1) == anyNs)
{
accessor.ChoiceIdentifier.MemberIds[i] = choiceMapping.Constants[j].Name;
found = true;
break;
}
continue;
}
int colon = xmlName.LastIndexOf(':');
string choiceNs = colon < 0 ? choiceMapping.Namespace : xmlName.Substring(0, colon);
string choiceName = colon < 0 ? xmlName : xmlName.Substring(colon + 1);
if (element.Name == choiceName)
{
if ((element.Form == XmlSchemaForm.Unqualified && string.IsNullOrEmpty(choiceNs)) || element.Namespace == choiceNs)
{
accessor.ChoiceIdentifier.MemberIds[i] = choiceMapping.Constants[j].Name;
found = true;
break;
}
}
}
if (!found)
{
if (element.Any && element.Name.Length == 0)
{
// Type {0} is missing enumeration value '##any' for XmlAnyElementAttribute.
throw new InvalidOperationException(SR.Format(SR.XmlChoiceMissingAnyValue, accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName));
}
else
{
string id = element.Namespace != null && element.Namespace.Length > 0 ? element.Namespace + ":" + element.Name : element.Name;
// Type {0} is missing value for '{1}'.
throw new InvalidOperationException(SR.Format(SR.XmlChoiceMissingValue, accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName, id, element.Name, element.Namespace));
}
}
}
}
_arrayNestingLevel = previousNestingLevel;
_savedArrayItemAttributes = previousArrayItemAttributes;
_savedArrayNamespace = previousArrayNamespace;
}