private void ParseComplexTypeForAttributes(XmlSchemaComplexType complexType, XSDMessage Message) { foreach (XmlSchemaAttribute a in complexType.Attributes) { XmlSchemaSimpleType st = a.AttributeSchemaType; if (st != null && Message.ContainsKey(a.Name)) { SetSchemaFacets(st, Message[a.Name]); } } XmlSchemaSequence sequence = complexType.Particle as XmlSchemaSequence; if (sequence != null) { foreach (XmlSchemaElement sequenceItem in sequence.Items) { XmlSchemaComplexType sequenceItemComplexType = sequenceItem.ElementSchemaType as XmlSchemaComplexType; if (sequenceItemComplexType != null) { ParseComplexTypeForAttributes(sequenceItemComplexType, Message); } XmlSchemaSimpleType sequenceItemSimpleType = sequenceItem.ElementSchemaType as XmlSchemaSimpleType; if (sequenceItemSimpleType != null) { if (Message.ContainsKey(sequenceItem.Name)) { XmlSchemaSimpleType newType = SetSchemaFacets(sequenceItemSimpleType, Message[sequenceItem.Name]); sequenceItem.SchemaType = newType; sequenceItem.SchemaTypeName = new XmlQualifiedName(); } } SetMinOccurs(sequenceItem, Message[sequenceItem.Name]); } } }
void ExtractAttributes(PropertyInfo pi, MessageDescription Message, OperationDescription Operation, MessagePartDescription MessagePartDescription) { object[] xmlElementAttributes = pi.GetCustomAttributes(typeof(XmlElementAttribute), false); object[] stringLengthAttributes = pi.GetCustomAttributes(typeof(StringLengthAttribute), false); object[] regexAttributes = pi.GetCustomAttributes(typeof(RegularExpressionAttribute), false); object[] rangeAttributes = pi.GetCustomAttributes(typeof(RangeAttribute), false); object[] dataMemberAttributes = pi.GetCustomAttributes(typeof(DataMemberAttribute), false); string ElemName = pi.Name; //pick up XmlElement's ElementName if used to match later if (xmlElementAttributes.Length > 0) { XmlElementAttribute xmlElementAttrib = xmlElementAttributes[0] as XmlElementAttribute; if (!string.IsNullOrWhiteSpace(xmlElementAttrib.ElementName)) { ElemName = xmlElementAttrib.ElementName; } } if (!_Namespaces.ContainsKey(MessagePartDescription.Namespace)) { _Namespaces.Add(MessagePartDescription.Namespace, new XSDNamespace()); } XSDNamespace Namespace = _Namespaces[MessagePartDescription.Namespace]; if (!Namespace.ContainsKey(Operation.Name)) { Namespace.Add(Operation.Name, new XSDMessage()); } XSDMessage XsdMessage = Namespace[Operation.Name]; for (int i = 0; i < stringLengthAttributes.Length; i++) { StringLengthAttribute sla = stringLengthAttributes[i] as StringLengthAttribute; XsdMessage.Add(ElemName, new StringLengthMessagePart() { MinLength = sla.MinimumLength, MaxLength = sla.MaximumLength }); } for (int i = 0; i < regexAttributes.Length; i++) { RegularExpressionAttribute rea = regexAttributes[i] as RegularExpressionAttribute; XsdMessage.Add(ElemName, new RegexMessagePart() { Regex = rea.Pattern }); } for (int i = 0; i < rangeAttributes.Length; i++) { RangeAttribute raa = rangeAttributes[i] as RangeAttribute; XsdMessage.Add(ElemName, new RangeMessagePart() { Min = raa.Minimum, Max = raa.Maximum }); } for (int i = 0; i < dataMemberAttributes.Length; i++) { DataMemberAttribute dma = dataMemberAttributes[i] as DataMemberAttribute; XsdMessage.Add(ElemName, new RequiredMessagePart() { Required = dma.IsRequired }); } //rough seach for properties that are "custom" classes: there isn't a better way of doing it that I can find. if (pi.PropertyType.IsClass && (pi.PropertyType.BaseType != pi.PropertyType) && !pi.PropertyType.Namespace.StartsWith("System.") && !pi.PropertyType.Namespace.StartsWith("Microsoft.")) //hopefully filter out base objects { //iterate nested properties, looking for more attributes foreach (PropertyInfo piNested in pi.PropertyType.GetProperties()) { ExtractAttributes(piNested, Message, Operation, MessagePartDescription); } } }