コード例 #1
0
        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)
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
 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);
         }
     }
 }
コード例 #5
0
        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);
                }
            }
        }
コード例 #6
0
        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);
        }