/// <summary> /// Finds a property with the specified XML element information. /// </summary> /// <param name="xml">The XML information to find.</param> /// <returns> /// A PropertyInfo for the first property found matching the specified /// information or null if no matches were found. /// </returns> public PropertyInfo FindElement(XmlComponent xml) { return(this.elements .Where(e => e.Item1.Equals(xml)) .Select(e => e.Item2) .FirstOrDefault()); }
/// <summary> /// Registers the specified type with the specified XML name and /// namespace URI. /// </summary> /// <typeparam name="T"> /// The type of the class to be registered, deriving from /// <see cref="Element"/>. /// </typeparam> /// <param name="xml">The XML information of the element.</param> /// <exception cref="ArgumentNullException">xml is null.</exception> /// <exception cref="ArgumentException"> /// The type has already been registered or another type with the /// same XML name and namespace URI has been already registered. /// </exception> public static void Register <T>(XmlComponent xml) where T : Element { Check.IsNotNull(xml, nameof(xml)); RegisterType(xml.Clone(), typeof(T)); // Don't store what the user passed us }
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 static bool WriteStartTag(XmlWriter writer, XmlNamespaceManager manager, Element element, out string ns) { ns = null; // Custom elements take priority over component if (element is ICustomElement customElement) { customElement.CreateStartElement(writer); if (!customElement.ProcessChildren) { return(false); // Don't need to do any more work. } } else { XmlComponent component = KmlFactory.FindType(element.GetType()); if (component == null) { // We can't handle it so ignore it System.Diagnostics.Debug.WriteLine("Unknown Element type - please register first." + element.GetType()); return(false); } ns = component.NamespaceUri; string prefix = FindPrefix(manager, ns); writer.WriteStartElement(prefix, component.Name, component.NamespaceUri); } return(true); }
/// <summary> /// Finds a property with the specified XML element information. /// </summary> /// <param name="xml">The XML information to find.</param> /// <returns> /// A PropertyInfo for the first property found matching the specified /// information or null if no matches were found. /// </returns> public PropertyInfo FindElement(XmlComponent xml) { var query = from element in _elements where element.Item1.Equals(xml) select element.Item2; return(query.FirstOrDefault()); }
/// <summary> /// Finds a property with the specified XML attribute information. /// </summary> /// <param name="xml">The XML information to find.</param> /// <returns> /// A PropertyInfo for the first property found matching the specified /// information or null if no matches were found. /// </returns> public PropertyInfo FindAttribute(XmlComponent xml) { if (this.attributes.TryGetValue(xml, out Tuple <PropertyInfo, KmlAttributeAttribute> property)) { return(property.Item1); } return(null); }
/// <summary> /// Creates a derived class of <see cref="Element"/> based on the XML /// information. /// </summary> /// <param name="xml">The XML information of the element.</param> /// <returns> /// A derived class of <c>Element</c> if the specified information was /// found; otherwise, null. /// </returns> /// <exception cref="System.MemberAccessException"> /// Cannot create an instance of an abstract class, or this member was /// invoked with a late-binding mechanism. /// </exception> /// <exception cref="System.Reflection.TargetInvocationException"> /// The constructor being called throws an exception. /// </exception> public static Element CreateElement(XmlComponent xml) { if (Types.TryGetValue(xml, out Func <Element> constructor)) { return(constructor()); } return(null); }
/// <summary> /// Creates a derived class of <see cref="Element"/> based on the XML /// information. /// </summary> /// <param name="xml">The XML information of the element.</param> /// <returns> /// A derived class of <c>Element</c> if the specified information was /// found; otherwise, null. /// </returns> /// <exception cref="System.MemberAccessException"> /// Cannot create an instance of an abstract class, or this member was /// invoked with a late-binding mechanism. /// </exception> /// <exception cref="System.Reflection.TargetInvocationException"> /// The constructor being called throws an exception. /// </exception> public static Element CreateElement(XmlComponent xml) { if (Types.TryGetValue(xml, out Type type)) { return((Element)Activator.CreateInstance(type)); } return(null); }
/// <summary> /// Registers the specified type with the specified XML name and /// namespace URI. /// </summary> /// <typeparam name="T"> /// The type of the class to be registered, deriving from /// <see cref="Element"/>. /// </typeparam> /// <param name="xml">The XML information of the element.</param> /// <exception cref="ArgumentNullException">xml is null.</exception> /// <exception cref="ArgumentException"> /// The type has already been registered or another type with the /// same XML name and namespace URI has been already registered. /// </exception> public static void Register <T>(XmlComponent xml) where T : Element { if (xml == null) { throw new ArgumentNullException("xml"); } RegisterType(xml.Clone(), typeof(T)); // Don't store what the user passed us }
private static void RegisterElement(Type type) { KmlElementAttribute element = TypeBrowser.GetElement(type.GetTypeInfo()); if (element != null) { var xml = new XmlComponent(null, element.ElementName, element.Namespace); RegisterType(xml, type); } }
private static void SerializeElement(XmlWriter writer, Element element) { // Write start tag XmlComponent component = KmlFactory.FindType(element.GetType()); // Custom elements take priority over component ICustomElement customElement = element as ICustomElement; if (customElement != null) { customElement.CreateStartElement(writer); if (!customElement.ProcessChildren) { return; // Don't need to to any more work. } } else if (component != null) { writer.WriteStartElement(component.Name, component.NamespaceUri); } else { // We can't handle it so ignore it System.Diagnostics.Debug.WriteLine("Unknown Element type - please register first." + element.GetType()); return; // Skip } // Write the attributes - unknown, serialized then namespaces. foreach (var att in element.Attributes) { writer.WriteAttributeString(att.Prefix, att.Name, att.NamespaceUri, att.Value); } WriteAttributes(writer, element); foreach (var ns in element.Namespaces.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml)) { writer.WriteAttributeString("xmlns", ns.Key, string.Empty, ns.Value); } // Now the text part WriteData(writer, element.InnerText); // Now write the elements - serialized, children then unknown children. WriteElements(writer, element); SerializeElements(writer, element.OrderedChildren); SerializeElements(writer, element.Orphans); // Finished... writer.WriteEndElement(); }
// Private helper function to ensure both dicionaries are updated. private static void RegisterType(XmlComponent xml, Type type) { if (_names.ContainsKey(type)) { throw new ArgumentException("Class type has already been registered."); } if (_types.ContainsKey(xml)) { throw new ArgumentException("Another type has been registered with the specified XML qualified name."); } _names.Add(type, xml); _types.Add(xml, type); }
private static void RegisterAssembly(Assembly assembly) { foreach (var type in assembly.GetExportedTypes()) { if (type.IsSubclassOf(typeof(Element))) { KmlElementAttribute element = TypeBrowser.GetElement(type); if (element != null) { var xml = new XmlComponent(null, element.ElementName, element.Namespace); RegisterType(xml, type); } } } }
/// <summary> /// Finds a property with the specified XML element information. /// </summary> /// <param name="xml">The XML information to find.</param> /// <returns> /// A PropertyInfo for the first property found matching the specified /// information or null if no matches were found. /// </returns> public PropertyInfo FindElement(XmlComponent xml) { var query = from element in this.elements where element.Item1.Equals(xml) select element.Item2; var propInfo = query.FirstOrDefault(); // try looking without the namespace if (propInfo == null) { propInfo = this.elements.Where(e => e.Item1.Name == xml.Name).Select(e => e.Item2).FirstOrDefault(); } return(propInfo); }
/// <summary> /// Creates a derived class of <see cref="Element"/> based on the XML /// information. /// </summary> /// <param name="xml">The XML information of the element.</param> /// <returns> /// A derived class of <c>Element</c> if the specified information was /// found; otherwise, null. /// </returns> /// <exception cref="System.MemberAccessException"> /// Cannot create an instance of an abstract class, or this member was /// invoked with a late-binding mechanism. /// </exception> /// <exception cref="System.Reflection.TargetInvocationException"> /// The constructor being called throws an exception. /// </exception> public static Element CreateElement(XmlComponent xml) { Type type; if (Types.TryGetValue(xml, out type)) { return((Element)Activator.CreateInstance(type)); } //check and see if the namespace is wrong but is in the 2.2 if (Kml22ElementTypes.TryGetValue(xml.Name, out type)) { return((Element)Activator.CreateInstance(type)); } return(null); }
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. this.ExtractAttributes(type.BaseType); // Store the found elements here so we can add them in order later var elements = new List <Tuple <XmlComponent, PropertyInfo, KmlElementAttribute> >(); const BindingFlags PropertyFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; foreach (var property in type.GetProperties(PropertyFlags)) { var attribute = GetAttribute(property); if (attribute != null) { XmlComponent 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 (!_attributes.ContainsKey(component)) { _attributes.Add(component, Tuple.Create(property, attribute)); } } else { var element = GetElement(property); if (element != null) { XmlComponent component = new XmlComponent(null, element.ElementName, element.Namespace); elements.Add(Tuple.Create(component, property, element)); } } } // Now add the elements in order _elements.AddRange(elements.OrderBy(e => e.Item3.Order)); }
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> /// Creates a derived class of <see cref="Element"/> based on the XML /// information. /// </summary> /// <param name="xml">The XML information of the element.</param> /// <returns> /// A derived class of <c>Element</c> if the specified information was /// found; otherwise, null. /// </returns> /// <exception cref="System.MemberAccessException"> /// Cannot create an instance of an abstract class, or this member was /// invoked with a late-binding mechanism. /// </exception> /// <exception cref="System.Reflection.TargetInvocationException"> /// The constructor being called throws an exception. /// </exception> public static Element CreateElement(XmlComponent xml) { if (Types.TryGetValue(xml, out Func <Element> constructor)) { return(constructor()); } if (string.IsNullOrEmpty(xml?.Namespace)) { var comp = new XmlComponent(string.Empty, xml.Name, KmlNamespaces.Kml22Namespace); if (Types.TryGetValue(xml, out Func <Element> cons)) { return(cons()); } } return(null); }
/// <summary> /// Finds a property with the specified XML element information. /// </summary> /// <param name="xml">The XML information to find.</param> /// <returns> /// A PropertyInfo for the first property found matching the specified /// information or null if no matches were found. /// </returns> public ElementInfo FindElement(XmlComponent xml) { this.elements.TryGetValue(xml, out ElementInfo info); return(info); }
/// <summary> /// Finds a property with the specified XML attribute information. /// </summary> /// <param name="xml">The XML information to find.</param> /// <returns> /// The information for the first property found matching the specified /// information or null if no matches were found. /// </returns> public ElementInfo FindAttribute(XmlComponent xml) { this.attributes.TryGetValue(xml, out ElementInfo info); return(info); }