Amien90 Ответов: 2

Легко переключить вывод с JSON на XML


using (StreamWriter file = File.CreateText(@"c:\test\source.json"))
           {
             JsonSerializer serializer = new JsonSerializer();
            serializer.Serialize(file, eList);
           }


Я использую это, чтобы написать мой JSON-объект в JSON-файл. Но легко ли с помощью некоторого аналогичного кода записать объект в XML вместо этого?

Спасибо заранее

Что я уже пробовал:

искал альтернативу для Newtonsoft.Json

2 Ответов

Рейтинг:
5

F-ES Sitecore

System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(eList.GetType());

using (StreamWriter file = File.CreateText(@"c:\test\source.xml"))
{
    ser.Serialize(file, eList);
}


Вы также можете использовать DataContractSerializer

Класс DataContractSerializer (System. Runtime.Сериализация)[^]


Graeme_Grant

Я упоминаю об этом в своем ответе. Просто оберните его в вспомогательный класс с некоторой дополнительной обработкой. ;)

Скрыть   скопировать код

XmlSerializer serializer = XmlSerializerFactoryNoThrow.Create(typeof(T));


Я хотел сказать, что XML немного более громоздок, чем Json.

Amien90

@F-ES Sitecore. . я получаю эту ошибку:

Необработанное исключение типа ' System.InvalidOperationException ' произошло в System.Xml.dll

Дополнительная информация: произошла ошибка, отражающая тип системы .Коллекции.Универсальный.Список`1[JsonSchema.RootJson]'.

F-ES Sitecore

У вас могут быть свойства объекта, которые не являются сериализуемыми. Убедитесь, что класс помечен как сериализуемый, и вам может понадобиться процесс исключения, чтобы выяснить, какие свойства имеют проблему, но детали исключения могут дать вам ключ к разгадке

http://stackoverflow.com/questions/60573/xmlserializer-there-was-an-error-reflecting-type

Рейтинг:
1

Graeme_Grant

Ответ - и да, и нет. Это зависит от того, как данные должны быть сериализованы.

У меня есть два класса конвертеров, один для JSON и один для XML. Оба они называются одинаково,поэтому их легко переключить.

Я опубликую и то, и другое ниже. Версия XML содержит дополнительную информацию,которая должна быть понятной.

JSON с использованием newtownsoft lib


using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;

namespace DotNet.Shared.Helpers
{
    public static class JsonConverter
    {
        public static string FromClass<T>(T data, bool isEmptyToNull = false, JsonSerializerSettings jsonSettings = null)
        {
            string response = string.Empty;

            if (!EqualityComparer<T>.Default.Equals(data, default(T)))
                response = JsonConvert.SerializeObject(data, jsonSettings);

            return isEmptyToNull ? (response == "{}" ? "null" : response) : response;
        }

        public static MemoryStream FromClassToStream<T>(T data, StreamWriter writer, bool isEmptyToNull = false, JsonSerializerSettings jsonSettings = null)
        {
            var stream = new MemoryStream();

            if (!EqualityComparer<T>.Default.Equals(data, default(T)))
            {
                writer = new StreamWriter(stream);
                writer.Write(FromClass(data, isEmptyToNull, jsonSettings));
                writer.Flush();
                stream.Position = 0;
            }
            return stream;
        }

        public static T ToClass<T>(string data, JsonSerializerSettings jsonSettings = null)
        {
            var response = default(T);

            if (!string.IsNullOrEmpty(data))
                response = jsonSettings == null 
                    ? JsonConvert.DeserializeObject<T>(data) 
                    : JsonConvert.DeserializeObject<T>(data, jsonSettings);

                return response;
        }

        public static T ToClassFromStream<T>(MemoryStream stream)
        {
            var response = default(T);

            if (stream != null)
            {
                using (var reader = new StreamReader(stream))
                    using (var jsonReader = new JsonTextReader(reader))
                        response = (new JsonSerializer()).Deserialize<T>(jsonReader);
            }
            return response;
        }
    }
}

XML с помощью Microsoft библиотеки


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace WorkingWithXml
{
    class Program
    {
        static void Main(string[] args)
        {
            var data = new XmlRootClass
            {
                Id = 12345567890123456789,
                Title = "Widget",
                Amount = new AmountType { Value = 123.45, CurrencyID = CurrencyCodeType.USD },
                Description = new CData("This is a description with embedded html"),
            };

            var raw = XmlConverter.FromClass(data);

            var newData = XmlConverter.ToClass<XmlRootClass>(raw);

            Debugger.Break();
        }
    }


    // Naming a root element
    [XmlRoot(ElementName = "Product", IsNullable = false)]
    public class XmlRootClass
    {
        [XmlElement("id123)")]
        public ulong Id { get; set; }
        public string Title { get; set; }

        // a value type element with an attribute
        [XmlElement("amt")]
        public AmountType Amount { get; set; }

        // Custom element data format
        [XmlElement("description", typeof(CData))]
        public CData Description { get; set; }

        // example of optional serialization
        [XmlElement, DefaultValue(false)]
        public bool IsAvailable { get; set; }

    }

    public class AmountType
    {
        [XmlText]
        public double Value { get; set; }

        //enum type attribute (same works with an XmlElement)
        [XmlAttribute("currencyID")]
        public string CurrencyID_intern { get; set; }
        [XmlIgnore]
        public CurrencyCodeType? CurrencyID
        {
            get
            {
                return CurrencyID_intern.StringToEnum<CurrencyCodeType?>
                  (CurrencyCodeType.CustomCode, isNullable: true);
            }
            set { CurrencyID_intern = value.ToString(); }
        }
    }

    public enum CurrencyCodeType
    {
        CustomCode, // missing from list
        AUD,        // Australia dollar
        JPY,        // Japanese yen
        USD,        // US dollar
    }

    public static class EnumExtensions
    {
        public static T StringToEnum<T>(this string input, T defaultValue = default(T), bool isNullable = false)
        {
            T outType;
            if (string.IsNullOrEmpty(input) &&
                isNullable &&
                Nullable.GetUnderlyingType(typeof(T)) != null &&
                Nullable.GetUnderlyingType(typeof(T)).GetElementType() == null)
                return default(T);
            return input.EnumTryParse(out outType) ? outType : defaultValue;
        }

        public static bool EnumTryParse<T>(this string input, out T theEnum)
        {
            Type type = Nullable.GetUnderlyingType(typeof(T)) != null ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T);

            foreach (string en in Enum.GetNames(type))
                if (en.Equals(input, StringComparison.CurrentCultureIgnoreCase))
                {
                    theEnum = (T)Enum.Parse(type, input, true);
                    return true;
                }
            theEnum = default(T);
            return false;
        }
    }

    public static class XmlConverter
    {
        public static string FromClass<T>(T data, XmlSerializerNamespaces ns = null)
        {
            string response = string.Empty;

            var ms = new MemoryStream();
            try
            {
                ms = FromClassToStream(data, ns);

                if (ms != null)
                {
                    ms.Position = 0;
                    using (var sr = new StreamReader(ms))
                        response = sr.ReadToEnd();
                }

            }
            finally
            {
                // don't want memory leaks...
                ms.Flush();
                ms.Dispose();
                ms = null;
            }

            return response;
        }

        public static MemoryStream FromClassToStream<T>(T data, XmlSerializerNamespaces ns = null)
        {
            var stream = default(MemoryStream);

            if (!EqualityComparer<T>.Default.Equals(data, default(T)))
            {
                var settings = new XmlWriterSettings()
                {
                    Encoding = Encoding.UTF8,
                    Indent = true,
                    ConformanceLevel = ConformanceLevel.Auto,
                    CheckCharacters = true,
                    OmitXmlDeclaration = false
                };

                XmlSerializer serializer = XmlSerializerFactoryNoThrow.Create(typeof(T));

                stream = new MemoryStream();
                using (XmlWriter writer = XmlWriter.Create(stream, settings))
                {
                    serializer.Serialize(writer, data, ns);
                    writer.Flush();
                }
                stream.Position = 0;
            }
            return stream;
        }

        public static T ToClass<T>(string data)
        {
            var response = default(T);

            if (!string.IsNullOrEmpty(data))
            {
                var settings = new XmlReaderSettings() { IgnoreWhitespace = true };

                XmlSerializer serializer = XmlSerializerFactoryNoThrow.Create(typeof(T));

                XmlReader reader = XmlReader.Create(new StringReader(data), settings);
                response = (T)Convert.ChangeType(serializer.Deserialize(reader), typeof(T));
            }
            return response;
        }
    }

    // ref: http://stackoverflow.com/questions/1127431/xmlserializer-giving-filenotfoundexception-at-constructor/39642834#39642834
    public static class XmlSerializerFactoryNoThrow
    {
        public static Dictionary<Type, XmlSerializer> cache = new Dictionary<Type, XmlSerializer>();

        private static object SyncRootCache = new object();

        public static XmlSerializer Create(Type type)
        {
            XmlSerializer serializer;

            lock (SyncRootCache)
                if (cache.TryGetValue(type, out serializer))
                    return serializer;

            lock (type) //multiple variable of type of one type is same instance
            {
                //constructor XmlSerializer.FromTypes does not throw the first chance exception           
                serializer = XmlSerializer.FromTypes(new[] { type })[0];
            }

            lock (SyncRootCache) cache[type] = serializer;
            return serializer;
        }
    }

    // ref: http://codercorner.blogspot.com.au/2006/11/serialization-and-cdata.html
    public class CData : IXmlSerializable
    {
        public CData()
        { }

        public CData(string text)
        {
            this.text = text;
        }

        private string text;
        public string Text => text;

        XmlSchema IXmlSerializable.GetSchema() => null;

        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            text = reader.ReadElementContentAsString();
            reader.Read(); // without this line, you will lose value of all other fields
        }

        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            writer.WriteCData(text);
        }

        public override string ToString() => text;