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); } }
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); } }
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; }
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; }
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); } } }
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(); }
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; }
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; }
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); } }
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; }
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 }; } }
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); } } }