易于将输出从JSON切换到XML [英] Easy to switch output from JSON to XML
本文介绍了易于将输出从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屋!
查看全文