Ejemplo n.º 1
0
        /// <summary>
        /// Save an object to Xml.
        /// </summary>
        /// <param name="value">The object to serialize.</param>
        /// <param name="writer">The XmlWriter object to save to.</param>
        public static void SaveToXml(object value, XmlWriter writer)
        {
            Type type = value.GetType();

            XmlElementNameAttribute[] xmlElementNameAttributes = (XmlElementNameAttribute[])type.GetCustomAttributes(typeof(XmlElementNameAttribute), true);
            string elementName = (xmlElementNameAttributes.Length > 0 ? xmlElementNameAttributes[0].XmlElementName : type.Name);

            writer.WriteStartElement(elementName);

            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                Type propertyType = property.PropertyType;

                XmlIgnoreAttribute[] ignoreAttributes = (XmlIgnoreAttribute[])property.GetCustomAttributes(typeof(XmlIgnoreAttribute), true);
                if (ignoreAttributes.Length == 0)
                {
                    XmlAttributeNameAttribute[] xmlAttributeNameAttributes = (XmlAttributeNameAttribute[])property.GetCustomAttributes(typeof(XmlAttributeNameAttribute), true);
                    string attributeName = (xmlAttributeNameAttributes.Length > 0 ? xmlAttributeNameAttributes[0].XmlAttributeName : property.Name);
                    object propertyValue = property.GetValue(value, null);
                    if (propertyValue != null)
                    {
                        XmlHasChildElementsAttribute[] xmlHasChildElementsAttributes = (XmlHasChildElementsAttribute[])propertyType.GetCustomAttributes(typeof(XmlHasChildElementsAttribute), true);
                        if ((xmlHasChildElementsAttributes.Length > 0) && (xmlHasChildElementsAttributes[0].HasChildElements))
                        {
                            SaveToXml(propertyValue, writer);
                        }
                        else
                        {
                            XmlCollectionAttribute[] xmlCollectionAttributes = (XmlCollectionAttribute[])property.GetCustomAttributes(typeof(XmlCollectionAttribute), true);
                            if (xmlCollectionAttributes.Length > 0)
                            {
                                if ((propertyValue is IList == false))
                                {
                                    throw new Exception("Property marked as XmlCollection but does not implement IList.");
                                }

                                XmlCollectionAttribute xmlCollectionAttribute = xmlCollectionAttributes[0];
                                writer.WriteStartElement(xmlCollectionAttribute.CollectionElementName);

                                IList listValue = (IList)propertyValue;
                                foreach (object childValue in listValue)
                                {
                                    SaveToXml(childValue, writer);
                                }

                                writer.WriteEndElement();
                            }
                            else
                            {
                                writer.WriteAttributeString(attributeName, (propertyValue != null ? XmlHelper.ToString(propertyValue) : String.Empty));
                            }
                        }
                    }
                }
            }

            writer.WriteEndElement();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parse an Xml element into a specifed type.
        /// </summary>
        /// <param name="elementNode">The xml node containing the element to parse.</param>
        /// <param name="elementType">The type of object to deserialize into.</param>
        /// <returns>The instance of the newly deserialized object.</returns>
        public static object ParseElement(XmlNode elementNode, Type elementType)
        {
            ConstructorInfo constructorInfo = elementType.GetConstructor(new Type[] { });
            object          elementObject   = constructorInfo.Invoke(null);

            XmlCollectionAttribute[] xmlCollectionClassAttributes = (XmlCollectionAttribute[])elementType.GetCustomAttributes(typeof(XmlCollectionAttribute), true);
            if (xmlCollectionClassAttributes.Length > 0)
            {
                if ((elementObject is IList == false))
                {
                    throw new Exception("Class marked as XmlCollection but type does not implement IList.");
                }

                XmlCollectionAttribute xmlCollectionClassAttribute = xmlCollectionClassAttributes[0];
                if ((elementNode.Name == xmlCollectionClassAttribute.CollectionElementName) && (elementNode.HasChildNodes))
                {
                    IList listObject = (IList)elementObject;
                    foreach (XmlNode childNode in elementNode.ChildNodes)
                    {
                        if (childNode.Name == xmlCollectionClassAttribute.ItemElementName)
                        {
                            object childValue = ParseElement(childNode, xmlCollectionClassAttribute.ItemType);
                            listObject.Add(childValue);
                        }
                    }
                }
            }
            else
            {
                PropertyInfo[] properties = elementType.GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    Type propertyType = property.PropertyType;

                    XmlIgnoreAttribute[] ignoreAttributes = (XmlIgnoreAttribute[])property.GetCustomAttributes(typeof(XmlIgnoreAttribute), true);
                    if (ignoreAttributes.Length > 0)
                    {
                        continue;
                    }

                    bool   isRequired;
                    bool   invokeConstructor;
                    object defaultValue;
                    XmlRequiredAttribute[] xmlRequiredAttributes = (XmlRequiredAttribute[])property.GetCustomAttributes(typeof(XmlRequiredAttribute), true);
                    if (xmlRequiredAttributes.Length > 0)
                    {
                        XmlRequiredAttribute xmlRequiredAttribute = xmlRequiredAttributes[0];

                        isRequired        = xmlRequiredAttribute.IsRequired;
                        invokeConstructor = xmlRequiredAttribute.InvokeConstructor;
                        defaultValue      = xmlRequiredAttribute.DefaultValue;
                    }
                    else
                    {
                        isRequired        = true;
                        invokeConstructor = false;
                        defaultValue      = null;
                    }

                    object value;
                    XmlHasChildElementsAttribute[] xmlHasChildElementsAttributes = (XmlHasChildElementsAttribute[])propertyType.GetCustomAttributes(typeof(XmlHasChildElementsAttribute), true);
                    if ((xmlHasChildElementsAttributes.Length > 0) && (xmlHasChildElementsAttributes[0].HasChildElements))
                    {
                        XmlElementNameAttribute[] xmlElementNameAttributes = (XmlElementNameAttribute[])propertyType.GetCustomAttributes(typeof(XmlElementNameAttribute), true);
                        string  childElementName = (xmlElementNameAttributes.Length > 0 ? xmlElementNameAttributes[0].XmlElementName : property.Name);
                        XmlNode childElementNode = XmlHelper.GetChildNode(elementNode, childElementName);

                        if (childElementNode != null)
                        {
                            value = ParseElement(childElementNode, propertyType);
                        }
                        else
                        {
                            if (isRequired)
                            {
                                throw new Exception("Child element [" + childElementName + "] not found.");
                            }

                            if (invokeConstructor)
                            {
                                ConstructorInfo childElementConstructorInfo = propertyType.GetConstructor(new Type[] { });
                                value = childElementConstructorInfo.Invoke(null);
                            }
                            else
                            {
                                value = defaultValue;
                            }
                        }
                    }
                    else
                    {
                        XmlAttributeNameAttribute[] xmlAttributeNameAttributes = (XmlAttributeNameAttribute[])property.GetCustomAttributes(typeof(XmlAttributeNameAttribute), true);
                        string attributeName = (xmlAttributeNameAttributes.Length > 0 ? xmlAttributeNameAttributes[0].XmlAttributeName : property.Name);
                        value = XmlHelper.GetAttribute(elementNode, attributeName, propertyType, isRequired, defaultValue);

                        if ((value == defaultValue) && (isRequired == false) && (invokeConstructor))
                        {
                            if (propertyType.IsValueType)
                            {
                                value = Activator.CreateInstance(propertyType);
                            }
                            else
                            {
                                ConstructorInfo propertyConstructorInfo = propertyType.GetConstructor(new Type[] { });
                                value = propertyConstructorInfo.Invoke(null);
                            }
                        }
                    }

                    XmlCollectionAttribute[] xmlCollectionAttributes = (XmlCollectionAttribute[])property.GetCustomAttributes(typeof(XmlCollectionAttribute), true);
                    if (xmlCollectionAttributes.Length > 0)
                    {
                        if ((value is IList == false))
                        {
                            throw new Exception("Property marked as XmlCollection but type does not implement IList.");
                        }

                        XmlCollectionAttribute xmlCollectionAttribute = xmlCollectionAttributes[0];
                        XmlNode xmlCollectionNode = XmlHelper.GetChildNode(elementNode, xmlCollectionAttribute.CollectionElementName);
                        if ((xmlCollectionNode != null) && (xmlCollectionNode.HasChildNodes))
                        {
                            IList listValue = (IList)value;
                            foreach (XmlNode childNode in xmlCollectionNode.ChildNodes)
                            {
                                if (childNode.Name == xmlCollectionAttribute.ItemElementName)
                                {
                                    object childValue = ParseElement(childNode, xmlCollectionAttribute.ItemType);
                                    listValue.Add(childValue);
                                }
                            }
                        }
                    }

                    property.SetValue(elementObject, value, null);
                }
            }

            return(elementObject);
        }