private static void SerializeXPathSerializableMember( XDocument document, object value, SerializationContext context, HashSet <object> objectsAlreadySerialized) { Debug.Assert(value != null); var mappedElement = XmlOperations.GetOrCreateElement(document, context.Mapping.ElementXPath, context.NamespaceResolver); // Emit type info if necessary if (context.EmitTypeInfo) { if (mappedElement.Attribute(Constants.TypeInfoAttributeName) != null) { throw new SerializationException( String.Format( "Cannot serialize object with type information. Mapping XPath '{0}' is used by more than 1 value.", context.Mapping.ElementXPath)); } mappedElement.Add(new XAttribute(Constants.TypeInfoAttributeName, context.DeserializeAs.AssemblyQualifiedName.ToString())); } var innnerObjectXml = ToXmlInternal( document, ((IXPathSerializable)value), objectsAlreadySerialized, useMembers: context.UseMembers, parentMapping: context.Mapping, emitTypeInfo: context.EmitTypeInfo, version: context.Version, provider: context.FormatProvider, resolver: context.NamespaceResolver); // TODO: property filter - will not work (and btw now not even passed) }
private static void LoadSimpleMemberFromXml(XElement mappedElement, SerializationContext context) { string value = null; if (mappedElement != null) { value = XmlOperations.ExtractValueAsStringFromXml(context.Mapping, mappedElement, context.NamespaceResolver); } var convertedValue = XmlMemberSerialization.GetMemberActualValue(context.DeserializeAs, value, context); context.Member.SetValue(context.Serializable, convertedValue); }
private static void SerializeSimpleMember( XDocument document, object value, SerializationContext context) { string valueString = XmlMemberSerialization.GetMemberXmlValue(value, context); XmlOperations.PutValueConvertedToStringToXml( document, valueString, context.DeserializeAs, context.Mapping, false, context.EmitTypeInfo, context.NamespaceResolver); }
internal static void PutValueConvertedToStringToXml( XDocument document, string value, Type deserializeAs, Mapping mapping, bool isArrayItem, bool emitTypeInfo, IXmlNamespaceResolver resolver) { if (value != null || mapping.IsXmlMandatory || isArrayItem) { var mappedElement = XmlOperations.GetOrCreateElement(document, mapping.ElementXPath, resolver); if (mappedElement == null) { throw new SerializationException( String.Format("Cannot serialize object. Could not find or create element with mapping XPath '{0}'.", mapping.ElementXPath)); } if (value == null) { value = String.Empty; } if (String.IsNullOrWhiteSpace(mapping.AttributeName)) { if (mapping.AsXml) { if (!String.IsNullOrWhiteSpace(value)) { var wrappingElement = XElement.Parse("<root>" + value + "</root>"); mappedElement.Add(wrappingElement.Elements()); } if (emitTypeInfo) { if (deserializeAs != null) { if (mappedElement.Attribute(Constants.TypeInfoAttributeName) != null) { throw new SerializationException( String.Format("Cannot serialize object with type information. Mapping XPath '{0}' is used by more than 1 value.", mapping.ElementXPath)); } mappedElement.Add(new XAttribute(Constants.TypeInfoAttributeName, deserializeAs.AssemblyQualifiedName.ToString())); } else { if (mappedElement.Attribute(Constants.NullValueAttributeName) != null) { throw new SerializationException( String.Format("Cannot serialize object with type information. Mapping XPath '{0}' is used by more than 1 value.", mapping.ElementXPath)); } mappedElement.Add(new XAttribute(Constants.NullValueAttributeName, "true")); } } } else if (isArrayItem) { var arrayItemElement = new XElement(mapping.ArrayItemElementName, value); if (emitTypeInfo) { if (deserializeAs != null) { arrayItemElement.Add(new XAttribute(Constants.TypeInfoAttributeName, deserializeAs.AssemblyQualifiedName.ToString())); } else { arrayItemElement.Add(new XAttribute(Constants.NullValueAttributeName, "true")); } } mappedElement.Add(arrayItemElement); } else { mappedElement.Value = value; if (emitTypeInfo) { if (deserializeAs != null) { if (mappedElement.Attribute(Constants.TypeInfoAttributeName) != null) { throw new SerializationException( String.Format("Cannot serialize object with type information. Mapping XPath '{0}' is used by more than 1 value.", mapping.ElementXPath)); } mappedElement.Add(new XAttribute(Constants.TypeInfoAttributeName, deserializeAs.AssemblyQualifiedName.ToString())); } else { if (mappedElement.Attribute(Constants.NullValueAttributeName) != null) { throw new SerializationException( String.Format("Cannot serialize object with type information. Mapping XPath '{0}' is used by more than 1 value.", mapping.ElementXPath)); } mappedElement.Add(new XAttribute(Constants.NullValueAttributeName, "true")); } } } } else { mappedElement.SetAttributeValue(XPathHelper.ConvertToXName(mapping.AttributeName, resolver), value); } } }
private static void SerializeArrayMember( XDocument document, object array, SerializationContext context, HashSet <object> objectsAlreadySerialized) { Debug.Assert(array != null); var mappedElement = XmlOperations.GetOrCreateElement(document, context.Mapping.ElementXPath, context.NamespaceResolver); // Emit type info if necessary if (context.EmitTypeInfo) { if (mappedElement.Attribute(Constants.TypeInfoAttributeName) != null) { throw new SerializationException( String.Format( "Cannot serialize object with type information. Mapping XPath '{0}' is used by more than 1 value.", context.Mapping.ElementXPath)); } mappedElement.Add(new XAttribute(Constants.TypeInfoAttributeName, context.DeserializeAs.AssemblyQualifiedName.ToString())); } foreach (var item in (IEnumerable)array) { var serializableItem = item as IXPathSerializable; if (serializableItem != null) { var objectElement = ToXmlInternal( new XDocument(), serializableItem, objectsAlreadySerialized, useMembers: null, parentMapping: null, emitTypeInfo: context.EmitTypeInfo, version: context.Version, provider: context.FormatProvider, resolver: context.NamespaceResolver).Root; // TODO: pass along every argument from outer ToXml if (context.EmitTypeInfo) { objectElement.Add(new XAttribute(Constants.TypeInfoAttributeName, serializableItem.GetType().AssemblyQualifiedName.ToString())); } mappedElement.Add(objectElement); } else { string valueString = XmlMemberSerialization.GetMemberXmlValue(item, context); Type deserializeItemAs = null; if (item != null && context.EmitTypeInfo) { deserializeItemAs = item.GetType(); } XmlOperations.PutValueConvertedToStringToXml( document, valueString, deserializeItemAs, context.Mapping, true, context.EmitTypeInfo, context.NamespaceResolver); } } }
private static XDocument ToXmlInternal( XDocument document, IXPathSerializable serializable, HashSet <object> objectsAlreadySerialized, MemberInfo[] useMembers, Mapping parentMapping, bool emitTypeInfo, int version, IFormatProvider provider, XmlNamespaceManager resolver) { // Take care of circular references if (objectsAlreadySerialized.Contains(serializable)) { throw new SerializationException( String.Format("A circular reference was detected while serializing an object of type '{0}'", serializable.GetType())); } else { objectsAlreadySerialized.Add(serializable); } if (document == null) { document = new XDocument(); } // Initialize namespace resolver from class attributes if (resolver == null) { resolver = new XmlNamespaceManager(new NameTable()); } var namespaceAttributes = serializable.GetType().GetCustomAttributes(typeof(NamespacePrefixAttribute), true); foreach (NamespacePrefixAttribute namespaceAttribute in namespaceAttributes) { resolver.AddNamespace(namespaceAttribute.Prefix, namespaceAttribute.Uri); } // Ensure minimal xml structure var minimalXmlAttributes = serializable.GetType().GetCustomAttributes(typeof(MinimalXmlStructureAttribute), true); if (minimalXmlAttributes != null) { foreach (MinimalXmlStructureAttribute minimalXmlAttribute in minimalXmlAttributes) { string xPath = minimalXmlAttribute.ElementXPath; if (String.IsNullOrWhiteSpace(xPath)) { xPath = XmlConvert.EncodeName(serializable.GetType().Name); } XmlOperations.GetOrCreateElement(document, xPath, resolver); } } var typeInfo = SerializableTypeInfo.GetTypeInfo(serializable.GetType()); var membersToSerialize = typeInfo.Members.Where(x => useMembers == null || useMembers.Length == 0 || useMembers.Contains(x.MemberInfo)); SerializeMembers( document, serializable, objectsAlreadySerialized, membersToSerialize.ToArray(), useMembers, parentMapping, emitTypeInfo, version, provider, resolver); // Return resulting document return(document); }