易于将输出从JSON切换到XML [英] Easy to switch output from JSON to XML

查看:51
本文介绍了易于将输出从JSON切换到XML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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





我用它来将我的JSON对象写入json文件。但是用一些类似的代码将对象写入XML却很容易吗?



先谢谢了



我尝试了什么:



为Newtonsoft.Json寻找替代方案

解决方案

答案是肯定的,不是。这取决于数据的序列化方式。



我有两个转换器类,一个用于JSON和amp;一个用于XML。两者都被称为相同的方式,因此很容易切换。



我会在下面发布两个。 XML版本的附加信息应该是不言自明的。

JSON使用NewtownSoft lib



 使用 Newtonsoft.Json; 
使用 System.Collections.Generic;
使用 System.IO;

命名空间 DotNet.Shared.Helpers
{
public static class JsonConverter
{
public static string FromClass< T>(T数据, 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>(< span class =code-keyword> 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 响应;
}

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

if (stream!= null
{
使用 var reader = new StreamReader(stream))
使用 var jsonReader = new JsonTextReader(reader))
response =( new JsonSerializer())。反序列化< T>(jsonReader);
}
返回响应;
}
}
}



使用Microsoft Libs的XML



< pre lang =c#> 使用系统;
使用 System.Collections.Generic;
使用 System.ComponentModel;
使用 System.Diagnostics;
使用 System.IO;
使用 System.Text;
使用 System.Xml;
使用 System.Xml.Schema;
使用 System.Xml.Serialization;

命名空间 WorkingWithXml
{
class Program
{
静态 void Main( string [] args)
{
var data = new XmlRootClass
{
Id = 12345567890123456789
Title = < span class =code-string> Widget,
Amount = new AmountType {Value = 123 45 ,CurrencyID = CurrencyCodeType.USD},
说明= new CData( 这是一个嵌入的描述 ded html),
};

var raw = XmlConverter.FromClass(data);

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

Debugger.Break();
}
}


// 命名a根元素
[XmlRoot(ElementName = Product,IsNullable = < span class =code-keyword> false )]
public class XmlRootClass
{
[XmlElement( id123))]
public ulong ID { get ; set ; }
public string 标题{ get ; set ; }

// 具有属性的值类型元素
[XmlElement( amt)]
公开 AmountType金额{ get ; set ; }

// 自定义元素数据格式
[XmlElement( description typeof (CData) )]
public CData说明{ get ; set ; }

// 可选序列化的示例
[XmlElement, DefaultValue( false )]
public bool IsAvailable { get ; set ; }

}

public class AmountType
{
[XmlText]
public double 值{获得; set ; }

// 枚举类型属性(与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, // 列表中缺少
AUD, // 澳元
JPY, // 日元
USD, // 美元
}

public static class EnumExtensions
{
public static T StringToEnum< T>( 字符串输入,T defaultValue = 默认(T), bool isNullable = false
{
T outType;
if string .IsNullOrEmpty(输入)&&
isNullable& ;&
Nullable.GetUnderlyingType( typeof (T))!= null && ;
Nullable.GetUnderlyingType( typeof (T))。GetElementType()== null
return 默认(T);
return input.EnumTryParse( out outType)? outType:defaultValue;
}

public static bool EnumTryParse< T>( 字符串输入, 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 = 默认(T);
return false ;
}
}

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

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

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

}
最后
{
// 不希望内存泄漏......
ms.Flush();
ms.Dispose();
ms = null ;
}

return 响应;
}

public static MemoryStream FromClassToStream< T>(T data,XmlSerializerNamespaces ns = null
{
var stream = 默认(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();
使用(XmlWriter writer = XmlWriter.Create(stream,settings))
{
serializer.Serialize(writer,data,ns );
writer.Flush();
}
stream.Position = 0 ;
}
return stream;
}

public static T ToClass< T>(< span class =code-keyword> string
data)
{
var response = 默认(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));
}
返回响应;
}
}

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

private static object SyncRootCache = new object ();

public static XmlSerializer Create(Type type)
{
XmlSerializer序列化器;

lock (SyncRootCache)
if (cache.TryGetValue( type, out 序列化程序))
return 序列化程序;

lock (type) // 一种类型的多个变量是同一个实例
{
// 构造函数XmlSerializer.FromTypes不会抛出第一次机会异常
serializer = XmlSerializer.FromTypes( new [] {type})[ 0 ];
}

lock (SyncRootCache)cache [type] = serializer;
return 序列化程序;
}
}

// 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(); // 如果没有此行,您将失去所有其他字段的价值
}

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

public 覆盖 字符串 ToString()= > 文字;
}
}


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

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





你也可以使用DataContractSerializer



< a href =https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer(v=vs.110).aspx> DataContractSerializer Class(System.Runtime.Serialization) [ ^ ]


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



I use this to write my JSON Object to a json file. But is it easy with some similar code to write the Object to XML instead?

Thanks in advanced

What I have tried:

looked for an alternative for Newtonsoft.Json

解决方案

The answer is yes and no. It depends on how the data is to be serialized.

I have two Converter classes, one for JSON & one for XML. Both are called the same way, so easy to switch.

I'll post both below. The XML version has additional information that should be self-explanatory.

JSON using 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 using Microsoft Libs


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;
    }
}


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);
}



You can also use DataContractSerializer

DataContractSerializer Class (System.Runtime.Serialization)[^]


这篇关于易于将输出从JSON切换到XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆