void WriteMember(string source, AttributeAccessor attribute, TypeDesc memberTypeDesc, string parent) {
            if (memberTypeDesc.IsAbstract) return;
            if (memberTypeDesc.IsArrayLike) {
                Writer.WriteLine("{");
                Writer.Indent++;
                string fullTypeName = memberTypeDesc.CSharpName;
                WriteArrayLocalDecl(fullTypeName, "a", source, memberTypeDesc);
                if (memberTypeDesc.IsNullable) {
                    Writer.WriteLine("if (a != null) {");
                    Writer.Indent++;
                }
                if (attribute.IsList) {
                    if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc)) {
                        Writer.Write("Writer.WriteStartAttribute(null, ");
                        WriteQuotedCSharpString(attribute.Name);
                        Writer.Write(", ");
                        string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
                        if (ns != null) {
                            WriteQuotedCSharpString(ns);
                        }
                        else {
                            Writer.Write("null");
                        }
                        Writer.WriteLine(");");
                    }
                    else {
                        Writer.Write(typeof(StringBuilder).FullName);
                        Writer.Write(" sb = new ");
                        Writer.Write(typeof(StringBuilder).FullName);
                        Writer.WriteLine("();");
                    }
                }
                TypeDesc arrayElementTypeDesc = memberTypeDesc.ArrayElementTypeDesc;

                if (memberTypeDesc.IsEnumerable) {
                    Writer.Write(" e = ");
                    Writer.Write(typeof(IEnumerator).FullName);
                    if (memberTypeDesc.IsPrivateImplementation) {
                        Writer.Write("((");
                        Writer.Write(typeof(IEnumerable).FullName);
                        Writer.WriteLine(").GetEnumerator();");
                    }
                    else if(memberTypeDesc.IsGenericInterface) {
                        if (memberTypeDesc.UseReflection) {
                            // we use wildcard method name for generic GetEnumerator method, so we cannot use GetStringForMethodInvoke call here
                            Writer.Write("(");
                            Writer.Write(typeof(IEnumerator).FullName);
                            Writer.Write(")");
                            Writer.Write(RaCodeGen.GetReflectionVariable(memberTypeDesc.CSharpName, "System.Collections.Generic.IEnumerable*"));
                            Writer.WriteLine(".Invoke(a, new object[0]);");
                        }
                        else {
                            Writer.Write("((System.Collections.Generic.IEnumerable<");
                            Writer.Write(arrayElementTypeDesc.CSharpName);
                            Writer.WriteLine(">)a).GetEnumerator();");
                        }
                    }
                    else {
                        if (memberTypeDesc.UseReflection) {
                            Writer.Write("(");
                            Writer.Write(typeof(IEnumerator).FullName);
                            Writer.Write(")");
                        }
                        Writer.Write(RaCodeGen.GetStringForMethodInvoke("a", memberTypeDesc.CSharpName, "GetEnumerator", memberTypeDesc.UseReflection));
                        Writer.WriteLine(";");
                    }
                    Writer.WriteLine("if (e != null)");
                    Writer.WriteLine("while (e.MoveNext()) {");
                    Writer.Indent++;

                    string arrayTypeFullName = arrayElementTypeDesc.CSharpName;
                    WriteLocalDecl(arrayTypeFullName, "ai", "e.Current", arrayElementTypeDesc.UseReflection);
                }
                else {
                    Writer.Write("for (int i = 0; i < ");
                    if (memberTypeDesc.IsArray) {
                        Writer.WriteLine("a.Length; i++) {");
                    }
                    else {
                        Writer.Write("((");
                        Writer.Write(typeof(ICollection).FullName);
                        Writer.WriteLine(")a).Count; i++) {");
                    }
                    Writer.Indent++;
                    string arrayTypeFullName = arrayElementTypeDesc.CSharpName;
                    WriteLocalDecl(arrayTypeFullName, "ai", RaCodeGen.GetStringForArrayMember("a", "i", memberTypeDesc), arrayElementTypeDesc.UseReflection);
                }
                if (attribute.IsList) {
                    // check to see if we can write values of the attribute sequentially
                    if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc)) {
                        Writer.WriteLine("if (i != 0) Writer.WriteString(\" \");");
                        Writer.Write("WriteValue(");
                    }
                    else {
                        Writer.WriteLine("if (i != 0) sb.Append(\" \");");
                        Writer.Write("sb.Append(");
                    }
                    if (attribute.Mapping is EnumMapping)
                        WriteEnumValue((EnumMapping)attribute.Mapping, "ai");
                    else
                        WritePrimitiveValue(arrayElementTypeDesc, "ai", true);
                    Writer.WriteLine(");");
                }
                else {
                    WriteAttribute("ai", attribute, parent);
                }
                Writer.Indent--;
                Writer.WriteLine("}");
                if (attribute.IsList) {
                    // check to see if we can write values of the attribute sequentially
                    if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc)) {
                        Writer.WriteLine("Writer.WriteEndAttribute();");
                    }
                    else {
                        Writer.WriteLine("if (sb.Length != 0) {");
                        Writer.Indent++;
                    
                        Writer.Write("WriteAttribute(");
                        WriteQuotedCSharpString(attribute.Name);
                        Writer.Write(", ");
                        string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
                        if (ns != null) {
                            WriteQuotedCSharpString(ns);
                            Writer.Write(", ");
                        }
                        Writer.WriteLine("sb.ToString());");
                        Writer.Indent--;
                        Writer.WriteLine("}");
                    }
                }

                if (memberTypeDesc.IsNullable) {
                    Writer.Indent--;
                    Writer.WriteLine("}");
                }
                Writer.Indent--;
                Writer.WriteLine("}");
            }
            else {
                WriteAttribute(source, attribute, parent);
            }
        }
Beispiel #2
0
 protected AccessorMapping(AccessorMapping mapping)
     : base(mapping)
 {
     _typeDesc = mapping._typeDesc;
     _attribute = mapping._attribute;
     _elements = mapping._elements;
     _sortedElements = mapping._sortedElements;
     _text = mapping._text;
     _choiceIdentifier = mapping._choiceIdentifier;
     _xmlns = mapping._xmlns;
     _ignore = mapping._ignore;
 }
 private void ExportAttributeAccessor(XmlSchemaComplexType type, AttributeAccessor accessor, bool valueTypeOptional, string ns)
 {
     if (accessor != null)
     {
         XmlSchemaObjectCollection attributes;
         if (type.ContentModel != null)
         {
             if (type.ContentModel.Content is XmlSchemaComplexContentRestriction)
             {
                 attributes = ((XmlSchemaComplexContentRestriction) type.ContentModel.Content).Attributes;
             }
             else if (!(type.ContentModel.Content is XmlSchemaComplexContentExtension))
             {
                 if (!(type.ContentModel.Content is XmlSchemaSimpleContentExtension))
                 {
                     throw new InvalidOperationException(Res.GetString("XmlInvalidContent", new object[] { type.ContentModel.Content.GetType().Name }));
                 }
                 attributes = ((XmlSchemaSimpleContentExtension) type.ContentModel.Content).Attributes;
             }
             else
             {
                 attributes = ((XmlSchemaComplexContentExtension) type.ContentModel.Content).Attributes;
             }
         }
         else
         {
             attributes = type.Attributes;
         }
         if (accessor.IsSpecialXmlNamespace)
         {
             this.AddSchemaImport("http://www.w3.org/XML/1998/namespace", ns);
             XmlSchemaAttribute item = new XmlSchemaAttribute {
                 Use = XmlSchemaUse.Optional,
                 RefName = new XmlQualifiedName(accessor.Name, "http://www.w3.org/XML/1998/namespace")
             };
             attributes.Add(item);
         }
         else if (accessor.Any)
         {
             if (type.ContentModel == null)
             {
                 type.AnyAttribute = new XmlSchemaAnyAttribute();
             }
             else
             {
                 XmlSchemaContent content = type.ContentModel.Content;
                 if (content is XmlSchemaComplexContentExtension)
                 {
                     XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension) content;
                     extension.AnyAttribute = new XmlSchemaAnyAttribute();
                 }
                 else if (content is XmlSchemaComplexContentRestriction)
                 {
                     XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction) content;
                     restriction.AnyAttribute = new XmlSchemaAnyAttribute();
                 }
                 else if (type.ContentModel.Content is XmlSchemaSimpleContentExtension)
                 {
                     XmlSchemaSimpleContentExtension extension2 = (XmlSchemaSimpleContentExtension) content;
                     extension2.AnyAttribute = new XmlSchemaAnyAttribute();
                 }
             }
         }
         else
         {
             XmlSchemaAttribute attribute2 = new XmlSchemaAttribute {
                 Use = XmlSchemaUse.None
             };
             if ((!accessor.HasDefault && !valueTypeOptional) && accessor.Mapping.TypeDesc.IsValueType)
             {
                 attribute2.Use = XmlSchemaUse.Required;
             }
             attribute2.Name = accessor.Name;
             if ((accessor.Namespace == null) || (accessor.Namespace == ns))
             {
                 XmlSchema schema = this.schemas[ns];
                 if (schema == null)
                 {
                     attribute2.Form = (accessor.Form == XmlSchemaForm.Unqualified) ? XmlSchemaForm.None : accessor.Form;
                 }
                 else
                 {
                     attribute2.Form = (accessor.Form == schema.AttributeFormDefault) ? XmlSchemaForm.None : accessor.Form;
                 }
                 attributes.Add(attribute2);
             }
             else
             {
                 if (this.attributes[accessor] == null)
                 {
                     attribute2.Use = XmlSchemaUse.None;
                     attribute2.Form = accessor.Form;
                     this.AddSchemaItem(attribute2, accessor.Namespace, ns);
                     this.attributes.Add(accessor, accessor);
                 }
                 XmlSchemaAttribute attribute3 = new XmlSchemaAttribute {
                     Use = XmlSchemaUse.None,
                     RefName = new XmlQualifiedName(accessor.Name, accessor.Namespace)
                 };
                 attributes.Add(attribute3);
                 this.AddSchemaImport(accessor.Namespace, ns);
             }
             if (accessor.Mapping is PrimitiveMapping)
             {
                 PrimitiveMapping mapping = (PrimitiveMapping) accessor.Mapping;
                 if (mapping.IsList)
                 {
                     XmlSchemaSimpleType type2 = new XmlSchemaSimpleType();
                     XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList();
                     if (mapping.IsAnonymousType)
                     {
                         list.ItemType = (XmlSchemaSimpleType) this.ExportAnonymousPrimitiveMapping(mapping);
                     }
                     else
                     {
                         list.ItemTypeName = this.ExportPrimitiveMapping(mapping, (accessor.Namespace == null) ? ns : accessor.Namespace);
                     }
                     type2.Content = list;
                     attribute2.SchemaType = type2;
                 }
                 else if (mapping.IsAnonymousType)
                 {
                     attribute2.SchemaType = (XmlSchemaSimpleType) this.ExportAnonymousPrimitiveMapping(mapping);
                 }
                 else
                 {
                     attribute2.SchemaTypeName = this.ExportPrimitiveMapping(mapping, (accessor.Namespace == null) ? ns : accessor.Namespace);
                 }
             }
             else if (!(accessor.Mapping is SpecialMapping))
             {
                 throw new InvalidOperationException(Res.GetString("XmlInternalError"));
             }
             if (accessor.HasDefault)
             {
                 attribute2.DefaultValue = ExportDefaultValue(accessor.Mapping, accessor.Default);
             }
         }
     }
 }
        void ExportTypeMembers(XmlSchemaComplexType type, MemberMapping[] members, string name, string ns, bool hasSimpleContent, bool openModel) {
            XmlSchemaGroupBase seq = new XmlSchemaSequence();
            TypeMapping textMapping = null;
            
            for (int i = 0; i < members.Length; i++) {
                MemberMapping member = members[i];
                if (member.Ignore)
                    continue;
                if (member.Text != null) {
                    if (textMapping != null) {
                        throw new InvalidOperationException(Res.GetString(Res.XmlIllegalMultipleText, name));
                    }
                    textMapping = member.Text.Mapping;
                }
                if (member.Elements.Length > 0) {
                    bool repeats = member.TypeDesc.IsArrayLike && 
                        !(member.Elements.Length == 1 && member.Elements[0].Mapping is ArrayMapping);

                    bool valueTypeOptional = member.CheckSpecified != SpecifiedAccessor.None || member.CheckShouldPersist;
                    ExportElementAccessors(seq, member.Elements, repeats, valueTypeOptional, ns);
                }
            }

            if (seq.Items.Count > 0) {
                if (type.ContentModel != null) {
                    if (type.ContentModel.Content is XmlSchemaComplexContentRestriction)
                        ((XmlSchemaComplexContentRestriction)type.ContentModel.Content).Particle = seq;
                    else if (type.ContentModel.Content is XmlSchemaComplexContentExtension)
                        ((XmlSchemaComplexContentExtension)type.ContentModel.Content).Particle = seq;
                    else
                        throw new InvalidOperationException(Res.GetString(Res.XmlInvalidContent, type.ContentModel.Content.GetType().Name));
                }
                else {
                    type.Particle = seq;
                }
            }
            if (textMapping != null) {
                if (hasSimpleContent) {
                    if (textMapping is PrimitiveMapping && seq.Items.Count == 0) {
                        PrimitiveMapping pm = (PrimitiveMapping)textMapping;
                        if (pm.IsList) {
                            type.IsMixed = true;
                        }
                        else {
                            if (pm.IsAnonymousType) {
                                throw new InvalidOperationException(Res.GetString(Res.XmlAnonymousBaseType, textMapping.TypeDesc.Name, pm.TypeDesc.Name, "AnonymousType", "false"));
                            }
                            // Create simpleContent
                            XmlSchemaSimpleContent model = new XmlSchemaSimpleContent();
                            XmlSchemaSimpleContentExtension ex = new XmlSchemaSimpleContentExtension();
                            model.Content = ex;
                            type.ContentModel = model;
                            ex.BaseTypeName = ExportPrimitiveMapping(pm, ns);
                        }
                    }
                }
                else {
                    type.IsMixed = true;
                }
            }
            bool anyAttribute = false;
            for (int i = 0; i < members.Length; i++) {
                AttributeAccessor accessor = members[i].Attribute;
                if (accessor != null) {
                    ExportAttributeAccessor(type, members[i].Attribute, members[i].CheckSpecified != SpecifiedAccessor.None || members[i].CheckShouldPersist, ns);
                    if (members[i].Attribute.Any)
                        anyAttribute = true;
                }
            }
            if (openModel && !anyAttribute) {
                AttributeAccessor any = new AttributeAccessor();
                any.Any = true;
                ExportAttributeAccessor(type, any, false, ns);
            }
        }
 private void WriteAttribute(object memberValue, AttributeAccessor attribute, object parent)
 {
     if (attribute.Mapping is SpecialMapping)
     {
         // TODO: this block is never hit by our tests.
         SpecialMapping special = (SpecialMapping)attribute.Mapping;
         if (special.TypeDesc.Kind == TypeKind.Attribute || special.TypeDesc.CanBeAttributeValue)
         {
             WriteXmlAttribute((XmlNode)memberValue, parent);
         }
         else
             throw new InvalidOperationException(SR.XmlInternalError);
     }
     else
     {
         string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "";
         WritePrimitive(WritePrimitiveMethodRequirement.WriteAttribute, attribute.Name, ns, attribute.Default, memberValue, attribute.Mapping, false, false, false);
     }
 }
Beispiel #6
0
        AttributeAccessor ImportAttribute(XmlSchemaAttribute attribute, string identifier, string ns) {
            if (attribute.Use == XmlSchemaUse.Prohibited) return null;
            if (!attribute.RefName.IsEmpty) {
                if (attribute.RefName.Namespace == XmlReservedNs.NsXml)
                    return ImportSpecialAttribute(attribute.RefName, identifier);
                else
                    return ImportAttribute(FindAttribute(attribute.RefName), identifier, attribute.RefName.Namespace);
            }
            TypeMapping mapping;
            if (attribute.Name.Length == 0) throw new InvalidOperationException(Res.GetString(Res.XmlAttributeHasNoName));
            if (identifier.Length == 0)
                identifier = CodeIdentifier.MakeValid(attribute.Name);
            else
                identifier += CodeIdentifier.MakePascal(attribute.Name);
            if (!attribute.SchemaTypeName.IsEmpty)
                mapping = (TypeMapping)ImportType(attribute.SchemaTypeName, typeof(TypeMapping), null);
            else if (attribute.SchemaType != null)
                mapping = ImportDataType((XmlSchemaSimpleType)attribute.SchemaType, ns, identifier, null);
            else {
                mapping = new PrimitiveMapping();
                mapping.TypeDesc = scope.GetTypeDesc(typeof(string));
                mapping.TypeName = mapping.TypeDesc.DataType.Name;
            }
            AttributeAccessor accessor = new AttributeAccessor();
            accessor.Name = attribute.Name;
            accessor.Namespace = ns;
            if (attribute.Form == XmlSchemaForm.None) {
                XmlSchema schema = schemas[ns];
                if (schema != null) accessor.Form = schema.AttributeFormDefault;
            }
            else {
                accessor.Form = attribute.Form;
            }
            accessor.CheckSpecial();
            accessor.Mapping = mapping;
            accessor.IsList = mapping.IsList;

            if (attribute.DefaultValue != null) {
                accessor.Default = ImportDefaultValue(mapping, attribute.DefaultValue);
            }
            else if (attribute.FixedValue != null) {
                accessor.Default = ImportDefaultValue(mapping, attribute.FixedValue);
            }
            return accessor;
        }
        void ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, string ns, Type choiceIdentifierType, bool rpc, bool openModel) {
            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.Mapping = ImportTypeMapping(modelScope.GetTypeModel(choiceIdentifierType), ns, ImportContext.Element, String.Empty, null);
                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(Res.GetString(Res.XmlIllegalAttributesArrayAttribute));

                    if (a.XmlAttribute != null && !accessor.TypeDesc.ArrayElementTypeDesc.IsPrimitive && !accessor.TypeDesc.ArrayElementTypeDesc.IsEnum) {

                        if (accessor.TypeDesc.ArrayElementTypeDesc.Kind == TypeKind.Serializable) {
                            throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttrOrTextInterface, accessorName, accessor.TypeDesc.ArrayElementTypeDesc.FullName, typeof(IXmlSerializable).Name));
                        }
                        else {
                            throw new InvalidOperationException(Res.GetString(Res.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);
                    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(Res.GetString(Res.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);
                        if (!(text.Mapping is SpecialMapping) && targetTypeDesc != typeScope.GetTypeDesc(typeof(string)))
                            throw new InvalidOperationException(Res.GetString(Res.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);
                        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)
                            throw new InvalidOperationException(Res.GetString(Res.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(Res.GetString(Res.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(Res.GetString(Res.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(Res.GetString(Res.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);
                        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(Res.GetString(Res.XmlSequenceMatch, "Order"));
                            sequenceId = xmlAnyElement.Order;
                        }
                    }
                }
                else {
                    if ((flags & arrayFlags) != 0) {
                        if ((flags & arrayFlags) != flags)
                            throw new InvalidOperationException(Res.GetString(Res.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);
                    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(Res.GetString(Res.XmlIllegalAttribute));

                if (accessor.TypeDesc.IsPrimitive || accessor.TypeDesc.IsEnum) {
                    if (a.XmlAnyElements.Count > 0) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAnyElement, accessor.TypeDesc.FullName));

                    if (a.XmlAttribute != null) {
                        if (a.XmlElements.Count > 0) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttribute));
                        if (a.XmlAttribute.Type != null) throw new InvalidOperationException(Res.GetString(Res.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);
                        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(Res.GetString(Res.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);
                            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(Res.GetString(Res.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);
                            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)
                                throw new InvalidOperationException(Res.GetString(Res.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(Res.GetString(Res.XmlSequenceMatch, "Order"));
                                sequenceId = xmlElement.Order;
                            }
                            AddUniqueAccessor(elements, element);
                            elementList.Add(element);
                        }
                    }
                }
                else if (a.Xmlns) {
                    if (flags != XmlAttributeFlags.XmlnsDeclarations)
                        throw new InvalidOperationException(Res.GetString(Res.XmlSoleXmlnsAttribute));
                    
                    if (accessorType != typeof(XmlSerializerNamespaces)) {
                        throw new InvalidOperationException(Res.GetString(Res.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(Res.GetString(Res.XmlIllegalAttrOrTextInterface, accessorName, accessor.TypeDesc.FullName, typeof(IXmlSerializable).Name));
                        }
                        else {
                            throw new InvalidOperationException(Res.GetString(Res.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);
                        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)
                            throw new InvalidOperationException(Res.GetString(Res.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(Res.GetString(Res.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(Res.GetString(Res.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(Res.GetString(Res.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);
                        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(Res.GetString(Res.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(Res.GetString(Res.XmlRpcLitArrayElement, accessor.Elements[0].Name));

                if (accessor.Xmlns != null)
                    throw new InvalidOperationException(Res.GetString(Res.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(Res.GetString(Res.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(Res.GetString(Res.XmlChoiceMissingValue, accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName, id, element.Name, element.Namespace));
                        }
                    }
                }
            }
            arrayNestingLevel = previousNestingLevel;
            savedArrayItemAttributes = previousArrayItemAttributes;
            savedArrayNamespace = previousArrayNamespace;
        }
Beispiel #8
0
        private void WriteAttributes(MemberMapping[] members, MemberMapping anyAttribute, Action <object> elseCall, ref object o)
        {
            MemberMapping xmlnsMember = null;
            var           attributes  = new List <AttributeAccessor>();

            while (Reader.MoveToNextAttribute())
            {
                bool memberFound = false;
                foreach (var member in members)
                {
                    if (member.Xmlns != null)
                    {
                        xmlnsMember = member;
                        continue;
                    }

                    if (member.Ignore)
                    {
                        continue;
                    }
                    AttributeAccessor attribute = member.Attribute;

                    if (attribute == null)
                    {
                        continue;
                    }
                    if (attribute.Any)
                    {
                        continue;
                    }

                    attributes.Add(attribute);

                    if (attribute.IsSpecialXmlNamespace)
                    {
                        memberFound = XmlNodeEqual(Reader, attribute.Name, XmlReservedNs.NsXml);
                    }
                    else
                    {
                        memberFound = XmlNodeEqual(Reader, attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "");
                    }

                    if (memberFound)
                    {
                        WriteAttribute(o, member);
                        memberFound = true;
                        break;
                    }
                }

                if (memberFound)
                {
                    continue;
                }

                bool flag2 = false;
                if (xmlnsMember != null)
                {
                    if (IsXmlnsAttribute(Reader.Name))
                    {
                        if (GetMemberType(xmlnsMember.MemberInfo) == typeof(XmlSerializerNamespaces))
                        {
                            var xmlnsMemberSource = GetMemberValue(o, xmlnsMember.MemberInfo) as XmlSerializerNamespaces;
                            if (xmlnsMemberSource == null)
                            {
                                xmlnsMemberSource = new XmlSerializerNamespaces();
                                SetMemberValue(o, xmlnsMemberSource, xmlnsMember.MemberInfo);
                            }

                            xmlnsMemberSource.Add(Reader.Name.Length == 5 ? "" : Reader.LocalName, Reader.Value);
                        }
                        else
                        {
                            throw new InvalidOperationException("xmlnsMemberSource is not of type XmlSerializerNamespaces");
                        }
                    }
                    else
                    {
                        flag2 = true;
                    }
                }
                else if (!IsXmlnsAttribute(Reader.Name))
                {
                    flag2 = true;
                }

                if (flag2)
                {
                    if (anyAttribute != null)
                    {
                        var attr = Document.ReadNode(Reader) as XmlAttribute;
                        ParseWsdlArrayType(attr);
                        WriteAttribute(o, anyAttribute, attr);
                    }
                    else
                    {
                        elseCall(o);
                    }
                }
            }
        }
 private AttributeAccessor ImportSpecialAttribute(XmlQualifiedName name, string identifier)
 {
     PrimitiveMapping mapping;
     mapping = new PrimitiveMapping {
         TypeDesc = base.Scope.GetTypeDesc(typeof(string)),
         TypeName = mapping.TypeDesc.DataType.Name
     };
     AttributeAccessor accessor = new AttributeAccessor {
         Name = name.Name,
         Namespace = "http://www.w3.org/XML/1998/namespace"
     };
     accessor.CheckSpecial();
     accessor.Mapping = mapping;
     return accessor;
 }
Beispiel #10
0
        void ExportAttributeAccessor(XmlSchemaComplexType type, AttributeAccessor accessor, string ns)
        {
            if (accessor == null)
            {
                return;
            }
            XmlSchemaObjectCollection attributes;

            if (type.ContentModel != null)
            {
                if (type.ContentModel.Content is XmlSchemaComplexContentRestriction)
                {
                    attributes = ((XmlSchemaComplexContentRestriction)type.ContentModel.Content).Attributes;
                }
                else if (type.ContentModel.Content is XmlSchemaComplexContentExtension)
                {
                    attributes = ((XmlSchemaComplexContentExtension)type.ContentModel.Content).Attributes;
                }
                else if (type.ContentModel.Content is XmlSchemaSimpleContentExtension)
                {
                    attributes = ((XmlSchemaSimpleContentExtension)type.ContentModel.Content).Attributes;
                }
                else
                {
                    throw new InvalidOperationException(Res.GetString(Res.XmlInvalidContent, type.ContentModel.Content.GetType().Name));
                }
            }
            else
            {
                attributes = type.Attributes;
            }

            if (accessor.IsSpecialXmlNamespace)
            {
                // add <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
                AddSchemaImport(XmlReservedNs.NsXml, ns);

                // generate <xsd:attribute ref="xml:lang" use="optional" />
                XmlSchemaAttribute attribute = new XmlSchemaAttribute();
                attribute.Use     = XmlSchemaUse.Optional;
                attribute.RefName = new XmlQualifiedName(accessor.Name, XmlReservedNs.NsXml);
                attributes.Add(attribute);
            }
            else if (accessor.Any)
            {
                if (type.ContentModel == null)
                {
                    type.AnyAttribute = new XmlSchemaAnyAttribute();
                }
                else
                {
                    XmlSchemaContent content = type.ContentModel.Content;
                    if (content is XmlSchemaComplexContentExtension)
                    {
                        XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)content;
                        extension.AnyAttribute = new XmlSchemaAnyAttribute();
                    }
                    else if (content is XmlSchemaComplexContentRestriction)
                    {
                        XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)content;
                        restriction.AnyAttribute = new XmlSchemaAnyAttribute();
                    }
                }
            }
            else
            {
                XmlSchemaAttribute attribute = new XmlSchemaAttribute();
                attribute.Use = XmlSchemaUse.None;
                if (accessor.HasDefault)
                {
                    attribute.Use = XmlSchemaUse.Optional;
                }
                attribute.Name = accessor.Name;
                if (accessor.Namespace == null || accessor.Namespace == ns)
                {
                    // determine the form attribute value
                    XmlSchema schema = schemas[ns];
                    if (schema == null)
                    {
                        attribute.Form = accessor.Form == attributeFormDefault ? XmlSchemaForm.None : accessor.Form;
                    }
                    else
                    {
                        attribute.Form = accessor.Form == schema.AttributeFormDefault ? XmlSchemaForm.None : accessor.Form;
                    }
                    attributes.Add(attribute);
                }
                else
                {
                    // we are going to add the attribute to the top-level items. "use" attribute should not be set
                    attribute.Use  = XmlSchemaUse.None;
                    attribute.Form = accessor.Form;
                    AddSchemaItem(attribute, accessor.Namespace, ns);
                    XmlSchemaAttribute refAttribute = new XmlSchemaAttribute();
                    refAttribute.Use     = XmlSchemaUse.None;
                    refAttribute.RefName = new XmlQualifiedName(accessor.Name, accessor.Namespace);
                    attributes.Add(refAttribute);
                }
                if (accessor.Mapping is PrimitiveMapping)
                {
                    PrimitiveMapping pm = (PrimitiveMapping)accessor.Mapping;
                    if (pm.IsList)
                    {
                        // create local simple type for the list-like attributes
                        XmlSchemaSimpleType     dataType = new XmlSchemaSimpleType();
                        XmlSchemaSimpleTypeList list     = new XmlSchemaSimpleTypeList();
                        list.ItemTypeName    = ExportPrimitiveMapping(pm, accessor.Namespace == null ? ns : accessor.Namespace);
                        dataType.Content     = list;
                        attribute.SchemaType = dataType;
                    }
                    else
                    {
                        attribute.SchemaTypeName = ExportPrimitiveMapping(pm, accessor.Namespace == null ? ns : accessor.Namespace);
                    }
                }
                else if (!(accessor.Mapping is SpecialMapping))
                {
                    throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
                }

                if (accessor.HasDefault && accessor.Mapping.TypeDesc.HasDefaultSupport)
                {
                    attribute.DefaultValue = ExportDefaultValue(accessor.Mapping, accessor.Default);
                }
            }
        }
 private void AddMemberMetadata(CodeMemberField field, CodeAttributeDeclarationCollection metadata, MemberMapping member, string ns, bool forceUseMemberName, CodeCommentStatementCollection comments, CodeConstructor ctor)
 {
     if (member.Xmlns != null)
     {
         CodeAttributeDeclaration declaration = new CodeAttributeDeclaration(typeof(XmlNamespaceDeclarationsAttribute).FullName);
         metadata.Add(declaration);
     }
     else if (member.Attribute != null)
     {
         AttributeAccessor attribute = member.Attribute;
         if (attribute.Any)
         {
             this.ExportAnyAttribute(metadata);
         }
         else
         {
             TypeMapping mapping = attribute.Mapping;
             string      str     = Accessor.UnescapeName(attribute.Name);
             bool        flag    = (mapping.TypeDesc == member.TypeDesc) || (member.TypeDesc.IsArrayLike && (mapping.TypeDesc == member.TypeDesc.ArrayElementTypeDesc));
             bool        flag2   = (str == member.Name) && !forceUseMemberName;
             bool        flag3   = attribute.Namespace == ns;
             bool        flag4   = attribute.Form != XmlSchemaForm.Qualified;
             this.ExportAttribute(metadata, flag2 ? null : str, (flag3 || flag4) ? null : attribute.Namespace, flag ? null : mapping.TypeDesc, mapping.TypeDesc, flag4 ? XmlSchemaForm.None : attribute.Form);
             this.AddDefaultValueAttribute(field, metadata, attribute.Default, mapping, comments, member.TypeDesc, attribute, ctor);
         }
     }
     else
     {
         if (member.Text != null)
         {
             TypeMapping mapping2 = member.Text.Mapping;
             bool        flag5    = (mapping2.TypeDesc == member.TypeDesc) || (member.TypeDesc.IsArrayLike && (mapping2.TypeDesc == member.TypeDesc.ArrayElementTypeDesc));
             this.ExportText(metadata, flag5 ? null : mapping2.TypeDesc, mapping2.TypeDesc.IsAmbiguousDataType ? mapping2.TypeDesc.DataType.Name : null);
         }
         if (member.Elements.Length == 1)
         {
             ElementAccessor accessor = member.Elements[0];
             TypeMapping     mapping3 = accessor.Mapping;
             string          name     = Accessor.UnescapeName(accessor.Name);
             bool            flag6    = (name == member.Name) && !forceUseMemberName;
             bool            flag7    = mapping3 is ArrayMapping;
             bool            flag8    = accessor.Namespace == ns;
             bool            flag9    = accessor.Form != XmlSchemaForm.Unqualified;
             if (accessor.Any)
             {
                 this.ExportAnyElement(metadata, name, accessor.Namespace, member.SequenceId);
             }
             else if (flag7)
             {
                 TypeDesc     typeDesc = mapping3.TypeDesc;
                 TypeDesc     desc2    = member.TypeDesc;
                 ArrayMapping array    = (ArrayMapping)mapping3;
                 if ((!flag6 || !flag8) || ((accessor.IsNullable || !flag9) || (member.SequenceId != -1)))
                 {
                     this.ExportArray(metadata, flag6 ? null : name, flag8 ? null : accessor.Namespace, accessor.IsNullable, flag9 ? XmlSchemaForm.None : accessor.Form, member.SequenceId);
                 }
                 else if (mapping3.TypeDesc.ArrayElementTypeDesc == new TypeScope().GetTypeDesc(typeof(byte)))
                 {
                     this.ExportArray(metadata, null, null, false, XmlSchemaForm.None, member.SequenceId);
                 }
                 this.ExportArrayElements(metadata, array, accessor.Namespace, member.TypeDesc.ArrayElementTypeDesc, 0);
             }
             else
             {
                 bool flag10 = (mapping3.TypeDesc == member.TypeDesc) || (member.TypeDesc.IsArrayLike && (mapping3.TypeDesc == member.TypeDesc.ArrayElementTypeDesc));
                 if (member.TypeDesc.IsArrayLike)
                 {
                     flag6 = false;
                 }
                 this.ExportElement(metadata, flag6 ? null : name, flag8 ? null : accessor.Namespace, flag10 ? null : mapping3.TypeDesc, mapping3.TypeDesc, accessor.IsNullable, flag9 ? XmlSchemaForm.None : accessor.Form, member.SequenceId);
             }
             this.AddDefaultValueAttribute(field, metadata, accessor.Default, mapping3, comments, member.TypeDesc, accessor, ctor);
         }
         else
         {
             for (int i = 0; i < member.Elements.Length; i++)
             {
                 ElementAccessor accessor3 = member.Elements[i];
                 string          str3      = Accessor.UnescapeName(accessor3.Name);
                 bool            flag11    = accessor3.Namespace == ns;
                 if (accessor3.Any)
                 {
                     this.ExportAnyElement(metadata, str3, accessor3.Namespace, member.SequenceId);
                 }
                 else
                 {
                     bool flag12 = accessor3.Form != XmlSchemaForm.Unqualified;
                     this.ExportElement(metadata, str3, flag11 ? null : accessor3.Namespace, accessor3.Mapping.TypeDesc, accessor3.Mapping.TypeDesc, accessor3.IsNullable, flag12 ? XmlSchemaForm.None : accessor3.Form, member.SequenceId);
                 }
             }
         }
         if (member.ChoiceIdentifier != null)
         {
             CodeAttributeDeclaration declaration2 = new CodeAttributeDeclaration(typeof(XmlChoiceIdentifierAttribute).FullName);
             declaration2.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(member.ChoiceIdentifier.MemberName)));
             metadata.Add(declaration2);
         }
         if (member.Ignore)
         {
             CodeAttributeDeclaration declaration3 = new CodeAttributeDeclaration(typeof(XmlIgnoreAttribute).FullName);
             metadata.Add(declaration3);
         }
     }
 }
Beispiel #12
0
        void AddMemberMetadata(CodeMemberField field, CodeAttributeDeclarationCollection metadata, MemberMapping member, string ns, bool forceUseMemberName)
        {
            if (member.Xmlns != null)
            {
                CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlNamespaceDeclarationsAttribute).FullName);
                metadata.Add(attribute);
            }
            else if (member.Attribute != null)
            {
                AttributeAccessor attribute = member.Attribute;
                if (attribute.Any)
                {
                    ExportAnyAttribute(metadata);
                }
                else
                {
                    TypeMapping mapping  = (TypeMapping)attribute.Mapping;
                    string      attrName = Accessor.UnescapeName(attribute.Name);
                    bool        sameType = mapping.TypeDesc == member.TypeDesc ||
                                           (member.TypeDesc.IsArrayLike && mapping.TypeDesc == member.TypeDesc.ArrayElementTypeDesc);
                    bool sameName = attrName == member.Name;
                    bool sameNs   = attribute.Namespace == ns;
                    ExportAttribute(metadata,
                                    sameName ? null : attrName,
                                    sameNs ? null : attribute.Namespace,
                                    sameType ? null : mapping.TypeDesc,
                                    mapping.TypeDesc, attribute.Form);

                    if (attribute.HasDefault)
                    {
                        AddDefaultValueAttribute(field, metadata, attribute.Default, mapping);
                    }
                }
            }
            else
            {
                if (member.Text != null)
                {
                    TypeMapping mapping  = (TypeMapping)member.Text.Mapping;
                    bool        sameType = mapping.TypeDesc == member.TypeDesc ||
                                           (member.TypeDesc.IsArrayLike && mapping.TypeDesc == member.TypeDesc.ArrayElementTypeDesc);
                    ExportText(metadata, sameType ? null : mapping.TypeDesc, mapping.TypeDesc.IsAmbiguousDataType ? mapping.TypeDesc.DataType.Name : null);
                }
                if (member.Elements.Length == 1)
                {
                    ElementAccessor element  = member.Elements[0];
                    TypeMapping     mapping  = (TypeMapping)element.Mapping;
                    string          elemName = Accessor.UnescapeName(element.Name);
                    bool            sameName = ((elemName == member.Name) && !forceUseMemberName);
                    bool            isArray  = mapping is ArrayMapping;
                    bool            sameNs   = element.Namespace == ns;

                    if (element.Any)
                    {
                        ExportAnyElement(metadata, null, null);
                    }
                    else if (isArray)
                    {
                        bool         sameType = mapping.TypeDesc == member.TypeDesc;
                        ArrayMapping array    = (ArrayMapping)mapping;
                        if (!sameName || !sameNs || element.IsNullable)
                        {
                            ExportArray(metadata, sameName ? null : elemName, sameNs ? null : element.Namespace, element.IsNullable, element.Form);
                        }
                        ExportArrayElements(metadata, array, ns, member.TypeDesc.ArrayElementTypeDesc, 0);
                    }
                    else
                    {
                        bool sameType = mapping.TypeDesc == member.TypeDesc ||
                                        (member.TypeDesc.IsArrayLike && mapping.TypeDesc == member.TypeDesc.ArrayElementTypeDesc);
                        if (member.TypeDesc.IsArrayLike)
                        {
                            sameName = false;
                        }
                        if (member.TypeDesc.IsAmbiguousDataType || member.TypeDesc.IsArrayLike || !sameName || !sameType || !sameNs || element.IsNullable || element.Form != XmlSchemaForm.Qualified)
                        {
                            ExportElement(metadata, sameName ? null : elemName, sameNs ? null : element.Namespace, sameType ? null : mapping.TypeDesc, mapping.TypeDesc, element.IsNullable, element.Form);
                        }
                    }
                    if (element.HasDefault)
                    {
                        AddDefaultValueAttribute(field, metadata, element.Default, mapping);
                    }
                }
                else
                {
                    for (int i = 0; i < member.Elements.Length; i++)
                    {
                        ElementAccessor element  = member.Elements[i];
                        string          elemName = Accessor.UnescapeName(element.Name);
                        if (element.Any)
                        {
                            ExportAnyElement(metadata, null, null);
                        }
                        else
                        {
                            bool sameNs = element.Namespace == ns;
                            ExportElement(metadata, elemName, sameNs ? null : element.Namespace, ((TypeMapping)element.Mapping).TypeDesc, ((TypeMapping)element.Mapping).TypeDesc, element.IsNullable, element.Form);
                        }
                    }
                }
                if (member.ChoiceIdentifier != null)
                {
                    CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlChoiceIdentifierAttribute).FullName);
                    attribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(member.ChoiceIdentifier.MemberName)));
                    metadata.Add(attribute);
                }
                if (member.Ignore)
                {
                    CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlIgnoreAttribute).FullName);
                    metadata.Add(attribute);
                }
            }
        }
 void WriteAttribute(string source, AttributeAccessor attribute, string parent) {
     if (attribute.Mapping is SpecialMapping) {
         SpecialMapping special = (SpecialMapping)attribute.Mapping;
         if (special.TypeDesc.Kind == TypeKind.Attribute || special.TypeDesc.CanBeAttributeValue) {
             writer.Write("WriteXmlAttribute(");
             writer.Write(source);
             writer.Write(", ");
             writer.Write(parent);
             writer.WriteLine(");");
         }
         else
             throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
     }
     else {
         TypeDesc typeDesc = attribute.Mapping.TypeDesc;
         WritePrimitive("WriteAttribute", attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "", attribute.Default, "(" + CodeIdentifier.EscapeKeywords(typeDesc.FullName) + ")" + source, attribute.Mapping, false);
     }
 }
        void WriteMember(string source, AttributeAccessor attribute, TypeDesc memberTypeDesc, string parent) {
            if (memberTypeDesc.IsAbstract) return;
            if (memberTypeDesc.IsArrayLike) {
                writer.WriteLine("{");
                writer.Indent++;
                string fullTypeName = CodeIdentifier.EscapeKeywords(memberTypeDesc.FullName);
                writer.Write(fullTypeName);
                writer.Write(" a = (");
                writer.Write(fullTypeName);
                writer.Write(")");
                writer.Write(source);
                writer.WriteLine(";");

                if (memberTypeDesc.IsNullable) {
                    writer.WriteLine("if (a != null) {");
                    writer.Indent++;
                }
                if (attribute.IsList) {
                    if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc)) {
                        writer.Write("Writer.WriteStartAttribute(null, ");
                        WriteQuotedCSharpString(attribute.Name);
                        writer.Write(", ");
                        string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
                        if (ns != null) {
                            WriteQuotedCSharpString(ns);
                        }
                        else {
                            writer.Write("null");
                        }
                        writer.WriteLine(");");
                    }
                    else {
                        writer.Write(typeof(StringBuilder).FullName);
                        writer.Write(" sb = new ");
                        writer.Write(typeof(StringBuilder).FullName);
                        writer.WriteLine("();");
                    }
                }
                TypeDesc arrayElementTypeDesc = memberTypeDesc.ArrayElementTypeDesc;

                if (memberTypeDesc.IsEnumerable) {
                    writer.Write(typeof(IEnumerator).FullName);
                    writer.WriteLine(" e = a.GetEnumerator();");

                    writer.WriteLine("if (e != null)");
                    writer.WriteLine("while (e.MoveNext()) {");
                    writer.Indent++;

                    string arrayTypeFullName = CodeIdentifier.EscapeKeywords(arrayElementTypeDesc.FullName);
                    writer.Write(arrayTypeFullName);
                    writer.Write(" ai = (");
                    writer.Write(arrayTypeFullName);
                    writer.WriteLine(")e.Current;");
                }
                else {
                    writer.Write("for (int i = 0; i < a.");
                    writer.Write(memberTypeDesc.ArrayLengthName);
                    writer.WriteLine("; i++) {");
                    writer.Indent++;
                    string arrayTypeFullName = CodeIdentifier.EscapeKeywords(arrayElementTypeDesc.FullName);
                    writer.Write(arrayTypeFullName);
                    writer.Write(" ai = (");
                    writer.Write(arrayTypeFullName);
                    writer.WriteLine(")a[i];");
                }
                if (attribute.IsList) {
                    // check to see if we can write values of the attribute sequentially
                    if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc)) {
                        writer.WriteLine("if (i != 0) Writer.WriteString(\" \");");
                        writer.Write("WriteValue(");
                    }
                    else {
                        writer.WriteLine("if (i != 0) sb.Append(\" \");");
                        writer.Write("sb.Append(");
                    }
                    if (attribute.Mapping is EnumMapping)
                        WriteEnumValue((EnumMapping)attribute.Mapping, "ai");
                    else
                        WritePrimitiveValue(arrayElementTypeDesc, "ai");
                    writer.WriteLine(");");
                }
                else {
                    WriteAttribute("ai", attribute, parent);
                }
                writer.Indent--;
                writer.WriteLine("}");
                if (attribute.IsList) {
                    // check to see if we can write values of the attribute sequentially
                    if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc)) {
                        writer.WriteLine("Writer.WriteEndAttribute();");
                    }
                    else {
                        writer.WriteLine("if (sb.Length != 0) {");
                        writer.Indent++;
                    
                        writer.Write("WriteAttribute(");
                        WriteQuotedCSharpString(attribute.Name);
                        writer.Write(", ");
                        string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
                        if (ns != null) {
                            WriteQuotedCSharpString(ns);
                            writer.Write(", ");
                        }
                        writer.WriteLine("sb.ToString());");
                        writer.Indent--;
                        writer.WriteLine("}");
                    }
                }

                if (memberTypeDesc.IsNullable) {
                    writer.Indent--;
                    writer.WriteLine("}");
                }
                writer.Indent--;
                writer.WriteLine("}");
            }
            else {
                WriteAttribute(source, attribute, parent);
            }
        }
 private void WriteAttribute(string source, AttributeAccessor attribute, string parent)
 {
     if (attribute.Mapping is SpecialMapping)
     {
         SpecialMapping mapping = (SpecialMapping) attribute.Mapping;
         if ((mapping.TypeDesc.Kind != TypeKind.Attribute) && !mapping.TypeDesc.CanBeAttributeValue)
         {
             throw new InvalidOperationException(Res.GetString("XmlInternalError"));
         }
         base.Writer.Write("WriteXmlAttribute(");
         base.Writer.Write(source);
         base.Writer.Write(", ");
         base.Writer.Write(parent);
         base.Writer.WriteLine(");");
     }
     else
     {
         TypeDesc typeDesc = attribute.Mapping.TypeDesc;
         if (!typeDesc.UseReflection)
         {
             source = "((" + typeDesc.CSharpName + ")" + source + ")";
         }
         this.WritePrimitive("WriteAttribute", attribute.Name, (attribute.Form == XmlSchemaForm.Qualified) ? attribute.Namespace : "", attribute.Default, source, attribute.Mapping, false, false, false);
     }
 }
 private void ImportAnyAttributeMember(XmlSchemaAnyAttribute any, CodeIdentifiers members, CodeIdentifiers membersScope)
 {
     SpecialMapping mapping;
     MemberMapping mapping2;
     mapping = new SpecialMapping {
         TypeDesc = base.Scope.GetTypeDesc(typeof(XmlAttribute)),
         TypeName = mapping.TypeDesc.Name
     };
     AttributeAccessor accessor = new AttributeAccessor {
         Any = true,
         Mapping = mapping
     };
     mapping2 = new MemberMapping {
         Elements = new ElementAccessor[0],
         Attribute = accessor,
         Name = membersScope.MakeRightCase("AnyAttr"),
         Name = membersScope.AddUnique(mapping2.Name, mapping2)
     };
     members.Add(mapping2.Name, mapping2);
     mapping2.TypeDesc = accessor.Mapping.TypeDesc;
     mapping2.TypeDesc = mapping2.TypeDesc.CreateArrayTypeDesc();
 }
Beispiel #17
0
 AttributeAccessor ImportSpecialAttribute(XmlQualifiedName name, string identifier) {
     PrimitiveMapping mapping = new PrimitiveMapping();
     mapping.TypeDesc = scope.GetTypeDesc(typeof(string));
     mapping.TypeName = mapping.TypeDesc.DataType.Name;
     AttributeAccessor accessor = new AttributeAccessor();
     accessor.Name = name.Name;
     accessor.Namespace = XmlReservedNs.NsXml;
     accessor.CheckSpecial();
     accessor.Mapping = mapping;
     return accessor;
 }
 private AttributeAccessor ImportAttribute(XmlSchemaAttribute attribute, string identifier, string ns, XmlSchemaAttribute defaultValueProvider)
 {
     TypeMapping defaultMapping;
     if (attribute.Use == XmlSchemaUse.Prohibited)
     {
         return null;
     }
     if (!attribute.RefName.IsEmpty)
     {
         if (attribute.RefName.Namespace == "http://www.w3.org/XML/1998/namespace")
         {
             return this.ImportSpecialAttribute(attribute.RefName, identifier);
         }
         return this.ImportAttribute(this.FindAttribute(attribute.RefName), identifier, attribute.RefName.Namespace, defaultValueProvider);
     }
     if (attribute.Name.Length == 0)
     {
         throw new InvalidOperationException(Res.GetString("XmlAttributeHasNoName"));
     }
     if (identifier.Length == 0)
     {
         identifier = CodeIdentifier.MakeValid(attribute.Name);
     }
     else
     {
         identifier = identifier + CodeIdentifier.MakePascal(attribute.Name);
     }
     if (!attribute.SchemaTypeName.IsEmpty)
     {
         defaultMapping = this.ImportType(attribute.SchemaTypeName, typeof(TypeMapping), null, TypeFlags.CanBeAttributeValue, false);
     }
     else if (attribute.SchemaType != null)
     {
         defaultMapping = this.ImportDataType(attribute.SchemaType, ns, identifier, null, TypeFlags.CanBeAttributeValue, false);
     }
     else
     {
         defaultMapping = this.GetDefaultMapping(TypeFlags.CanBeAttributeValue);
     }
     if ((defaultMapping != null) && !defaultMapping.TypeDesc.IsMappedType)
     {
         this.RunSchemaExtensions(defaultMapping, attribute.SchemaTypeName, attribute.SchemaType, attribute, TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue | TypeFlags.CanBeAttributeValue);
     }
     AttributeAccessor accessor = new AttributeAccessor {
         Name = attribute.Name,
         Namespace = ns,
         Form = this.AttributeForm(ns, attribute)
     };
     accessor.CheckSpecial();
     accessor.Mapping = defaultMapping;
     accessor.IsList = defaultMapping.IsList;
     accessor.IsOptional = attribute.Use != XmlSchemaUse.Required;
     if (defaultValueProvider.DefaultValue != null)
     {
         accessor.Default = defaultValueProvider.DefaultValue;
         return accessor;
     }
     if (defaultValueProvider.FixedValue != null)
     {
         accessor.Default = defaultValueProvider.FixedValue;
         accessor.IsFixed = true;
         return accessor;
     }
     if (attribute != defaultValueProvider)
     {
         if (attribute.DefaultValue != null)
         {
             accessor.Default = attribute.DefaultValue;
             return accessor;
         }
         if (attribute.FixedValue != null)
         {
             accessor.Default = attribute.FixedValue;
             accessor.IsFixed = true;
         }
     }
     return accessor;
 }
Beispiel #19
0
        void ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, string ns, XmlSchemaForm form, Type choiceIdentifierType) {
            int previousNestingLevel = arrayNestingLevel;
            XmlArrayItemAttributes previousArrayItemAttributes = savedArrayItemAttributes;
            string previousArrayNamespace = savedArrayNamespace;
            arrayNestingLevel = 0;
            savedArrayItemAttributes = null;
            savedArrayNamespace = null;
            Type accessorType = model.FieldType;
            string accessorName = model.Name;
            NameTable elements = new NameTable();
            accessor.TypeDesc = typeScope.GetTypeDesc(accessorType);
            XmlAttributeFlags flags = a.XmlFlags;
            accessor.Ignore = a.XmlIgnore;
            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.Mapping = ImportTypeMapping(modelScope.GetTypeModel(choiceIdentifierType), ns, ImportContext.Element, String.Empty);
            }

            if (accessor.TypeDesc.IsArrayLike) {
                Type arrayElementType = TypeScope.GetArrayElementType(accessorType);

                if ((flags & attrFlags) != 0) {
                    if ((flags & attrFlags) != flags) 
                        throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttributesArrayAttribute));

                    if (a.XmlAttribute != null && !accessor.TypeDesc.ArrayElementTypeDesc.IsPrimitive && !accessor.TypeDesc.ArrayElementTypeDesc.IsEnum)
                        throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttrOrText, accessorName));

                    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.EscapeName(a.XmlAttribute.AttributeName.Length == 0 ? accessorName : a.XmlAttribute.AttributeName, true);
                    attribute.Namespace = a.XmlAttribute.Namespace == null ? ns : a.XmlAttribute.Namespace;
                    attribute.Form = a.XmlAttribute.Form;   // == XmlSchemaForm.None ? 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, XmlSchemaForm.Qualified, isList);
                    attribute.IsList = isList;
                    attribute.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                    attribute.Any = (a.XmlAnyAttribute != null);
                    accessor.Attribute = attribute;

                }
                else if ((flags & elemFlags) != 0) {
                    if ((flags & elemFlags) != flags)
                        throw new InvalidOperationException(Res.GetString(Res.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, XmlSchemaForm.Qualified, true);
                        if (!(text.Mapping is SpecialMapping) && targetTypeDesc != typeScope.GetTypeDesc(typeof(string)))
                            throw new InvalidOperationException(Res.GetString(Res.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 = xmlElement.Namespace == null ? ns : xmlElement.Namespace;
                        element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, xmlElement.DataType);
                        if (a.XmlElements.Count == 1) {
	                        element.Name = Accessor.EscapeName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName, false);
                        }
                        else {
	                        element.Name = Accessor.EscapeName(xmlElement.ElementName.Length == 0 ? element.Mapping.TypeName : xmlElement.ElementName, false);
                        }
                        element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                        element.IsNullable = xmlElement.IsNullable;
                        element.Form = xmlElement.Form == XmlSchemaForm.None ? form : xmlElement.Form;
                        CheckForm(element.Form, ns != element.Namespace);
                        CheckNullable(element.IsNullable, targetTypeDesc);
                        element = ReconcileLocalAccessor(element, ns);
                        AddUniqueAccessor(elements, element);
                    }
                    
                    for (int i = 0; i < a.XmlAnyElements.Count; i++) {
                        XmlAnyElementAttribute xmlAnyElement = a.XmlAnyElements[i];
                        Type targetType = typeof(XmlNode).IsAssignableFrom(arrayElementType) ? arrayElementType : typeof(XmlElement);
                        ElementAccessor element = new ElementAccessor();
                        element.Name = Accessor.EscapeName(xmlAnyElement.Name, false);
                        element.Namespace = xmlAnyElement.Namespace == null ? ns : xmlAnyElement.Namespace;
                        element.Any = true;
                        TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType);
                        TypeModel typeModel = modelScope.GetTypeModel(targetType);
                        if (element.Name != String.Empty)
                            typeModel.TypeDesc.IsMixed = true;
                        else if (xmlAnyElement.Namespace != null)
                            throw new InvalidOperationException(Res.GetString(Res.XmlAnyElementNamespace, accessorName, xmlAnyElement.Namespace));
                        element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, String.Empty);
                        element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                        element.IsNullable = false;
                        element.Form = form;
                        CheckForm(element.Form, ns != element.Namespace);
                        CheckNullable(element.IsNullable, targetTypeDesc);
                        element = ReconcileLocalAccessor(element, ns);
                        elements.Add(element.Name, element.Namespace, element);
                    }

                }
                else {
                    if ((flags & arrayFlags) != 0) {
                        if ((flags & arrayFlags) != flags)
                            throw new InvalidOperationException(Res.GetString(Res.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 = Accessor.EscapeName(a.XmlArray.ElementName.Length == 0 ? accessorName : a.XmlArray.ElementName, false);
                    arrayElement.Namespace = a.XmlArray.Namespace == null ? ns : a.XmlArray.Namespace;
                    savedArrayItemAttributes = a.XmlArrayItems;
                    savedArrayNamespace = arrayElement.Namespace;
                    ArrayMapping arrayMapping = ImportArrayLikeMapping(modelScope.GetArrayModel(accessorType), ns, form);
                    arrayElement.Mapping = arrayMapping;
                    arrayElement.IsNullable = a.XmlArray.IsNullable;
                    arrayElement.Form = a.XmlArray.Form == XmlSchemaForm.None ? form : a.XmlArray.Form;
                    CheckForm(arrayElement.Form, ns != arrayElement.Namespace);
                    CheckNullable(arrayElement.IsNullable, accessor.TypeDesc);
                    savedArrayItemAttributes = null;
                    savedArrayNamespace = null;
                    arrayElement = ReconcileLocalAccessor(arrayElement, ns);
                    AddUniqueAccessor(elements, 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(Res.GetString(Res.XmlIllegalAttribute));

                if (accessor.TypeDesc.IsPrimitive || accessor.TypeDesc.IsEnum) {
                    if (a.XmlAnyElements.Count > 0) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAnyElement));

                    if (a.XmlAttribute != null) {
                        if (a.XmlElements.Count > 0) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttribute));
                        if (a.XmlAttribute.Type != null) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalType, "XmlAttribute"));
                        AttributeAccessor attribute = new AttributeAccessor();
                        attribute.Name = Accessor.EscapeName(a.XmlAttribute.AttributeName.Length == 0 ? accessorName : a.XmlAttribute.AttributeName, true);
                        attribute.Namespace = a.XmlAttribute.Namespace == null ? ns : a.XmlAttribute.Namespace;
                        attribute.Form = a.XmlAttribute.Form;   // == XmlSchemaForm.None ? 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);
                        attribute.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                        attribute.Any = a.XmlAnyAttribute != null;
                        accessor.Attribute = attribute;
                    }
                    else {
                        if (a.XmlText != null) {
                            if (a.XmlText.Type != null && a.XmlText.Type != accessorType) 
                                throw new InvalidOperationException(Res.GetString(Res.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);
                            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(Res.GetString(Res.XmlIllegalType, "XmlElement"));
                            }
                            ElementAccessor element = new ElementAccessor();
                            element.Name = Accessor.EscapeName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName, false);
                            element.Namespace = xmlElement.Namespace == null ? ns : xmlElement.Namespace;
                            element.Mapping = ImportTypeMapping(modelScope.GetTypeModel(accessorType), element.Namespace, ImportContext.Element, xmlElement.DataType);
                            element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                            element.IsNullable = xmlElement.IsNullable;
                            element.Form = xmlElement.Form == XmlSchemaForm.None ? form : xmlElement.Form;
                            CheckForm(element.Form, ns != element.Namespace);
                            CheckNullable(element.IsNullable, accessor.TypeDesc);
                            element = ReconcileLocalAccessor(element, ns);
                            AddUniqueAccessor(elements, element);
                        }
                    }
                }
                else if (a.Xmlns) {
                    if (flags != XmlAttributeFlags.XmlnsDeclarations)
                        throw new InvalidOperationException(Res.GetString(Res.XmlSoleXmlnsAttribute));
                    
                    if (accessorType != typeof(XmlSerializerNamespaces)) {
                        throw new InvalidOperationException(Res.GetString(Res.XmlXmlnsInvalidType, accessorName, accessorType.FullName, typeof(XmlSerializerNamespaces).FullName));
                    }
                    accessor.Xmlns = new XmlnsAccessor();
                    accessor.Ignore = true;
                }
                else  {
                    if (a.XmlAttribute != null || a.XmlText != null) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttrOrText, accessorName));
                    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 = xmlElement.Namespace == null ? ns : xmlElement.Namespace;
                        element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, xmlElement.DataType);
                        if (a.XmlElements.Count == 1) {
                            element.Name = Accessor.EscapeName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName, false);
                        }
                        else {
                            element.Name = Accessor.EscapeName(xmlElement.ElementName.Length == 0 ? element.Mapping.TypeName : xmlElement.ElementName, false);
                        }
                        element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                        element.IsNullable = xmlElement.IsNullable;
                        element.Form = xmlElement.Form == XmlSchemaForm.None ? form : xmlElement.Form;
                        CheckForm(element.Form, ns != element.Namespace);
                        CheckNullable(element.IsNullable, targetTypeDesc);
                        element = ReconcileLocalAccessor(element, ns);
                        AddUniqueAccessor(elements, element);
                    }
                    
                    for (int i = 0; i < a.XmlAnyElements.Count; i++) {
                        XmlAnyElementAttribute xmlAnyElement = a.XmlAnyElements[i];
                        Type targetType = typeof(XmlNode).IsAssignableFrom(accessorType) ? accessorType : typeof(XmlElement);
                        ElementAccessor element = new ElementAccessor();
                        element.Name = Accessor.EscapeName(xmlAnyElement.Name, false);
                        element.Namespace = xmlAnyElement.Namespace == null ? ns : xmlAnyElement.Namespace;
                        element.Any = true;
                        TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType);
                        TypeModel typeModel = modelScope.GetTypeModel(targetType);
                        if (element.Name != String.Empty)
                            typeModel.TypeDesc.IsMixed = true;
                        else if (xmlAnyElement.Namespace != null)
                            throw new InvalidOperationException(Res.GetString(Res.XmlAnyElementNamespace, accessorName, xmlAnyElement.Namespace));
                        element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, String.Empty);
                        element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                        element.IsNullable = false;
                        element.Form = form;
                        CheckForm(element.Form, ns != element.Namespace);
                        CheckNullable(element.IsNullable, targetTypeDesc);
                        element = ReconcileLocalAccessor(element, ns);
                        elements.Add(element.Name, element.Namespace, element);
                    }
                }
            }

            accessor.Elements = (ElementAccessor[])elements.ToArray(typeof(ElementAccessor));

            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;
                        int colon = xmlName.LastIndexOf(':');
                        string choiceNs = colon < 0 ? element.Namespace : xmlName.Substring(0, colon);
                        string choiceName = colon < 0 ? xmlName : xmlName.Substring(colon+1);
                        if (element.Name == choiceName && element.Namespace == choiceNs) {
                            accessor.ChoiceIdentifier.MemberIds[i] = choiceMapping.Constants[j].Name;
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        // Type {0} is missing value for '{1}'.
                        throw new InvalidOperationException(Res.GetString(Res.XmlChoiceMissingValue, accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName, element.Name));
                    }
                }
            }
            arrayNestingLevel = previousNestingLevel;
            savedArrayItemAttributes = previousArrayItemAttributes;
            savedArrayNamespace = previousArrayNamespace;
        }
Beispiel #20
0
        private void WriteMember(object memberValue, AttributeAccessor attribute, TypeDesc memberTypeDesc, object parent)
        {
            if (memberTypeDesc.IsAbstract)
            {
                return;
            }
            if (memberTypeDesc.IsArrayLike)
            {
                var      sb = new StringBuilder();
                TypeDesc arrayElementTypeDesc         = memberTypeDesc.ArrayElementTypeDesc;
                bool     canOptimizeWriteListSequence = CanOptimizeWriteListSequence(arrayElementTypeDesc);
                if (attribute.IsList)
                {
                    if (canOptimizeWriteListSequence)
                    {
                        Writer.WriteStartAttribute(null, attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty);
                    }
                }

                var a = memberValue as IEnumerable;

                // #10593: Add More Tests for Serialization Code
                Debug.Assert(a != null);

                var  e = a.GetEnumerator();
                bool shouldAppendWhitespace = false;
                if (e != null)
                {
                    while (e.MoveNext())
                    {
                        object ai = e.Current;

                        if (attribute.IsList)
                        {
                            string stringValue;
                            if (attribute.Mapping is EnumMapping)
                            {
                                stringValue = WriteEnumMethod((EnumMapping)attribute.Mapping, ai);
                            }
                            else
                            {
                                if (!WritePrimitiveValue(arrayElementTypeDesc, ai, true, out stringValue))
                                {
                                    // #10593: Add More Tests for Serialization Code
                                    Debug.Assert(ai is byte[]);
                                }
                            }

                            // check to see if we can write values of the attribute sequentially
                            if (canOptimizeWriteListSequence)
                            {
                                if (shouldAppendWhitespace)
                                {
                                    Writer.WriteString(" ");
                                }

                                if (ai is byte[])
                                {
                                    WriteValue((byte[])ai);
                                }
                                else
                                {
                                    WriteValue(stringValue);
                                }
                            }
                            else
                            {
                                if (shouldAppendWhitespace)
                                {
                                    sb.Append(" ");
                                }

                                sb.Append(stringValue);
                            }
                        }
                        else
                        {
                            WriteAttribute(ai, attribute, parent);
                        }

                        shouldAppendWhitespace = true;
                    }

                    if (attribute.IsList)
                    {
                        // check to see if we can write values of the attribute sequentially
                        if (canOptimizeWriteListSequence)
                        {
                            Writer.WriteEndAttribute();
                        }
                        else
                        {
                            if (sb.Length != 0)
                            {
                                string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
                                WriteAttribute(attribute.Name, ns, sb.ToString());
                            }
                        }
                    }
                }
            }
            else
            {
                WriteAttribute(memberValue, attribute, parent);
            }
        }
        void ExportAttributeAccessor(XmlSchemaComplexType type, AttributeAccessor accessor, bool valueTypeOptional, string ns) {
            if (accessor == null) return;
            XmlSchemaObjectCollection attributes;

            if (type.ContentModel != null) {
                if (type.ContentModel.Content is XmlSchemaComplexContentRestriction)
                    attributes = ((XmlSchemaComplexContentRestriction)type.ContentModel.Content).Attributes;
                else if (type.ContentModel.Content is XmlSchemaComplexContentExtension)
                    attributes = ((XmlSchemaComplexContentExtension)type.ContentModel.Content).Attributes;
                else if (type.ContentModel.Content is XmlSchemaSimpleContentExtension)
                    attributes = ((XmlSchemaSimpleContentExtension)type.ContentModel.Content).Attributes;
                else
                    throw new InvalidOperationException(Res.GetString(Res.XmlInvalidContent, type.ContentModel.Content.GetType().Name));
            }
            else {
                attributes = type.Attributes;
            }

            if (accessor.IsSpecialXmlNamespace) {

                // add <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
                AddSchemaImport(XmlReservedNs.NsXml, ns);

                // generate <xsd:attribute ref="xml:lang" use="optional" />
                XmlSchemaAttribute attribute = new XmlSchemaAttribute();
                attribute.Use = XmlSchemaUse.Optional;
                attribute.RefName = new XmlQualifiedName(accessor.Name, XmlReservedNs.NsXml);
                attributes.Add(attribute);
            }
            else if (accessor.Any) {
                if (type.ContentModel == null) {
                    type.AnyAttribute = new XmlSchemaAnyAttribute();
                }
                else {
                    XmlSchemaContent content = type.ContentModel.Content;
                    if (content is XmlSchemaComplexContentExtension) {
                        XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)content;
                        extension.AnyAttribute = new XmlSchemaAnyAttribute();
                    }
                    else if (content is XmlSchemaComplexContentRestriction) {
                        XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)content;
                        restriction.AnyAttribute = new XmlSchemaAnyAttribute();
                    }
                    else if (type.ContentModel.Content is XmlSchemaSimpleContentExtension) {
                        XmlSchemaSimpleContentExtension extension = (XmlSchemaSimpleContentExtension)content;
                        extension.AnyAttribute = new XmlSchemaAnyAttribute();
                    }
                }
            }
            else {
                XmlSchemaAttribute attribute = new XmlSchemaAttribute();
                attribute.Use = XmlSchemaUse.None;
                if (!accessor.HasDefault && !valueTypeOptional && accessor.Mapping.TypeDesc.IsValueType) {
                    attribute.Use = XmlSchemaUse.Required;
                }
                attribute.Name = accessor.Name;
                if (accessor.Namespace == null || accessor.Namespace == ns) {
                    // determine the form attribute value
                    XmlSchema schema = schemas[ns];
                    if (schema == null)
                        attribute.Form = accessor.Form == attributeFormDefault ? XmlSchemaForm.None : accessor.Form;
                    else {
                        attribute.Form = accessor.Form == schema.AttributeFormDefault ? XmlSchemaForm.None : accessor.Form;
                    }
                    attributes.Add(attribute);
                }
                else {
                    // we are going to add the attribute to the top-level items. "use" attribute should not be set
                    if (this.attributes[accessor] == null) {
                        attribute.Use = XmlSchemaUse.None;
                        attribute.Form = accessor.Form;
                        AddSchemaItem(attribute, accessor.Namespace, ns);
                        this.attributes.Add(accessor, accessor);
                    }
                    XmlSchemaAttribute refAttribute = new XmlSchemaAttribute();
                    refAttribute.Use = XmlSchemaUse.None;
                    refAttribute.RefName = new XmlQualifiedName(accessor.Name, accessor.Namespace);
                    attributes.Add(refAttribute);
                    AddSchemaImport(accessor.Namespace, ns);
                }
                if (accessor.Mapping is PrimitiveMapping) {
                    PrimitiveMapping pm = (PrimitiveMapping)accessor.Mapping;
                    if (pm.IsList) {
                        // create local simple type for the list-like attributes
                        XmlSchemaSimpleType dataType = new XmlSchemaSimpleType();
                        XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList();
                        if (pm.IsAnonymousType) {
                            list.ItemType = (XmlSchemaSimpleType)ExportAnonymousPrimitiveMapping(pm);
                        }
                        else {
                            list.ItemTypeName = ExportPrimitiveMapping(pm, accessor.Namespace == null ? ns : accessor.Namespace);
                        }
                        dataType.Content = list;
                        attribute.SchemaType = dataType;
                    }
                    else {
                        if (pm.IsAnonymousType) {
                            attribute.SchemaType = (XmlSchemaSimpleType)ExportAnonymousPrimitiveMapping(pm);
                        }
                        else {
                            attribute.SchemaTypeName = ExportPrimitiveMapping(pm, accessor.Namespace == null ? ns : accessor.Namespace);
                        }
                    }
                }
                else if (!(accessor.Mapping is SpecialMapping))
                    throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));

                if (accessor.HasDefault) {
                    attribute.DefaultValue = ExportDefaultValue(accessor.Mapping, accessor.Default);
                }
            }
        }
 private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, string ns, Type choiceIdentifierType, bool rpc, bool openModel, RecursionLimiter limiter)
 {
     XmlSchemaForm qualified = XmlSchemaForm.Qualified;
     int arrayNestingLevel = this.arrayNestingLevel;
     int order = -1;
     XmlArrayItemAttributes savedArrayItemAttributes = this.savedArrayItemAttributes;
     string savedArrayNamespace = this.savedArrayNamespace;
     this.arrayNestingLevel = 0;
     this.savedArrayItemAttributes = null;
     this.savedArrayNamespace = null;
     Type fieldType = model.FieldType;
     string name = model.Name;
     ArrayList list = new ArrayList();
     System.Xml.Serialization.NameTable scope = new System.Xml.Serialization.NameTable();
     accessor.TypeDesc = this.typeScope.GetTypeDesc(fieldType);
     XmlAttributeFlags xmlFlags = a.XmlFlags;
     accessor.Ignore = a.XmlIgnore;
     if (rpc)
     {
         this.CheckTopLevelAttributes(a, name);
     }
     else
     {
         this.CheckAmbiguousChoice(a, fieldType, name);
     }
     XmlAttributeFlags flags2 = XmlAttributeFlags.ChoiceIdentifier | XmlAttributeFlags.AnyElements | XmlAttributeFlags.Elements | XmlAttributeFlags.Text;
     XmlAttributeFlags flags3 = XmlAttributeFlags.AnyAttribute | XmlAttributeFlags.Attribute;
     XmlAttributeFlags flags4 = XmlAttributeFlags.ArrayItems | XmlAttributeFlags.Array;
     if (((xmlFlags & flags4) != ((XmlAttributeFlags) 0)) && (fieldType == typeof(byte[])))
     {
         accessor.TypeDesc = this.typeScope.GetArrayTypeDesc(fieldType);
     }
     if (a.XmlChoiceIdentifier != null)
     {
         accessor.ChoiceIdentifier = new ChoiceIdentifierAccessor();
         accessor.ChoiceIdentifier.MemberName = a.XmlChoiceIdentifier.MemberName;
         accessor.ChoiceIdentifier.Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(choiceIdentifierType), ns, ImportContext.Element, string.Empty, null, limiter);
         this.CheckChoiceIdentifierMapping((EnumMapping) accessor.ChoiceIdentifier.Mapping);
     }
     if (accessor.TypeDesc.IsArrayLike)
     {
         Type arrayElementType = TypeScope.GetArrayElementType(fieldType, model.FieldTypeDesc.FullName + "." + model.Name);
         if ((xmlFlags & flags3) != ((XmlAttributeFlags) 0))
         {
             if ((xmlFlags & flags3) != xmlFlags)
             {
                 throw new InvalidOperationException(Res.GetString("XmlIllegalAttributesArrayAttribute"));
             }
             if (((a.XmlAttribute != null) && !accessor.TypeDesc.ArrayElementTypeDesc.IsPrimitive) && !accessor.TypeDesc.ArrayElementTypeDesc.IsEnum)
             {
                 if (accessor.TypeDesc.ArrayElementTypeDesc.Kind == TypeKind.Serializable)
                 {
                     throw new InvalidOperationException(Res.GetString("XmlIllegalAttrOrTextInterface", new object[] { name, accessor.TypeDesc.ArrayElementTypeDesc.FullName, typeof(IXmlSerializable).Name }));
                 }
                 throw new InvalidOperationException(Res.GetString("XmlIllegalAttrOrText", new object[] { name, accessor.TypeDesc.ArrayElementTypeDesc.FullName }));
             }
             bool repeats = (a.XmlAttribute != null) && (accessor.TypeDesc.ArrayElementTypeDesc.IsPrimitive || accessor.TypeDesc.ArrayElementTypeDesc.IsEnum);
             if (a.XmlAnyAttribute != null)
             {
                 a.XmlAttribute = new XmlAttributeAttribute();
             }
             AttributeAccessor accessor2 = new AttributeAccessor();
             Type type = (a.XmlAttribute.Type == null) ? arrayElementType : a.XmlAttribute.Type;
             this.typeScope.GetTypeDesc(type);
             accessor2.Name = Accessor.EscapeQName((a.XmlAttribute.AttributeName.Length == 0) ? name : a.XmlAttribute.AttributeName);
             accessor2.Namespace = (a.XmlAttribute.Namespace == null) ? ns : a.XmlAttribute.Namespace;
             accessor2.Form = a.XmlAttribute.Form;
             if ((accessor2.Form == XmlSchemaForm.None) && (ns != accessor2.Namespace))
             {
                 accessor2.Form = XmlSchemaForm.Qualified;
             }
             accessor2.CheckSpecial();
             CheckForm(accessor2.Form, ns != accessor2.Namespace);
             accessor2.Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(type), ns, ImportContext.Attribute, a.XmlAttribute.DataType, null, repeats, false, limiter);
             accessor2.IsList = repeats;
             accessor2.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
             accessor2.Any = a.XmlAnyAttribute != null;
             if ((accessor2.Form == XmlSchemaForm.Qualified) && (accessor2.Namespace != ns))
             {
                 if (this.xsdAttributes == null)
                 {
                     this.xsdAttributes = new System.Xml.Serialization.NameTable();
                 }
                 accessor2 = (AttributeAccessor) this.ReconcileAccessor(accessor2, this.xsdAttributes);
             }
             accessor.Attribute = accessor2;
         }
         else if ((xmlFlags & flags2) != ((XmlAttributeFlags) 0))
         {
             if ((xmlFlags & flags2) != xmlFlags)
             {
                 throw new InvalidOperationException(Res.GetString("XmlIllegalElementsArrayAttribute"));
             }
             if (a.XmlText != null)
             {
                 TextAccessor accessor3 = new TextAccessor();
                 Type type4 = (a.XmlText.Type == null) ? arrayElementType : a.XmlText.Type;
                 TypeDesc typeDesc = this.typeScope.GetTypeDesc(type4);
                 accessor3.Name = name;
                 accessor3.Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(type4), ns, ImportContext.Text, a.XmlText.DataType, null, true, false, limiter);
                 if (!(accessor3.Mapping is SpecialMapping) && (typeDesc != this.typeScope.GetTypeDesc(typeof(string))))
                 {
                     throw new InvalidOperationException(Res.GetString("XmlIllegalArrayTextAttribute", new object[] { name }));
                 }
                 accessor.Text = accessor3;
             }
             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++)
             {
                 ElementAccessor accessor4;
                 XmlElementAttribute attribute = a.XmlElements[i];
                 Type type5 = (attribute.Type == null) ? arrayElementType : attribute.Type;
                 TypeDesc desc2 = this.typeScope.GetTypeDesc(type5);
                 TypeModel typeModel = this.modelScope.GetTypeModel(type5);
                 accessor4 = new ElementAccessor {
                     Namespace = rpc ? null : ((attribute.Namespace == null) ? ns : attribute.Namespace),
                     Mapping = this.ImportTypeMapping(typeModel, rpc ? ns : accessor4.Namespace, ImportContext.Element, attribute.DataType, null, limiter)
                 };
                 if (a.XmlElements.Count == 1)
                 {
                     accessor4.Name = XmlConvert.EncodeLocalName((attribute.ElementName.Length == 0) ? name : attribute.ElementName);
                 }
                 else
                 {
                     accessor4.Name = (attribute.ElementName.Length == 0) ? accessor4.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(attribute.ElementName);
                 }
                 accessor4.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                 if ((attribute.IsNullableSpecified && !attribute.IsNullable) && typeModel.TypeDesc.IsOptionalValue)
                 {
                     throw new InvalidOperationException(Res.GetString("XmlInvalidNotNullable", new object[] { typeModel.TypeDesc.BaseTypeDesc.FullName, "XmlElement" }));
                 }
                 accessor4.IsNullable = attribute.IsNullableSpecified ? attribute.IsNullable : typeModel.TypeDesc.IsOptionalValue;
                 accessor4.Form = rpc ? XmlSchemaForm.Unqualified : ((attribute.Form == XmlSchemaForm.None) ? qualified : attribute.Form);
                 CheckNullable(accessor4.IsNullable, desc2, accessor4.Mapping);
                 if (!rpc)
                 {
                     CheckForm(accessor4.Form, ns != accessor4.Namespace);
                     accessor4 = this.ReconcileLocalAccessor(accessor4, ns);
                 }
                 if (attribute.Order != -1)
                 {
                     if ((attribute.Order != order) && (order != -1))
                     {
                         throw new InvalidOperationException(Res.GetString("XmlSequenceMatch", new object[] { "Order" }));
                     }
                     order = attribute.Order;
                 }
                 AddUniqueAccessor(scope, accessor4);
                 list.Add(accessor4);
             }
             System.Xml.Serialization.NameTable table2 = new System.Xml.Serialization.NameTable();
             for (int j = 0; j < a.XmlAnyElements.Count; j++)
             {
                 XmlAnyElementAttribute attribute2 = a.XmlAnyElements[j];
                 Type c = typeof(IXmlSerializable).IsAssignableFrom(arrayElementType) ? arrayElementType : (typeof(XmlNode).IsAssignableFrom(arrayElementType) ? arrayElementType : typeof(XmlElement));
                 if (!arrayElementType.IsAssignableFrom(c))
                 {
                     throw new InvalidOperationException(Res.GetString("XmlIllegalAnyElement", new object[] { arrayElementType.FullName }));
                 }
                 string str3 = (attribute2.Name.Length == 0) ? attribute2.Name : XmlConvert.EncodeLocalName(attribute2.Name);
                 string str4 = attribute2.NamespaceSpecified ? attribute2.Namespace : null;
                 if (table2[str3, str4] == null)
                 {
                     table2[str3, str4] = attribute2;
                     if (scope[str3, (str4 == null) ? ns : str4] != null)
                     {
                         throw new InvalidOperationException(Res.GetString("XmlAnyElementDuplicate", new object[] { name, attribute2.Name, (attribute2.Namespace == null) ? "null" : attribute2.Namespace }));
                     }
                     ElementAccessor accessor5 = new ElementAccessor {
                         Name = str3,
                         Namespace = (str4 == null) ? ns : str4,
                         Any = true,
                         AnyNamespaces = str4
                     };
                     TypeDesc desc3 = this.typeScope.GetTypeDesc(c);
                     TypeModel model3 = this.modelScope.GetTypeModel(c);
                     if (accessor5.Name.Length > 0)
                     {
                         model3.TypeDesc.IsMixed = true;
                     }
                     accessor5.Mapping = this.ImportTypeMapping(model3, accessor5.Namespace, ImportContext.Element, string.Empty, null, limiter);
                     accessor5.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                     accessor5.IsNullable = false;
                     accessor5.Form = qualified;
                     CheckNullable(accessor5.IsNullable, desc3, accessor5.Mapping);
                     if (!rpc)
                     {
                         CheckForm(accessor5.Form, ns != accessor5.Namespace);
                         accessor5 = this.ReconcileLocalAccessor(accessor5, ns);
                     }
                     scope.Add(accessor5.Name, accessor5.Namespace, accessor5);
                     list.Add(accessor5);
                     if (attribute2.Order != -1)
                     {
                         if ((attribute2.Order != order) && (order != -1))
                         {
                             throw new InvalidOperationException(Res.GetString("XmlSequenceMatch", new object[] { "Order" }));
                         }
                         order = attribute2.Order;
                     }
                 }
             }
         }
         else
         {
             if (((xmlFlags & flags4) != ((XmlAttributeFlags) 0)) && ((xmlFlags & flags4) != xmlFlags))
             {
                 throw new InvalidOperationException(Res.GetString("XmlIllegalArrayArrayAttribute"));
             }
             TypeDesc desc4 = this.typeScope.GetTypeDesc(arrayElementType);
             if (a.XmlArray == null)
             {
                 a.XmlArray = CreateArrayAttribute(accessor.TypeDesc);
             }
             if (CountAtLevel(a.XmlArrayItems, this.arrayNestingLevel) == 0)
             {
                 a.XmlArrayItems.Add(CreateArrayItemAttribute(desc4, this.arrayNestingLevel));
             }
             ElementAccessor accessor6 = new ElementAccessor {
                 Name = XmlConvert.EncodeLocalName((a.XmlArray.ElementName.Length == 0) ? name : a.XmlArray.ElementName),
                 Namespace = rpc ? null : ((a.XmlArray.Namespace == null) ? ns : a.XmlArray.Namespace)
             };
             this.savedArrayItemAttributes = a.XmlArrayItems;
             this.savedArrayNamespace = accessor6.Namespace;
             ArrayMapping mapping = this.ImportArrayLikeMapping(this.modelScope.GetArrayModel(fieldType), ns, limiter);
             accessor6.Mapping = mapping;
             accessor6.IsNullable = a.XmlArray.IsNullable;
             accessor6.Form = rpc ? XmlSchemaForm.Unqualified : ((a.XmlArray.Form == XmlSchemaForm.None) ? qualified : a.XmlArray.Form);
             order = a.XmlArray.Order;
             CheckNullable(accessor6.IsNullable, accessor.TypeDesc, accessor6.Mapping);
             if (!rpc)
             {
                 CheckForm(accessor6.Form, ns != accessor6.Namespace);
                 accessor6 = this.ReconcileLocalAccessor(accessor6, ns);
             }
             this.savedArrayItemAttributes = null;
             this.savedArrayNamespace = null;
             AddUniqueAccessor(scope, accessor6);
             list.Add(accessor6);
         }
     }
     else if (!accessor.TypeDesc.IsVoid)
     {
         XmlAttributeFlags flags5 = XmlAttributeFlags.XmlnsDeclarations | XmlAttributeFlags.ChoiceIdentifier | XmlAttributeFlags.AnyElements | XmlAttributeFlags.Attribute | XmlAttributeFlags.Elements | XmlAttributeFlags.Text;
         if ((xmlFlags & flags5) != xmlFlags)
         {
             throw new InvalidOperationException(Res.GetString("XmlIllegalAttribute"));
         }
         if (accessor.TypeDesc.IsPrimitive || accessor.TypeDesc.IsEnum)
         {
             if (a.XmlAnyElements.Count > 0)
             {
                 throw new InvalidOperationException(Res.GetString("XmlIllegalAnyElement", new object[] { accessor.TypeDesc.FullName }));
             }
             if (a.XmlAttribute != null)
             {
                 if (a.XmlElements.Count > 0)
                 {
                     throw new InvalidOperationException(Res.GetString("XmlIllegalAttribute"));
                 }
                 if (a.XmlAttribute.Type != null)
                 {
                     throw new InvalidOperationException(Res.GetString("XmlIllegalType", new object[] { "XmlAttribute" }));
                 }
                 AttributeAccessor accessor7 = new AttributeAccessor {
                     Name = Accessor.EscapeQName((a.XmlAttribute.AttributeName.Length == 0) ? name : a.XmlAttribute.AttributeName),
                     Namespace = (a.XmlAttribute.Namespace == null) ? ns : a.XmlAttribute.Namespace,
                     Form = a.XmlAttribute.Form
                 };
                 if ((accessor7.Form == XmlSchemaForm.None) && (ns != accessor7.Namespace))
                 {
                     accessor7.Form = XmlSchemaForm.Qualified;
                 }
                 accessor7.CheckSpecial();
                 CheckForm(accessor7.Form, ns != accessor7.Namespace);
                 accessor7.Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(fieldType), ns, ImportContext.Attribute, a.XmlAttribute.DataType, null, limiter);
                 accessor7.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                 accessor7.Any = a.XmlAnyAttribute != null;
                 if ((accessor7.Form == XmlSchemaForm.Qualified) && (accessor7.Namespace != ns))
                 {
                     if (this.xsdAttributes == null)
                     {
                         this.xsdAttributes = new System.Xml.Serialization.NameTable();
                     }
                     accessor7 = (AttributeAccessor) this.ReconcileAccessor(accessor7, this.xsdAttributes);
                 }
                 accessor.Attribute = accessor7;
             }
             else
             {
                 if (a.XmlText != null)
                 {
                     if ((a.XmlText.Type != null) && (a.XmlText.Type != fieldType))
                     {
                         throw new InvalidOperationException(Res.GetString("XmlIllegalType", new object[] { "XmlText" }));
                     }
                     TextAccessor accessor8 = new TextAccessor {
                         Name = name,
                         Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(fieldType), ns, ImportContext.Text, a.XmlText.DataType, null, limiter)
                     };
                     accessor.Text = accessor8;
                 }
                 else if (a.XmlElements.Count == 0)
                 {
                     a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc));
                 }
                 for (int k = 0; k < a.XmlElements.Count; k++)
                 {
                     XmlElementAttribute attribute3 = a.XmlElements[k];
                     if ((attribute3.Type != null) && (this.typeScope.GetTypeDesc(attribute3.Type) != accessor.TypeDesc))
                     {
                         throw new InvalidOperationException(Res.GetString("XmlIllegalType", new object[] { "XmlElement" }));
                     }
                     ElementAccessor accessor9 = new ElementAccessor {
                         Name = XmlConvert.EncodeLocalName((attribute3.ElementName.Length == 0) ? name : attribute3.ElementName),
                         Namespace = rpc ? null : ((attribute3.Namespace == null) ? ns : attribute3.Namespace)
                     };
                     TypeModel model4 = this.modelScope.GetTypeModel(fieldType);
                     accessor9.Mapping = this.ImportTypeMapping(model4, rpc ? ns : accessor9.Namespace, ImportContext.Element, attribute3.DataType, null, limiter);
                     if (accessor9.Mapping.TypeDesc.Kind == TypeKind.Node)
                     {
                         accessor9.Any = true;
                     }
                     accessor9.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                     if ((attribute3.IsNullableSpecified && !attribute3.IsNullable) && model4.TypeDesc.IsOptionalValue)
                     {
                         throw new InvalidOperationException(Res.GetString("XmlInvalidNotNullable", new object[] { model4.TypeDesc.BaseTypeDesc.FullName, "XmlElement" }));
                     }
                     accessor9.IsNullable = attribute3.IsNullableSpecified ? attribute3.IsNullable : model4.TypeDesc.IsOptionalValue;
                     accessor9.Form = rpc ? XmlSchemaForm.Unqualified : ((attribute3.Form == XmlSchemaForm.None) ? qualified : attribute3.Form);
                     CheckNullable(accessor9.IsNullable, accessor.TypeDesc, accessor9.Mapping);
                     if (!rpc)
                     {
                         CheckForm(accessor9.Form, ns != accessor9.Namespace);
                         accessor9 = this.ReconcileLocalAccessor(accessor9, ns);
                     }
                     if (attribute3.Order != -1)
                     {
                         if ((attribute3.Order != order) && (order != -1))
                         {
                             throw new InvalidOperationException(Res.GetString("XmlSequenceMatch", new object[] { "Order" }));
                         }
                         order = attribute3.Order;
                     }
                     AddUniqueAccessor(scope, accessor9);
                     list.Add(accessor9);
                 }
             }
         }
         else if (a.Xmlns)
         {
             if (xmlFlags != XmlAttributeFlags.XmlnsDeclarations)
             {
                 throw new InvalidOperationException(Res.GetString("XmlSoleXmlnsAttribute"));
             }
             if (fieldType != typeof(XmlSerializerNamespaces))
             {
                 throw new InvalidOperationException(Res.GetString("XmlXmlnsInvalidType", new object[] { name, fieldType.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(Res.GetString("XmlIllegalAttrOrTextInterface", new object[] { name, accessor.TypeDesc.FullName, typeof(IXmlSerializable).Name }));
                 }
                 throw new InvalidOperationException(Res.GetString("XmlIllegalAttrOrText", new object[] { name, accessor.TypeDesc }));
             }
             if ((a.XmlElements.Count == 0) && (a.XmlAnyElements.Count == 0))
             {
                 a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc));
             }
             for (int m = 0; m < a.XmlElements.Count; m++)
             {
                 XmlElementAttribute attribute4 = a.XmlElements[m];
                 Type type7 = (attribute4.Type == null) ? fieldType : attribute4.Type;
                 TypeDesc desc5 = this.typeScope.GetTypeDesc(type7);
                 ElementAccessor accessor10 = new ElementAccessor();
                 TypeModel model5 = this.modelScope.GetTypeModel(type7);
                 accessor10.Namespace = rpc ? null : ((attribute4.Namespace == null) ? ns : attribute4.Namespace);
                 accessor10.Mapping = this.ImportTypeMapping(model5, rpc ? ns : accessor10.Namespace, ImportContext.Element, attribute4.DataType, null, false, openModel, limiter);
                 if (a.XmlElements.Count == 1)
                 {
                     accessor10.Name = XmlConvert.EncodeLocalName((attribute4.ElementName.Length == 0) ? name : attribute4.ElementName);
                 }
                 else
                 {
                     accessor10.Name = (attribute4.ElementName.Length == 0) ? accessor10.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(attribute4.ElementName);
                 }
                 accessor10.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                 if ((attribute4.IsNullableSpecified && !attribute4.IsNullable) && model5.TypeDesc.IsOptionalValue)
                 {
                     throw new InvalidOperationException(Res.GetString("XmlInvalidNotNullable", new object[] { model5.TypeDesc.BaseTypeDesc.FullName, "XmlElement" }));
                 }
                 accessor10.IsNullable = attribute4.IsNullableSpecified ? attribute4.IsNullable : model5.TypeDesc.IsOptionalValue;
                 accessor10.Form = rpc ? XmlSchemaForm.Unqualified : ((attribute4.Form == XmlSchemaForm.None) ? qualified : attribute4.Form);
                 CheckNullable(accessor10.IsNullable, desc5, accessor10.Mapping);
                 if (!rpc)
                 {
                     CheckForm(accessor10.Form, ns != accessor10.Namespace);
                     accessor10 = this.ReconcileLocalAccessor(accessor10, ns);
                 }
                 if (attribute4.Order != -1)
                 {
                     if ((attribute4.Order != order) && (order != -1))
                     {
                         throw new InvalidOperationException(Res.GetString("XmlSequenceMatch", new object[] { "Order" }));
                     }
                     order = attribute4.Order;
                 }
                 AddUniqueAccessor(scope, accessor10);
                 list.Add(accessor10);
             }
             System.Xml.Serialization.NameTable table3 = new System.Xml.Serialization.NameTable();
             for (int n = 0; n < a.XmlAnyElements.Count; n++)
             {
                 XmlAnyElementAttribute attribute5 = a.XmlAnyElements[n];
                 Type type8 = typeof(IXmlSerializable).IsAssignableFrom(fieldType) ? fieldType : (typeof(XmlNode).IsAssignableFrom(fieldType) ? fieldType : typeof(XmlElement));
                 if (!fieldType.IsAssignableFrom(type8))
                 {
                     throw new InvalidOperationException(Res.GetString("XmlIllegalAnyElement", new object[] { fieldType.FullName }));
                 }
                 string str5 = (attribute5.Name.Length == 0) ? attribute5.Name : XmlConvert.EncodeLocalName(attribute5.Name);
                 string str6 = attribute5.NamespaceSpecified ? attribute5.Namespace : null;
                 if (table3[str5, str6] == null)
                 {
                     table3[str5, str6] = attribute5;
                     if (scope[str5, (str6 == null) ? ns : str6] != null)
                     {
                         throw new InvalidOperationException(Res.GetString("XmlAnyElementDuplicate", new object[] { name, attribute5.Name, (attribute5.Namespace == null) ? "null" : attribute5.Namespace }));
                     }
                     ElementAccessor accessor11 = new ElementAccessor {
                         Name = str5,
                         Namespace = (str6 == null) ? ns : str6,
                         Any = true,
                         AnyNamespaces = str6
                     };
                     TypeDesc desc6 = this.typeScope.GetTypeDesc(type8);
                     TypeModel model6 = this.modelScope.GetTypeModel(type8);
                     if (accessor11.Name.Length > 0)
                     {
                         model6.TypeDesc.IsMixed = true;
                     }
                     accessor11.Mapping = this.ImportTypeMapping(model6, accessor11.Namespace, ImportContext.Element, string.Empty, null, false, openModel, limiter);
                     accessor11.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a);
                     accessor11.IsNullable = false;
                     accessor11.Form = qualified;
                     CheckNullable(accessor11.IsNullable, desc6, accessor11.Mapping);
                     if (!rpc)
                     {
                         CheckForm(accessor11.Form, ns != accessor11.Namespace);
                         accessor11 = this.ReconcileLocalAccessor(accessor11, ns);
                     }
                     if (attribute5.Order != -1)
                     {
                         if ((attribute5.Order != order) && (order != -1))
                         {
                             throw new InvalidOperationException(Res.GetString("XmlSequenceMatch", new object[] { "Order" }));
                         }
                         order = attribute5.Order;
                     }
                     scope.Add(accessor11.Name, accessor11.Namespace, accessor11);
                     list.Add(accessor11);
                 }
             }
         }
     }
     accessor.Elements = (ElementAccessor[]) list.ToArray(typeof(ElementAccessor));
     accessor.SequenceId = order;
     if (rpc)
     {
         if ((accessor.TypeDesc.IsArrayLike && (accessor.Elements.Length > 0)) && !(accessor.Elements[0].Mapping is ArrayMapping))
         {
             throw new InvalidOperationException(Res.GetString("XmlRpcLitArrayElement", new object[] { accessor.Elements[0].Name }));
         }
         if (accessor.Xmlns != null)
         {
             throw new InvalidOperationException(Res.GetString("XmlRpcLitXmlns", new object[] { accessor.Name }));
         }
     }
     if (accessor.ChoiceIdentifier != null)
     {
         accessor.ChoiceIdentifier.MemberIds = new string[accessor.Elements.Length];
         for (int num8 = 0; num8 < accessor.Elements.Length; num8++)
         {
             bool flag2 = false;
             ElementAccessor accessor12 = accessor.Elements[num8];
             EnumMapping mapping2 = (EnumMapping) accessor.ChoiceIdentifier.Mapping;
             for (int num9 = 0; num9 < mapping2.Constants.Length; num9++)
             {
                 string xmlName = mapping2.Constants[num9].XmlName;
                 if (accessor12.Any && (accessor12.Name.Length == 0))
                 {
                     string str8 = (accessor12.AnyNamespaces == null) ? "##any" : accessor12.AnyNamespaces;
                     if (!(xmlName.Substring(0, xmlName.Length - 1) == str8))
                     {
                         continue;
                     }
                     accessor.ChoiceIdentifier.MemberIds[num8] = mapping2.Constants[num9].Name;
                     flag2 = true;
                     break;
                 }
                 int length = xmlName.LastIndexOf(':');
                 string str9 = (length < 0) ? mapping2.Namespace : xmlName.Substring(0, length);
                 string str10 = (length < 0) ? xmlName : xmlName.Substring(length + 1);
                 if ((accessor12.Name == str10) && (((accessor12.Form == XmlSchemaForm.Unqualified) && string.IsNullOrEmpty(str9)) || (accessor12.Namespace == str9)))
                 {
                     accessor.ChoiceIdentifier.MemberIds[num8] = mapping2.Constants[num9].Name;
                     flag2 = true;
                     break;
                 }
             }
             if (!flag2)
             {
                 if (accessor12.Any && (accessor12.Name.Length == 0))
                 {
                     throw new InvalidOperationException(Res.GetString("XmlChoiceMissingAnyValue", new object[] { accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName }));
                 }
                 string str11 = ((accessor12.Namespace != null) && (accessor12.Namespace.Length > 0)) ? (accessor12.Namespace + ":" + accessor12.Name) : accessor12.Name;
                 throw new InvalidOperationException(Res.GetString("XmlChoiceMissingValue", new object[] { accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName, str11, accessor12.Name, accessor12.Namespace }));
             }
         }
     }
     this.arrayNestingLevel = arrayNestingLevel;
     this.savedArrayItemAttributes = savedArrayItemAttributes;
     this.savedArrayNamespace = savedArrayNamespace;
 }
        private void WriteMember(object memberValue, AttributeAccessor attribute, TypeDesc memberTypeDesc, object parent)
        {
            if (memberTypeDesc.IsAbstract) return;
            if (memberTypeDesc.IsArrayLike)
            {
                var sb = new StringBuilder();
                TypeDesc arrayElementTypeDesc = memberTypeDesc.ArrayElementTypeDesc;
                bool canOptimizeWriteListSequence = CanOptimizeWriteListSequence(arrayElementTypeDesc);
                if (attribute.IsList)
                {
                    if (canOptimizeWriteListSequence)
                    {
                        Writer.WriteStartAttribute(null, attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty);
                    }
                }

                var a = memberValue as IEnumerable;

                // #10593: Add More Tests for Serialization Code
                Debug.Assert(a != null);

                var e = a.GetEnumerator();
                bool shouldAppendWhitespace = false;
                if (e != null)
                {
                    while (e.MoveNext())
                    {
                        object ai = e.Current;

                        if (attribute.IsList)
                        {
                            string stringValue;
                            if (attribute.Mapping is EnumMapping)
                            {
                                stringValue = WriteEnumMethod((EnumMapping)attribute.Mapping, ai);
                            }
                            else
                            {
                                if (!WritePrimitiveValue(arrayElementTypeDesc, ai, true, out stringValue))
                                {
                                    // #10593: Add More Tests for Serialization Code
                                    Debug.Assert(ai is byte[]);
                                }
                            }

                            // check to see if we can write values of the attribute sequentially
                            if (canOptimizeWriteListSequence)
                            {
                                if (shouldAppendWhitespace)
                                {
                                    Writer.WriteString(" ");
                                }

                                if (ai is byte[])
                                {
                                    WriteValue((byte[])ai);
                                }
                                else
                                {
                                    WriteValue(stringValue);
                                }
                            }
                            else
                            {
                                if (shouldAppendWhitespace)
                                {
                                    sb.Append(" ");
                                }

                                sb.Append(stringValue);
                            }
                        }
                        else
                        {
                            WriteAttribute(ai, attribute, parent);
                        }

                        shouldAppendWhitespace = true;
                    }

                    if (attribute.IsList)
                    {
                        // check to see if we can write values of the attribute sequentially
                        if (canOptimizeWriteListSequence)
                        {
                            Writer.WriteEndAttribute();
                        }
                        else
                        {
                            if (sb.Length != 0)
                            {
                                string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
                                WriteAttribute(attribute.Name, ns, sb.ToString());
                            }
                        }
                    }
                }
            }
            else
            {
                WriteAttribute(memberValue, attribute, parent);
            }
        }
Beispiel #24
0
        private AttributeAccessor ImportAttribute(XmlSchemaAttribute attribute, string identifier, string ns, XmlSchemaAttribute defaultValueProvider)
        {
            if (attribute.Use == XmlSchemaUse.Prohibited) return null;
            if (!attribute.RefName.IsEmpty)
            {
                if (attribute.RefName.Namespace == XmlReservedNs.NsXml)
                    return ImportSpecialAttribute(attribute.RefName, identifier);
                else
                    return ImportAttribute(FindAttribute(attribute.RefName), identifier, attribute.RefName.Namespace, defaultValueProvider);
            }
            TypeMapping mapping;
            if (attribute.Name.Length == 0) throw new InvalidOperationException(SR.XmlAttributeHasNoName);
            if (identifier.Length == 0)
                identifier = CodeIdentifier.MakeValid(attribute.Name);
            else
                identifier += CodeIdentifier.MakePascal(attribute.Name);
            if (!attribute.SchemaTypeName.IsEmpty)
                mapping = (TypeMapping)ImportType(attribute.SchemaTypeName, typeof(TypeMapping), null, TypeFlags.CanBeAttributeValue, false);
            else if (attribute.SchemaType != null)
                mapping = ImportDataType((XmlSchemaSimpleType)attribute.SchemaType, ns, identifier, null, TypeFlags.CanBeAttributeValue, false);
            else
            {
                mapping = GetDefaultMapping(TypeFlags.CanBeAttributeValue);
            }

            // let the extensions to run
            if (mapping != null && !mapping.TypeDesc.IsMappedType)
            {
                RunSchemaExtensions(mapping, attribute.SchemaTypeName, attribute.SchemaType, attribute, TypeFlags.CanBeElementValue | TypeFlags.CanBeAttributeValue | TypeFlags.CanBeTextValue);
            }
            AttributeAccessor accessor = new AttributeAccessor();
            accessor.Name = attribute.Name;
            accessor.Namespace = ns;
            accessor.Form = AttributeForm(ns, attribute);
            accessor.CheckSpecial();
            accessor.Mapping = mapping;
            accessor.IsList = mapping.IsList;
            accessor.IsOptional = attribute.Use != XmlSchemaUse.Required;

            if (defaultValueProvider.DefaultValue != null)
            {
                accessor.Default = defaultValueProvider.DefaultValue;
            }
            else if (defaultValueProvider.FixedValue != null)
            {
                accessor.Default = defaultValueProvider.FixedValue;
                accessor.IsFixed = true;
            }
            else if (attribute != defaultValueProvider)
            {
                if (attribute.DefaultValue != null)
                {
                    accessor.Default = attribute.DefaultValue;
                }
                else if (attribute.FixedValue != null)
                {
                    accessor.Default = attribute.FixedValue;
                    accessor.IsFixed = true;
                }
            }
            return accessor;
        }
Beispiel #25
0
 protected AccessorMapping(AccessorMapping mapping)
     : base(mapping)
 {
     this.typeDesc = mapping.typeDesc;
     this.attribute = mapping.attribute;
     this.elements = mapping.elements;
     this.sortedElements = mapping.sortedElements;
     this.text = mapping.text;
     this.choiceIdentifier = mapping.choiceIdentifier;
     this.xmlns = mapping.xmlns;
     this.ignore = mapping.ignore;
 }
        private void WriteMember(SourceInfo source, AttributeAccessor attribute, TypeDesc memberTypeDesc, string parent)
        {
            if (memberTypeDesc.IsAbstract) return;
            if (memberTypeDesc.IsArrayLike)
            {
                string aVar = "a" + memberTypeDesc.Name;
                string aiVar = "ai" + memberTypeDesc.Name;
                string iVar = "i";
                string fullTypeName = memberTypeDesc.CSharpName;
                WriteArrayLocalDecl(fullTypeName, aVar, source, memberTypeDesc);
                if (memberTypeDesc.IsNullable)
                {
                    ilg.Ldloc(memberTypeDesc.Type, aVar);
                    ilg.Load(null);
                    ilg.If(Cmp.NotEqualTo);
                }
                if (attribute.IsList)
                {
                    if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc))
                    {
                        string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
                        MethodInfo XmlSerializationWriter_get_Writer = typeof(XmlSerializationWriter).GetMethod(
                            "get_Writer",
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        MethodInfo XmlWriter_WriteStartAttribute = typeof(XmlWriter).GetMethod(
                            "WriteStartAttribute",
                            CodeGenerator.InstanceBindingFlags,
                            new Type[] { typeof(String), typeof(String), typeof(String) }
                            );
                        ilg.Ldarg(0);
                        ilg.Call(XmlSerializationWriter_get_Writer);
                        ilg.Load(null);
                        ilg.Ldstr(GetCSharpString(attribute.Name));
                        ilg.Ldstr(GetCSharpString(ns));
                        ilg.Call(XmlWriter_WriteStartAttribute);
                    }
                    else
                    {
                        LocalBuilder sbLoc = ilg.DeclareOrGetLocal(typeof(StringBuilder), "sb");
                        ConstructorInfo StringBuilder_ctor = typeof(StringBuilder).GetConstructor(
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        ilg.New(StringBuilder_ctor);
                        ilg.Stloc(sbLoc);
                    }
                }
                TypeDesc arrayElementTypeDesc = memberTypeDesc.ArrayElementTypeDesc;

                if (memberTypeDesc.IsEnumerable)
                {
                    throw Globals.NotSupported("CDF15337, DDB176069: Also fail in whidbey IEnumerable member with XmlAttributeAttribute");
                }
                else
                {
                    LocalBuilder localI = ilg.DeclareOrGetLocal(typeof(Int32), iVar);
                    ilg.For(localI, 0, ilg.GetLocal(aVar));
                    WriteLocalDecl(aiVar, RaCodeGen.GetStringForArrayMember(aVar, iVar, memberTypeDesc), arrayElementTypeDesc.Type);
                }
                if (attribute.IsList)
                {
                    string methodName;
                    Type methodType;
                    Type argType = typeof(string);
                    // check to see if we can write values of the attribute sequentially
                    if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc))
                    {
                        ilg.Ldloc(iVar);
                        ilg.Ldc(0);
                        ilg.If(Cmp.NotEqualTo);
                        MethodInfo XmlSerializationWriter_get_Writer = typeof(XmlSerializationWriter).GetMethod(
                            "get_Writer",
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        MethodInfo XmlWriter_WriteString = typeof(XmlWriter).GetMethod(
                            "WriteString",
                            CodeGenerator.InstanceBindingFlags,
                            new Type[] { typeof(String) }
                            );
                        ilg.Ldarg(0);
                        ilg.Call(XmlSerializationWriter_get_Writer);
                        ilg.Ldstr(" ");
                        ilg.Call(XmlWriter_WriteString);
                        ilg.EndIf();
                        ilg.Ldarg(0);
                        methodName = "WriteValue";
                        methodType = typeof(XmlSerializationWriter);
                    }
                    else
                    {
                        MethodInfo StringBuilder_Append = typeof(StringBuilder).GetMethod(
                            "Append",
                            CodeGenerator.InstanceBindingFlags,
                            new Type[] { typeof(string) }
                            );
                        ilg.Ldloc(iVar);
                        ilg.Ldc(0);
                        ilg.If(Cmp.NotEqualTo);
                        ilg.Ldloc("sb");
                        ilg.Ldstr(" ");
                        ilg.Call(StringBuilder_Append);
                        ilg.Pop();
                        ilg.EndIf();
                        ilg.Ldloc("sb");
                        methodName = "Append";
                        methodType = typeof(StringBuilder);
                    }
                    if (attribute.Mapping is EnumMapping)
                        WriteEnumValue((EnumMapping)attribute.Mapping, new SourceInfo(aiVar, aiVar, null, arrayElementTypeDesc.Type, ilg), out argType);
                    else
                        WritePrimitiveValue(arrayElementTypeDesc, new SourceInfo(aiVar, aiVar, null, arrayElementTypeDesc.Type, ilg), out argType);
                    MethodInfo method = methodType.GetMethod(
                        methodName,
                        CodeGenerator.InstanceBindingFlags,
                        new Type[] { argType }
                        );
                    ilg.Call(method);
                    if (method.ReturnType != typeof(void))
                        ilg.Pop();
                }
                else
                {
                    WriteAttribute(new SourceInfo(aiVar, aiVar, null, null, ilg), attribute, parent);
                }
                if (memberTypeDesc.IsEnumerable)
                    throw Globals.NotSupported("CDF15337, DDB176069: Also fail in whidbey IEnumerable member with XmlAttributeAttribute");
                else
                    ilg.EndFor();
                if (attribute.IsList)
                {
                    // check to see if we can write values of the attribute sequentially
                    if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc))
                    {
                        MethodInfo XmlSerializationWriter_get_Writer = typeof(XmlSerializationWriter).GetMethod(
                            "get_Writer",
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        MethodInfo XmlWriter_WriteEndAttribute = typeof(XmlWriter).GetMethod(
                            "WriteEndAttribute",
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        ilg.Ldarg(0);
                        ilg.Call(XmlSerializationWriter_get_Writer);
                        ilg.Call(XmlWriter_WriteEndAttribute);
                    }
                    else
                    {
                        MethodInfo StringBuilder_get_Length = typeof(StringBuilder).GetMethod(
                            "get_Length",
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        ilg.Ldloc("sb");
                        ilg.Call(StringBuilder_get_Length);
                        ilg.Ldc(0);
                        ilg.If(Cmp.NotEqualTo);

                        List<Type> argTypes = new List<Type>();
                        ilg.Ldarg(0);
                        ilg.Ldstr(GetCSharpString(attribute.Name));
                        argTypes.Add(typeof(string));
                        string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
                        if (ns != null)
                        {
                            ilg.Ldstr(GetCSharpString(ns));
                            argTypes.Add(typeof(string));
                        }
                        MethodInfo Object_ToString = typeof(Object).GetMethod(
                            "ToString",
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        ilg.Ldloc("sb");
                        ilg.Call(Object_ToString);
                        argTypes.Add(typeof(string));
                        MethodInfo XmlSerializationWriter_WriteAttribute = typeof(XmlSerializationWriter).GetMethod(
                             "WriteAttribute",
                             CodeGenerator.InstanceBindingFlags,
                             argTypes.ToArray()
                             );
                        ilg.Call(XmlSerializationWriter_WriteAttribute);
                        ilg.EndIf();
                    }
                }

                if (memberTypeDesc.IsNullable)
                {
                    ilg.EndIf();
                }
            }
            else
            {
                WriteAttribute(source, attribute, parent);
            }
        }
 private void ExportTypeMembers(XmlSchemaComplexType type, MemberMapping[] members, string name, string ns, bool hasSimpleContent, bool openModel)
 {
     XmlSchemaGroupBase group = new XmlSchemaSequence();
     TypeMapping mapping = null;
     for (int i = 0; i < members.Length; i++)
     {
         MemberMapping mapping2 = members[i];
         if (!mapping2.Ignore)
         {
             if (mapping2.Text != null)
             {
                 if (mapping != null)
                 {
                     throw new InvalidOperationException(Res.GetString("XmlIllegalMultipleText", new object[] { name }));
                 }
                 mapping = mapping2.Text.Mapping;
             }
             if (mapping2.Elements.Length > 0)
             {
                 bool repeats = mapping2.TypeDesc.IsArrayLike && ((mapping2.Elements.Length != 1) || !(mapping2.Elements[0].Mapping is ArrayMapping));
                 bool valueTypeOptional = (mapping2.CheckSpecified != SpecifiedAccessor.None) || mapping2.CheckShouldPersist;
                 this.ExportElementAccessors(group, mapping2.Elements, repeats, valueTypeOptional, ns);
             }
         }
     }
     if (group.Items.Count > 0)
     {
         if (type.ContentModel != null)
         {
             if (type.ContentModel.Content is XmlSchemaComplexContentRestriction)
             {
                 ((XmlSchemaComplexContentRestriction) type.ContentModel.Content).Particle = group;
             }
             else
             {
                 if (!(type.ContentModel.Content is XmlSchemaComplexContentExtension))
                 {
                     throw new InvalidOperationException(Res.GetString("XmlInvalidContent", new object[] { type.ContentModel.Content.GetType().Name }));
                 }
                 ((XmlSchemaComplexContentExtension) type.ContentModel.Content).Particle = group;
             }
         }
         else
         {
             type.Particle = group;
         }
     }
     if (mapping != null)
     {
         if (hasSimpleContent)
         {
             if ((mapping is PrimitiveMapping) && (group.Items.Count == 0))
             {
                 PrimitiveMapping mapping3 = (PrimitiveMapping) mapping;
                 if (mapping3.IsList)
                 {
                     type.IsMixed = true;
                 }
                 else
                 {
                     if (mapping3.IsAnonymousType)
                     {
                         throw new InvalidOperationException(Res.GetString("XmlAnonymousBaseType", new object[] { mapping.TypeDesc.Name, mapping3.TypeDesc.Name, "AnonymousType", "false" }));
                     }
                     XmlSchemaSimpleContent content = new XmlSchemaSimpleContent();
                     XmlSchemaSimpleContentExtension extension = new XmlSchemaSimpleContentExtension();
                     content.Content = extension;
                     type.ContentModel = content;
                     extension.BaseTypeName = this.ExportPrimitiveMapping(mapping3, ns);
                 }
             }
         }
         else
         {
             type.IsMixed = true;
         }
     }
     bool flag3 = false;
     for (int j = 0; j < members.Length; j++)
     {
         if (members[j].Attribute != null)
         {
             this.ExportAttributeAccessor(type, members[j].Attribute, (members[j].CheckSpecified != SpecifiedAccessor.None) || members[j].CheckShouldPersist, ns);
             if (members[j].Attribute.Any)
             {
                 flag3 = true;
             }
         }
     }
     if (openModel && !flag3)
     {
         AttributeAccessor accessor = new AttributeAccessor {
             Any = true
         };
         this.ExportAttributeAccessor(type, accessor, false, ns);
     }
 }
 private void WriteAttribute(SourceInfo source, AttributeAccessor attribute, string parent)
 {
     if (attribute.Mapping is SpecialMapping)
     {
         SpecialMapping special = (SpecialMapping)attribute.Mapping;
         if (special.TypeDesc.Kind == TypeKind.Attribute || special.TypeDesc.CanBeAttributeValue)
         {
             System.Diagnostics.Debug.Assert(parent == "o" || parent == "p");
             MethodInfo XmlSerializationWriter_WriteXmlAttribute = typeof(XmlSerializationWriter).GetMethod(
                 "WriteXmlAttribute",
                 CodeGenerator.InstanceBindingFlags,
                 new Type[] { typeof(XmlNode), typeof(Object) }
                 );
             ilg.Ldarg(0);
             ilg.Ldloc(source.Source);
             ilg.Ldarg(parent);
             ilg.ConvertValue(ilg.GetArg(parent).ArgType, typeof(Object));
             ilg.Call(XmlSerializationWriter_WriteXmlAttribute);
         }
         else
             throw new InvalidOperationException(SR.XmlInternalError);
     }
     else
     {
         TypeDesc typeDesc = attribute.Mapping.TypeDesc;
         source = source.CastTo(typeDesc);
         WritePrimitive("WriteAttribute", attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "", attribute.Default, source, attribute.Mapping, false, false, false);
     }
 }
        void ImportAccessorMapping(MemberMapping accessor, FieldModel model, SoapAttributes a, string ns, XmlSchemaForm form) {
            Type accessorType = model.FieldType;
            string accessorName = model.Name;
            accessor.TypeDesc = typeScope.GetTypeDesc(accessorType);
            if (accessor.TypeDesc.IsVoid) {
                throw new InvalidOperationException(Res.GetString(Res.XmlInvalidVoid));
            }

            SoapAttributeFlags flags = a.SoapFlags;
            if ((flags & SoapAttributeFlags.Attribute) == SoapAttributeFlags.Attribute) {
                if (!accessor.TypeDesc.IsPrimitive && !accessor.TypeDesc.IsEnum)
                    throw new InvalidOperationException(Res.GetString(Res.XmlIllegalSoapAttribute, accessorName, accessor.TypeDesc.FullName));

                if ((flags & SoapAttributeFlags.Attribute) != flags)
                    throw new InvalidOperationException(Res.GetString(Res.XmlInvalidElementAttribute));
                
                AttributeAccessor attribute = new AttributeAccessor();
                attribute.Name = Accessor.EscapeQName(a.SoapAttribute == null || a.SoapAttribute.AttributeName.Length == 0 ? accessorName : a.SoapAttribute.AttributeName);
                attribute.Namespace = a.SoapAttribute == null || a.SoapAttribute.Namespace == null ? ns : a.SoapAttribute.Namespace;
                attribute.Form = XmlSchemaForm.Qualified; // attributes are always qualified since they're only used for encoded soap headers
                attribute.Mapping = ImportTypeMapping(modelScope.GetTypeModel(accessorType), (a.SoapAttribute == null ? String.Empty : a.SoapAttribute.DataType));
                attribute.Default = GetDefaultValue(model.FieldTypeDesc, a);
                accessor.Attribute = attribute;
                accessor.Elements = new ElementAccessor[0];
            }
            else {
                if ((flags & SoapAttributeFlags.Element) != flags)
                    throw new InvalidOperationException(Res.GetString(Res.XmlInvalidElementAttribute));

                ElementAccessor element = new ElementAccessor();
                element.IsSoap = true;
                element.Name = XmlConvert.EncodeLocalName(a.SoapElement == null || a.SoapElement.ElementName.Length == 0 ? accessorName : a.SoapElement.ElementName);
                element.Namespace = ns;
                element.Form = form;
                element.Mapping = ImportTypeMapping(modelScope.GetTypeModel(accessorType), (a.SoapElement == null ? String.Empty : a.SoapElement.DataType));
                if (a.SoapElement != null)
                    element.IsNullable = a.SoapElement.IsNullable;
                accessor.Elements = new ElementAccessor[] { element };
            }
        }
Beispiel #30
0
        void ImportAnyAttributeMember(XmlSchemaAnyAttribute any, CodeIdentifiers members) {
            SpecialMapping mapping = new SpecialMapping();
            mapping.TypeDesc = scope.GetTypeDesc(typeof(XmlAttribute));
            mapping.TypeName = mapping.TypeDesc.Name;

            AttributeAccessor accessor = new AttributeAccessor();
            accessor.Any = true;
            accessor.Mapping = mapping;

            MemberMapping member = new MemberMapping();
            member.Elements = new ElementAccessor[0];
            member.Attribute = accessor;
            member.Name = members.MakeRightCase("AnyAttr");
            member.Name = members.AddUnique(member.Name, member);
            member.TypeDesc = ((TypeMapping)accessor.Mapping).TypeDesc;
            member.TypeDesc = member.TypeDesc.CreateArrayTypeDesc();
        }
 void WriteAttribute(string source, AttributeAccessor attribute, string parent) {
     if (attribute.Mapping is SpecialMapping) {
         SpecialMapping special = (SpecialMapping)attribute.Mapping;
         if (special.TypeDesc.Kind == TypeKind.Attribute || special.TypeDesc.CanBeAttributeValue) {
             Writer.Write("WriteXmlAttribute(");
             Writer.Write(source);
             Writer.Write(", ");
             Writer.Write(parent);
             Writer.WriteLine(");");
         }
         else
             throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
     }
     else {
         TypeDesc typeDesc = attribute.Mapping.TypeDesc;
         if (!typeDesc.UseReflection) source = "(("+typeDesc.CSharpName+")"+source+")";
         WritePrimitive("WriteAttribute", attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "", attribute.Default, source, attribute.Mapping, false, false, false);
     }
 }
 private void WriteMember(string source, AttributeAccessor attribute, TypeDesc memberTypeDesc, string parent)
 {
     if (!memberTypeDesc.IsAbstract)
     {
         if (memberTypeDesc.IsArrayLike)
         {
             base.Writer.WriteLine("{");
             IndentedWriter writer = base.Writer;
             writer.Indent++;
             string cSharpName = memberTypeDesc.CSharpName;
             this.WriteArrayLocalDecl(cSharpName, "a", source, memberTypeDesc);
             if (memberTypeDesc.IsNullable)
             {
                 base.Writer.WriteLine("if (a != null) {");
                 IndentedWriter writer2 = base.Writer;
                 writer2.Indent++;
             }
             if (attribute.IsList)
             {
                 if (this.CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc))
                 {
                     base.Writer.Write("Writer.WriteStartAttribute(null, ");
                     base.WriteQuotedCSharpString(attribute.Name);
                     base.Writer.Write(", ");
                     string str2 = (attribute.Form == XmlSchemaForm.Qualified) ? attribute.Namespace : string.Empty;
                     if (str2 != null)
                     {
                         base.WriteQuotedCSharpString(str2);
                     }
                     else
                     {
                         base.Writer.Write("null");
                     }
                     base.Writer.WriteLine(");");
                 }
                 else
                 {
                     base.Writer.Write(typeof(StringBuilder).FullName);
                     base.Writer.Write(" sb = new ");
                     base.Writer.Write(typeof(StringBuilder).FullName);
                     base.Writer.WriteLine("();");
                 }
             }
             TypeDesc arrayElementTypeDesc = memberTypeDesc.ArrayElementTypeDesc;
             if (memberTypeDesc.IsEnumerable)
             {
                 base.Writer.Write(" e = ");
                 base.Writer.Write(typeof(IEnumerator).FullName);
                 if (memberTypeDesc.IsPrivateImplementation)
                 {
                     base.Writer.Write("((");
                     base.Writer.Write(typeof(IEnumerable).FullName);
                     base.Writer.WriteLine(").GetEnumerator();");
                 }
                 else if (memberTypeDesc.IsGenericInterface)
                 {
                     if (memberTypeDesc.UseReflection)
                     {
                         base.Writer.Write("(");
                         base.Writer.Write(typeof(IEnumerator).FullName);
                         base.Writer.Write(")");
                         base.Writer.Write(base.RaCodeGen.GetReflectionVariable(memberTypeDesc.CSharpName, "System.Collections.Generic.IEnumerable*"));
                         base.Writer.WriteLine(".Invoke(a, new object[0]);");
                     }
                     else
                     {
                         base.Writer.Write("((System.Collections.Generic.IEnumerable<");
                         base.Writer.Write(arrayElementTypeDesc.CSharpName);
                         base.Writer.WriteLine(">)a).GetEnumerator();");
                     }
                 }
                 else
                 {
                     if (memberTypeDesc.UseReflection)
                     {
                         base.Writer.Write("(");
                         base.Writer.Write(typeof(IEnumerator).FullName);
                         base.Writer.Write(")");
                     }
                     base.Writer.Write(base.RaCodeGen.GetStringForMethodInvoke("a", memberTypeDesc.CSharpName, "GetEnumerator", memberTypeDesc.UseReflection, new string[0]));
                     base.Writer.WriteLine(";");
                 }
                 base.Writer.WriteLine("if (e != null)");
                 base.Writer.WriteLine("while (e.MoveNext()) {");
                 IndentedWriter writer3 = base.Writer;
                 writer3.Indent++;
                 string typeName = arrayElementTypeDesc.CSharpName;
                 this.WriteLocalDecl(typeName, "ai", "e.Current", arrayElementTypeDesc.UseReflection);
             }
             else
             {
                 base.Writer.Write("for (int i = 0; i < ");
                 if (memberTypeDesc.IsArray)
                 {
                     base.Writer.WriteLine("a.Length; i++) {");
                 }
                 else
                 {
                     base.Writer.Write("((");
                     base.Writer.Write(typeof(ICollection).FullName);
                     base.Writer.WriteLine(")a).Count; i++) {");
                 }
                 IndentedWriter writer4 = base.Writer;
                 writer4.Indent++;
                 string str4 = arrayElementTypeDesc.CSharpName;
                 this.WriteLocalDecl(str4, "ai", base.RaCodeGen.GetStringForArrayMember("a", "i", memberTypeDesc), arrayElementTypeDesc.UseReflection);
             }
             if (attribute.IsList)
             {
                 if (this.CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc))
                 {
                     base.Writer.WriteLine("if (i != 0) Writer.WriteString(\" \");");
                     base.Writer.Write("WriteValue(");
                 }
                 else
                 {
                     base.Writer.WriteLine("if (i != 0) sb.Append(\" \");");
                     base.Writer.Write("sb.Append(");
                 }
                 if (attribute.Mapping is EnumMapping)
                 {
                     this.WriteEnumValue((EnumMapping) attribute.Mapping, "ai");
                 }
                 else
                 {
                     this.WritePrimitiveValue(arrayElementTypeDesc, "ai", true);
                 }
                 base.Writer.WriteLine(");");
             }
             else
             {
                 this.WriteAttribute("ai", attribute, parent);
             }
             IndentedWriter writer5 = base.Writer;
             writer5.Indent--;
             base.Writer.WriteLine("}");
             if (attribute.IsList)
             {
                 if (this.CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc))
                 {
                     base.Writer.WriteLine("Writer.WriteEndAttribute();");
                 }
                 else
                 {
                     base.Writer.WriteLine("if (sb.Length != 0) {");
                     IndentedWriter writer6 = base.Writer;
                     writer6.Indent++;
                     base.Writer.Write("WriteAttribute(");
                     base.WriteQuotedCSharpString(attribute.Name);
                     base.Writer.Write(", ");
                     string str5 = (attribute.Form == XmlSchemaForm.Qualified) ? attribute.Namespace : string.Empty;
                     if (str5 != null)
                     {
                         base.WriteQuotedCSharpString(str5);
                         base.Writer.Write(", ");
                     }
                     base.Writer.WriteLine("sb.ToString());");
                     IndentedWriter writer7 = base.Writer;
                     writer7.Indent--;
                     base.Writer.WriteLine("}");
                 }
             }
             if (memberTypeDesc.IsNullable)
             {
                 IndentedWriter writer8 = base.Writer;
                 writer8.Indent--;
                 base.Writer.WriteLine("}");
             }
             IndentedWriter writer9 = base.Writer;
             writer9.Indent--;
             base.Writer.WriteLine("}");
         }
         else
         {
             this.WriteAttribute(source, attribute, parent);
         }
     }
 }