using System; using System.Xml; using System.Xml.Linq; using Umbraco.Core.Configuration; using Umbraco.Core.PropertyEditors; namespace Umbraco.Core.Models { public static class PropertyExtensions { /// /// Creates the xml representation for the object /// /// to generate xml for /// Xml of the property and its value public static XElement ToXml(this Property property) { return property.ToXml(ApplicationContext.Current.Services.DataTypeService); } internal static XElement ToXml(this Property property, IDataTypeService dataTypeService) { var nodeName = UmbracoSettings.UseLegacyXmlSchema ? "data" : property.Alias.ToSafeAlias(); var xd = new XmlDocument(); var xmlNode = xd.CreateNode(XmlNodeType.Element, nodeName, ""); //Add the property alias to the legacy schema if (UmbracoSettings.UseLegacyXmlSchema) { var alias = xd.CreateAttribute("alias"); alias.Value = property.Alias.ToSafeAlias(); xmlNode.Attributes.Append(alias); } //TODO: We'll need to clean this up eventually but for now here's what we're doing: // * Check if the property's DataType is assigned from a Property Editor or a legacy IDataType // * Get the XML result from the IDataType if there is one, otherwise just construct a simple // XML construct from the value returned from the Property Editor. // More details discussed here: https://groups.google.com/forum/?fromgroups=#!topic/umbraco-dev/fieWZzHj7oY //var dataType = ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionById(property.PropertyType.DataTypeDefinitionId); //if (dataType == null) throw new InvalidOperationException("No data type definition found with id " + property.PropertyType.DataTypeDefinitionId); //We've already got the value for the property so we're going to give it to the // data type's data property so it doesn't go re-look up the value from the db again. var defaultData = dt.Data as IDataValueSetter; if (defaultData != null) { defaultData.SetValue(property.Value, property.PropertyType.DataTypeDatabaseType.ToString()); } xmlNode.AppendChild(dt.Data.ToXMl(xd)); var propertyEditor = PropertyEditorResolver.Current.GetById(property.PropertyType.DataTypeId); if (propertyEditor != null) { switch (property.PropertyType.DataTypeDatabaseType) { case DataTypeDatabaseType.Nvarchar: xmlNode.AppendChild(xd.CreateTextNode(property.Value.ToXmlString())); break; case DataTypeDatabaseType.Integer: xmlNode.AppendChild(xd.CreateTextNode(property.Value.ToXmlString(property.Value.GetType()))); break; case DataTypeDatabaseType.Ntext: //put text in cdata xmlNode.AppendChild(xd.CreateCDataSection(property.Value.ToXmlString())); break; case DataTypeDatabaseType.Date: //treat dates differently, output the format as xml format if (property.Value == null) { xmlNode.AppendChild(xd.CreateTextNode(string.Empty)); } else { var dt = (DateTime)property.Value; xmlNode.AppendChild(xd.CreateTextNode(dt.ToXmlString())); } break; default: throw new ArgumentOutOfRangeException(); } } else { //NOTE: An exception will be thrown if this doesn't exist var legacyDataType = property.PropertyType.DataType(property.Id); xmlNode.AppendChild(legacyDataType.Data.ToXMl(xd)); } var element = xmlNode.GetXElement(); return element; } } }