private IEnumerable <ElementInfo> ExtractPropertyElements(TypeInfo typeInfo) { bool IsSerializableProperty(PropertyInfo property) { return(property.CanRead && !property.GetMethod.IsStatic && (property.CanWrite || IsEnumerable(property))); } foreach (PropertyInfo property in typeInfo.DeclaredProperties.Where(IsSerializableProperty)) { KmlAttributeAttribute attribute = GetAttribute <KmlAttributeAttribute>(property); if (attribute != null) { var component = new XmlComponent(null, attribute.AttributeName, null); // Check if a property has already been registered with the info. // Ignore later properties - i.e. don't throw an exception. if (!this.attributes.ContainsKey(component)) { this.attributes.Add(component, new ElementInfo(property, attribute)); } } else { KmlElementAttribute kmlElement = GetElement(property); if (kmlElement != null) { yield return(new ElementInfo(property, kmlElement)); } } } }
private void ExtractAttributes(Type type) { if (type == null || type == typeof(object)) { return; // We've reached the top, now we have to stop } // Look at the base type first as the KML schema specifies <sequence> // This will also find private fields in the base classes, which can't // be seen through a derived class. TypeInfo typeInfo = type.GetTypeInfo(); this.ExtractAttributes(typeInfo.BaseType); // Store the found elements here so we can add them in order later var elements = new List <Tuple <XmlComponent, PropertyInfo, KmlElementAttribute> >(); foreach (PropertyInfo property in typeInfo.DeclaredProperties.Where(p => !p.GetMethod.IsStatic)) { KmlAttributeAttribute attribute = GetAttribute(property); if (attribute != null) { var component = new XmlComponent(null, attribute.AttributeName, null); // Check if a property has already been registered with the info. // Ignore later properties - i.e. don't throw an exception. if (!this.attributes.ContainsKey(component)) { this.attributes.Add(component, Tuple.Create(property, attribute)); } } else { KmlElementAttribute element = GetElement(property); if (element != null) { var component = new XmlComponent(null, element.ElementName, element.Namespace); elements.Add(Tuple.Create(component, property, element)); } } } // Now add the elements in order this.elements.AddRange(elements.OrderBy((Tuple <XmlComponent, PropertyInfo, KmlElementAttribute> e) => e.Item3.Order)); }
/// <summary> /// Initializes a new instance of the <see cref="ElementInfo"/> class. /// </summary> /// <param name="property">The property information.</param> /// <param name="kmlAttribute">The KML attribute information.</param> public ElementInfo(PropertyInfo property, KmlAttributeAttribute kmlAttribute) : this(property) { this.Component = new XmlComponent(null, kmlAttribute.AttributeName, null); }