Exemple #1
0
 /// <summary>
 /// Adds an <see cref="string"/> XML converter to the list.
 /// </summary>
 /// <param name="converters">The list of XML converters.</param>
 public static void AddStringConverter(this IList <XmlConverter> converters)
 {
     converters.AddXmlConverter <string>((w, s, q) =>
     {
         if (s.IsNullOrWhiteSpace())
         {
             return;
         }
         if (w.WriteState == WriteState.Start && q == null)
         {
             q = new XmlQualifiedEntity(typeof(string).ToFriendlyName());
         }
         w.WriteEncapsulatingElementIfNotNull(s, q, (writer, value) =>
         {
             if (value.IsXmlString())
             {
                 writer.WriteCData(value);
             }
             else
             {
                 writer.WriteValue(value);
             }
         });
     });
 }
 public override void WriteXml(XmlWriter writer, object value, XmlQualifiedEntity elementName = null)
 {
     if (Writer == null)
     {
         throw new NotImplementedException("Delegate writer is null.");
     }
     Writer.Invoke(writer, value, elementName ?? RootName);
 }
 internal DynamicXmlConverterCore(Type objectType, Action <XmlWriter, object, XmlQualifiedEntity> writer, Func <XmlReader, Type, object> reader, Func <Type, bool> secondaryCanConvertPredicate, XmlQualifiedEntity rootName)
 {
     RootName            = rootName;
     ObjectType          = objectType;
     Writer              = writer;
     Reader              = reader;
     CanConvertPredicate = secondaryCanConvertPredicate;
 }
Exemple #4
0
        /// <summary>
        /// Creates and returns a chunked sequence of <see cref="XmlReader"/> objects with a maximum of the specified <paramref name="size"/> of XML node elements located on a depth of 1.
        /// </summary>
        /// <param name="reader">The <see cref="XmlReader"/> object that contains the XML data to chunk into smaller <see cref="XmlReader"/> objects for a batch run or similar.</param>
        /// <param name="size">The amount of XML node elements allowed per <see cref="XmlReader"/> object. Default is 128 XML node element.</param>
        /// <param name="setup">The <see cref="XmlWriterSettings"/> which need to be configured.</param>
        /// <returns>An sequence of <see cref="XmlReader"/> objects that contains no more than the specified <paramref name="size"/> of XML node elements from the <paramref name="reader" /> object.</returns>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="reader"/> is null.
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// The <see cref="XmlReader.Read"/> method of the <paramref name="reader"/> object has already been called.
        /// </exception>
        public static IEnumerable <XmlReader> Chunk(XmlReader reader, int size, Action <XmlWriterSettings> setup = null)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            if (reader.ReadState != ReadState.Initial)
            {
                throw new ArgumentException("The Read method of the XmlReader object has already been called.", nameof(reader));
            }
            List <XmlReader>  outerReaders   = new List <XmlReader>();
            XmlReaderSettings readerSettings = reader.Settings;

            if (MoveToFirstElement(reader))
            {
                XmlQualifiedEntity rootElement  = new XmlQualifiedEntity(reader.Prefix, reader.LocalName, reader.NamespaceURI);
                List <XmlReader>   innerReaders = new List <XmlReader>();
                Stream             result;
                while (reader.Read())
                {
                    if (reader.Depth > 1)
                    {
                        continue;
                    }
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        XPathDocument  document  = new XPathDocument(reader.ReadSubtree());
                        XPathNavigator navigator = document.CreateNavigator();
                        innerReaders.Add(navigator.ReadSubtree());
                        break;
                    }

                    if (innerReaders.Count != size)
                    {
                        continue;
                    }

                    result = XmlWriterUtility.CreateXml(ChunkCore, innerReaders, rootElement, setup);
                    outerReaders.Add(XmlReader.Create(result, readerSettings));
                    innerReaders.Clear();
                }

                if (innerReaders.Count > 0)
                {
                    result = XmlWriterUtility.CreateXml(ChunkCore, innerReaders, rootElement, setup);
                    outerReaders.Add(XmlReader.Create(result, readerSettings));
                    innerReaders.Clear();
                }
            }
            return(outerReaders);
        }
        internal static XmlQualifiedEntity LookupXmlStartElement(this IHierarchy <object> node, XmlQualifiedEntity qualifiedRootEntity = null)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (qualifiedRootEntity != null && !qualifiedRootEntity.LocalName.IsNullOrWhiteSpace())
            {
                return(qualifiedRootEntity);
            }
            bool   hasRootAttribute    = TypeUtility.ContainsAttributeType(node.InstanceType, true, typeof(XmlRootAttribute));
            bool   hasElementAttribute = node.HasMemberReference && TypeUtility.ContainsAttributeType(node.MemberReference, typeof(XmlElementAttribute));
            string rootOrElementName   = XmlUtility.SanitizeElementName(node.HasMemberReference ? node.MemberReference.Name : StringConverter.FromType(node.InstanceType, false, true));
            string ns = null;

            if (hasRootAttribute || hasElementAttribute)
            {
                string elementName = null;
                if (hasRootAttribute)
                {
                    XmlRootAttribute rootAttribute = node.InstanceType.GetTypeInfo().GetCustomAttribute <XmlRootAttribute>(true);
                    elementName = rootAttribute.ElementName;
                    ns          = rootAttribute.Namespace;
                }

                if (hasElementAttribute)
                {
                    XmlElementAttribute elementAttribute = node.MemberReference.GetCustomAttribute <XmlElementAttribute>();
                    elementName = elementAttribute.ElementName;
                    ns          = elementAttribute.Namespace;
                }

                if (!string.IsNullOrEmpty(elementName))
                {
                    rootOrElementName = elementName;
                }
            }

            XmlQualifiedEntity instance = node.Instance as XmlQualifiedEntity;

            return(instance ?? new XmlQualifiedEntity(XmlUtility.SanitizeElementName(rootOrElementName), ns));
        }
Exemple #6
0
        private void WriteXmlChildren(XmlWriter writer, IHierarchy <object> node)
        {
            foreach (IHierarchy <object> childNode in node.GetChildren().OrderByXmlAttributes())
            {
                if (childNode.HasXmlIgnoreAttribute())
                {
                    return;
                }

                XmlQualifiedEntity qualifiedEntity = childNode.LookupXmlStartElement();
                if (childNode.HasChildren && TypeUtility.IsComplex(childNode.InstanceType))
                {
                    writer.WriteStartElement(qualifiedEntity.Prefix, qualifiedEntity.LocalName, qualifiedEntity.Namespace);
                }
                WriteXmlNodes(writer, childNode);
                if (childNode.HasChildren && TypeUtility.IsComplex(childNode.InstanceType))
                {
                    writer.WriteEndElement();
                }
            }
        }
Exemple #7
0
 private void WriteXmlChildren(XmlWriter writer, IHierarchy <object> node)
 {
     foreach (IHierarchy <object> childNode in node.GetChildren().OrderByXmlAttributes())
     {
         if (childNode.HasXmlIgnoreAttribute())
         {
             continue;
         }
         if (!childNode.InstanceType.GetTypeInfo().IsValueType&& childNode.Instance == null)
         {
             continue;
         }
         if (childNode.InstanceType.IsEnumerable() && childNode.InstanceType != typeof(string) && !childNode.InstanceType.IsDictionary())
         {
             var i = childNode.Instance as IEnumerable;
             if (i == null || i.Cast <object>().Count() == 0)
             {
                 continue;
             }
         }
         XmlQualifiedEntity qualifiedEntity = childNode.LookupXmlStartElement();
         if (childNode.HasChildren && TypeUtility.IsComplex(childNode.InstanceType))
         {
             writer.WriteStartElement(qualifiedEntity);
         }
         var converter = Converters.FirstOrDefaultWriterConverter(childNode.InstanceType);
         if (converter != null)
         {
             converter.WriteXml(writer, childNode.Instance, qualifiedEntity);
         }
         else
         {
             WriteXmlNodes(writer, childNode);
         }
         if (childNode.HasChildren && TypeUtility.IsComplex(childNode.InstanceType))
         {
             writer.WriteEndElement();
         }
     }
 }
Exemple #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DefaultXmlConverter"/> class.
 /// </summary>
 public DefaultXmlConverter(XmlQualifiedEntity rootName, IList <XmlConverter> converters)
 {
     RootName   = rootName;
     Converters = converters ?? new List <XmlConverter>();
 }
Exemple #9
0
 private static void ChunkCore(XmlWriter writer, IEnumerable <XmlReader> readers, XmlQualifiedEntity rootElement)
 {
     if (readers == null)
     {
         throw new ArgumentNullException(nameof(readers));
     }
     if (writer == null)
     {
         throw new ArgumentNullException(nameof(writer));
     }
     writer.WriteStartElement(rootElement.Prefix, rootElement.LocalName, rootElement.Namespace);
     foreach (XmlReader reader in readers)
     {
         try
         {
             writer.WriteNode(reader, true);
         }
         finally
         {
             reader.Dispose();
         }
     }
     writer.WriteEndDocument();
 }
Exemple #10
0
 private static void WriteXmlRootElementCore(XmlWriter writer, object value, Action <XmlWriter, object> treeWriterPublic, Action <XmlWriter, IHierarchy <object> > treeWriterInternal, XmlQualifiedEntity rootEntity = null)
 {
     Validator.ThrowIfNull(writer, nameof(writer));
     Validator.ThrowIfNull(value, nameof(value));
     try
     {
         IHierarchy <object> nodes;
         XmlQualifiedEntity  rootElement;
         if (treeWriterInternal == null)
         {
             nodes       = new Hierarchy <object>().Add(value);
             rootElement = nodes.LookupXmlStartElement(rootEntity);
             writer.WriteStartElement(rootElement.Prefix, rootElement.LocalName, rootElement.Namespace);
             treeWriterPublic?.Invoke(writer, value);
         }
         else
         {
             nodes       = new HierarchySerializer(value).Nodes;
             rootElement = nodes.LookupXmlStartElement(rootEntity);
             writer.WriteStartElement(rootElement.Prefix, rootElement.LocalName, rootElement.Namespace);
             treeWriterInternal(writer, nodes);
         }
     }
     catch (Exception ex)
     {
         Exception innerException = ex;
         if (innerException is OutOfMemoryException)
         {
             throw;
         }
         if (innerException is TargetInvocationException)
         {
             innerException = innerException.InnerException;
         }
         throw ExceptionUtility.Refine(new InvalidOperationException("There is an error in the XML document.", innerException), MethodBaseConverter.FromType(typeof(XmlWriterExtensions), flags: ReflectionUtility.BindingInstancePublicAndPrivateNoneInheritedIncludeStatic), writer, value).Unwrap();
     }
     writer.WriteEndElement();
     writer.Flush();
 }
        /// <summary>
        /// Creates a dynamic instance of an <see cref="XmlConverter" /> implementation wrapping <see cref="XmlConverter.WriteXml" /> through <paramref name="writer" /> and <see cref="XmlConverter.ReadXml" /> through <paramref name="reader" />.
        /// </summary>
        /// <typeparam name="T">The type to implement an <see cref="XmlConverter" />.</typeparam>
        /// <param name="writer">The delegate that converts <typeparamref name="T" /> to its XML representation.</param>
        /// <param name="reader">The delegate that generates <typeparamref name="T" /> from its XML representation.</param>
        /// <param name="canConvertPredicate">The predicate that determines if an <see cref="XmlConverter"/> can convert.</param>
        /// <param name="rootEntity">The optional <seealso cref="XmlQualifiedEntity"/> that will provide the name of the root element.</param>
        /// <returns>An <see cref="XmlConverter" /> implementation of <typeparamref name="T" />.</returns>
        public static XmlConverter Create <T>(Action <XmlWriter, T, XmlQualifiedEntity> writer = null, Func <XmlReader, Type, T> reader = null, Func <Type, bool> canConvertPredicate = null, XmlQualifiedEntity rootEntity = null)
        {
            var castedWriter = writer == null ? (Action <XmlWriter, object, XmlQualifiedEntity>)null : (w, t, q) => writer(w, (T)t, q);
            var castedReader = reader == null ? (Func <XmlReader, Type, object>)null : (r, t) => reader(r, t);

            return(Create(typeof(T), castedWriter, castedReader, canConvertPredicate, rootEntity));
        }
Exemple #12
0
 /// <summary>
 /// Writes the specified <paramref name="value"/> with the delegate <paramref name="nodeWriter"/>.
 /// If <paramref name="elementName"/> is not null, then the delegate <paramref name="nodeWriter"/> is called from within an encapsulating Start- and End-element.
 /// </summary>
 /// <typeparam name="T">The type of the object to serialize.</typeparam>
 /// <param name="writer">The writer used in the serialization process.</param>
 /// <param name="value">The object to serialize.</param>
 /// <param name="elementName">The optional fully qualified name of the element.</param>
 /// <param name="nodeWriter">The delegate node writer.</param>
 public static void WriteEncapsulatingElementIfNotNull <T>(this XmlWriter writer, T value, XmlQualifiedEntity elementName, Action <XmlWriter, T> nodeWriter)
 {
     if (elementName == null)
     {
         nodeWriter(writer, value);
         return;
     }
     writer.WriteStartElement(elementName);
     nodeWriter(writer, value);
     writer.WriteEndElement();
 }
Exemple #13
0
 /// <summary>
 /// Writes the specified start tag and associates it with the given <paramref name="elementName"/>.
 /// </summary>
 /// <param name="writer">The writer used in the serialization process.</param>
 /// <param name="elementName">The fully qualified name of the element.</param>
 public static void WriteStartElement(this XmlWriter writer, XmlQualifiedEntity elementName)
 {
     writer.WriteStartElement(elementName.Prefix, elementName.LocalName, elementName.Namespace);
 }
Exemple #14
0
        private void WriteXmlEnumerable(XmlWriter writer, IHierarchy <object> current, bool skipStartElement = false)
        {
            Type currentType = current.InstanceType;

            Type[] genericParameters = currentType.GetGenericArguments();
            if (genericParameters.Length == 0)
            {
                genericParameters = null;
            }
            if (TypeUtility.IsEnumerable(currentType) && currentType != typeof(string))
            {
                bool        isDictionary = TypeUtility.IsDictionary(currentType);
                IEnumerable enumerable   = current.Instance as IEnumerable;
                if (enumerable != null)
                {
                    var list = enumerable.Cast <object>().ToList();
                    if (!skipStartElement && !current.HasChildren && list.Count > 0)
                    {
                        XmlQualifiedEntity qualifiedEntity = null;
                        if (!current.InstanceType.HasAttributes(typeof(XmlRootAttribute)) && current.MemberReference == null)
                        {
                            qualifiedEntity = new XmlQualifiedEntity(StringConverter.FromType(current.InstanceType, false, true).SanitizeElementName());
                        }
                        qualifiedEntity = current.LookupXmlStartElement(qualifiedEntity);
                        writer.WriteStartElement(qualifiedEntity.Prefix, qualifiedEntity.LocalName, qualifiedEntity.Namespace);
                    }
                    IEnumerator         enumerator     = list.GetEnumerator();
                    IHierarchy <object> enumeratorNode = new Hierarchy <object>();
                    enumeratorNode.Add(enumerator);
                    while (enumerator.MoveNext())
                    {
                        object value = enumerator.Current;
                        if (value == null)
                        {
                            continue;
                        }
                        writer.WriteStartElement(EnumerableElementName);
                        Type valueType = value.GetType();

                        if (isDictionary)
                        {
                            PropertyInfo keyProperty   = valueType.GetProperty("Key");
                            PropertyInfo valueProperty = valueType.GetProperty("Value");
                            object       keyValue      = keyProperty.GetValue(value, null) ?? "null";
                            object       valueValue    = valueProperty.GetValue(value, null) ?? "null";
                            var          kvpWrapper    = DynamicXmlSerializable.Create(new[] { keyValue, valueValue }, (xmlWriter, o) =>
                            {
                                var k = o[0];
                                var v = ReflectionUtility.GetObjectHierarchy(o[1], options => options.MaxDepth = 0);
                                v.Data.Add("enumerableCaller", true);
                                writer.WriteAttributeString("key", k.ToString());

                                XmlQualifiedEntity qualifiedEntity = null;
                                if (genericParameters != null && genericParameters.Length > 0)
                                {
                                    qualifiedEntity = new XmlQualifiedEntity(StringConverter.FromType(genericParameters.Last(), false, true).SanitizeElementName());
                                }

                                qualifiedEntity = v.LookupXmlStartElement(qualifiedEntity);
                                writer.WriteStartElement(qualifiedEntity.Prefix, qualifiedEntity.LocalName, qualifiedEntity.Namespace);
                                WriteXmlNodes(writer, v);
                                writer.WriteEndElement();
                            });
                            WriteXmlNodes(writer, ReflectionUtility.GetObjectHierarchy(kvpWrapper, options => options.MaxDepth = 0));
                        }
                        else
                        {
                            IHierarchy <object> itemNode = ReflectionUtility.GetObjectHierarchy(value, options => options.MaxDepth = 0);
                            itemNode.Data.Add("enumerableCaller", true);

                            XmlQualifiedEntity qualifiedEntity = null;

                            if (genericParameters != null && genericParameters.Length > 0)
                            {
                                qualifiedEntity = new XmlQualifiedEntity(StringConverter.ToDelimitedString(genericParameters, "And", StringConverter.FromType));
                            }

                            qualifiedEntity = itemNode.LookupXmlStartElement(qualifiedEntity);
                            writer.WriteStartElement(qualifiedEntity.Prefix, qualifiedEntity.LocalName, qualifiedEntity.Namespace);
                            WriteXmlNodes(writer, itemNode);
                            writer.WriteEndElement();
                        }
                        writer.WriteEndElement();
                    }
                    if (!skipStartElement && !current.HasChildren && list.Count > 0)
                    {
                        writer.WriteEndElement();
                    }
                }
            }
        }
 /// <summary>
 /// Creates a dynamic instance of an <see cref="XmlConverter" /> implementation wrapping <see cref="XmlConverter.WriteXml" /> through <paramref name="writer" /> and <see cref="XmlConverter.ReadXml" /> through <paramref name="reader" />.
 /// </summary>
 /// <param name="objectType">The type of the object to make convertible.</param>
 /// <param name="writer">The delegate that converts an object to its XML representation.</param>
 /// <param name="reader">The delegate that generates an object from its XML representation.</param>
 /// <param name="canConvertPredicate">The predicate that determines if an <see cref="XmlConverter" /> can convert.</param>
 /// <param name="rootEntity">The optional <seealso cref="XmlQualifiedEntity"/> that will provide the name of the root element.</param>
 /// <returns>An <see cref="XmlConverter" /> implementation of an object.</returns>
 public static XmlConverter Create(Type objectType, Action <XmlWriter, object, XmlQualifiedEntity> writer = null, Func <XmlReader, Type, object> reader = null, Func <Type, bool> canConvertPredicate = null, XmlQualifiedEntity rootEntity = null)
 {
     return(new DynamicXmlConverterCore(objectType, writer, reader, canConvertPredicate, rootEntity));
 }
Exemple #16
0
 /// <summary>
 /// Writes the XML root element to an existing <paramref name="writer"/>.
 /// </summary>
 /// <typeparam name="T">The type of the object to serialize.</typeparam>
 /// <param name="writer">The writer used in the serialization process.</param>
 /// <param name="value">The object to serialize.</param>
 /// <param name="treeWriter">The delegate used to write the XML hierarchy.</param>
 /// <param name="rootEntity">The optional <seealso cref="XmlQualifiedEntity"/> that will provide the name of the root element.</param>
 public static void WriteXmlRootElement <T>(this XmlWriter writer, T value, Action <XmlWriter, T, XmlQualifiedEntity> treeWriter, XmlQualifiedEntity rootEntity = null)
 {
     WriteXmlRootElementCore(writer, value, (w, o) => treeWriter(w, value, rootEntity), null, rootEntity);
 }
Exemple #17
0
 /// <summary>
 /// Converts an object into its XML representation.
 /// </summary>
 /// <param name="writer">The <see cref="XmlWriter" /> stream to which the object is serialized.</param>
 /// <param name="value">The object to convert.</param>
 /// <param name="elementName">The element name to encapsulate around <paramref name="value" />.</param>
 /// <exception cref="InvalidOperationException">There is an error in the XML document.</exception>
 public override void WriteXml(XmlWriter writer, object value, XmlQualifiedEntity elementName = null)
 {
     writer.WriteXmlRootElement(value, WriteXmlNodes, elementName ?? RootName);
 }
Exemple #18
0
 internal static void WriteXmlRootElement(this XmlWriter writer, object value, Action <XmlWriter, IHierarchy <object> > treeWriter, XmlQualifiedEntity rootEntity = null)
 {
     WriteXmlRootElementCore(writer, value, null, treeWriter, rootEntity);
 }
Exemple #19
0
 /// <summary>
 /// Inserts an XML converter to the list at the specified <paramref name="index" />.
 /// </summary>
 /// <typeparam name="T">The type of the object to converts to and from XML.</typeparam>
 /// <param name="converters">The list of XML converters.</param>
 /// <param name="index">The zero-based index at which an XML converter should be inserted.</param>
 /// <param name="writer">The delegate that converts <typeparamref name="T" /> to its XML representation.</param>
 /// <param name="reader">The delegate that generates <typeparamref name="T" /> from its XML representation.</param>
 /// <param name="canConvertPredicate">The delegate that determines if an object can be converted.</param>
 /// <param name="qe">The optional <seealso cref="XmlQualifiedEntity"/> that will provide the name of the root element.</param>
 public static void InsertXmlConverter <T>(this IList <XmlConverter> converters, int index, Action <XmlWriter, T, XmlQualifiedEntity> writer = null, Func <XmlReader, Type, T> reader = null, Func <Type, bool> canConvertPredicate = null, XmlQualifiedEntity qe = null)
 {
     converters.Insert(index, DynamicXmlConverter.Create(writer, reader, canConvertPredicate, qe));
 }
 /// <summary>
 /// Writes the XML representation of the <paramref name="value" />.
 /// </summary>
 /// <param name="writer">The <see cref="XmlWriter" /> to write to.</param>
 /// <param name="value">The object to serialize.</param>
 /// <param name="elementName">The element name to encapsulate around <paramref name="value"/>.</param>
 public abstract void WriteXml(XmlWriter writer, object value, XmlQualifiedEntity elementName = null);