我从网站http://www.dotnetcurry.com/ShowArticle.aspx?ID=428
查看他们的代码
class Program
{
static void Main(string[] args)
{
List<Employee> empList = new List<Employee>();
empList.Add(new Employee() { ID = 1, FName = "John", LName = "Shields", DOB = DateTime.Parse("12/11/1971"), Sex = 'M' });
empList.Add(new Employee() { ID = 2, FName = "Mary", LName = "Jacobs", DOB = DateTime.Parse("01/17/1961"), Sex = 'F' });
empList.Add(new Employee() { ID = 3, FName = "Amber", LName = "Agar", DOB = DateTime.Parse("12/23/1971"), Sex = 'M' });
empList.Add(new Employee() { ID = 4, FName = "Kathy", LName = "Berry", DOB = DateTime.Parse("11/15/1976"), Sex = 'F' });
empList.Add(new Employee() { ID = 5, FName = "Lena", LName = "Bilton", DOB = DateTime.Parse("05/11/1978"), Sex = 'F' });
}
}
class Employee
{
public int ID { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public DateTime DOB { get; set; }
public char Sex { get; set; }
}
如果有人看到这个代码区域从列表生成xml,那么必须注意代码不是通用的,而是依赖于List。 我想要一个可以将任何列表转换为xml的通用例程。特别是如果我可以通过扩展方法做。
try
{
var xEle = new XElement("Employees",
from emp in empList
select new XElement("Employee",
new XAttribute("ID", emp.ID),
new XElement("FName", emp.FName),
new XElement("LName", emp.LName),
new XElement("DOB", emp.DOB),
new XElement("Sex", emp.Sex)
));
xEle.Save("D:\\employees.xml");
Console.WriteLine("Converted to XML");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
寻求帮助。感谢
我只是稍微定制ToXml()
,但为什么会抛出错误?任何想法?
public static class utility
{
public static string ToXml<T>(this T obj, string strContainer = "")
{
XmlSerializer serialize = null;
if (strContainer.Trim() == "")
serializer = new XmlSerializer(typeof(T));
else
serializer = new XmlSerializer(typeof(T), new XmlRootAttribute(strContainer));
using (StringWriter sw = new StringWriter())
{
serializer.Serialize(sw, obj);
return sw.ToString();
}
}
}
答案 0 :(得分:1)
看看你是否可以使用这个通用扩展
public static string ToXml<T>(this T obj)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringWriter sw = new StringWriter())
{
serializer.Serialize(sw, obj);
return sw.ToString();
}
}
像
一样使用它var xmlString = empList.ToXml();
使用您的代码生成此XML
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfEmployee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Employee>
<ID>1</ID>
<FName>John</FName>
<LName>Shields</LName>
<DOB>1971-12-11T00:00:00</DOB>
<Sex>77</Sex>
</Employee>
<Employee>
<ID>2</ID>
<FName>Mary</FName>
<LName>Jacobs</LName>
<DOB>1961-01-17T00:00:00</DOB>
<Sex>70</Sex>
</Employee>
</ArrayOfEmployee>
修改强>
使用自定义根元素名称&amp;删除命名空间,使用此重载
public static string ToXml<T>(this T obj, string rootName)
{
XmlSerializer serializer = new XmlSerializer(typeof(T), new XmlRootAttribute(rootName));
var xmlNs = new XmlSerializerNamespaces();
xmlNs.Add(string.Empty, string.Empty);
using (StringWriter sw = new StringWriter())
{
serializer.Serialize(sw, obj, xmlNs);
return sw.ToString();
}
}
哪个产生
<?xml version="1.0" encoding="utf-16"?>
<Employees>
<Employee>
<ID>1</ID>
<FName>John</FName>
<LName>Shields</LName>
<DOB>1971-12-11T00:00:00</DOB>
<Sex>77</Sex>
</Employee>
<Employee>
<ID>2</ID>
<FName>Mary</FName>
<LName>Jacobs</LName>
<DOB>1961-01-17T00:00:00</DOB>
<Sex>70</Sex>
</Employee>
</Employees>
答案 1 :(得分:1)
您可以使用XmlSerializer默认情况下可以序列化公共字段,并可以attributes进行自定义。演示场景的最简单示例如下所示:
static void Main(string[] args)
{
List<Employee> empList = new List<Employee>();
empList.Add(new Employee() { ID = 1, FName = "John", LName = "Shields", DOB = DateTime.Parse("12/11/1971"), Sex = 'M' });
empList.Add(new Employee() { ID = 2, FName = "Mary", LName = "Jacobs", DOB = DateTime.Parse("01/12/1961"), Sex = 'F' });
empList.Add(new Employee() { ID = 3, FName = "Amber", LName = "Agar", DOB = DateTime.Parse("05/12/1971"), Sex = 'M' });
empList.Add(new Employee() { ID = 4, FName = "Kathy", LName = "Berry", DOB = DateTime.Parse("11/06/1976"), Sex = 'F' });
empList.Add(new Employee() { ID = 5, FName = "Lena", LName = "Bilton", DOB = DateTime.Parse("05/11/1978"), Sex = 'F' });
XmlSerializer serializer = new XmlSerializer(empList.GetType());
serializer.Serialize(Console.Out, empList);
Console.ReadKey();
}
此示例将显示下一个结果:
<?xml version="1.0" encoding="cp866"?>
<ArrayOfEmployee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd
="http://www.w3.org/2001/XMLSchema">
<Employee>
<ID>1</ID>
<FName>John</FName>
<LName>Shields</LName>
<DOB>1971-11-12T00:00:00</DOB>
<Sex>77</Sex>
</Employee>
<Employee>
<ID>2</ID>
<FName>Mary</FName>
<LName>Jacobs</LName>
<DOB>1961-12-01T00:00:00</DOB>
<Sex>70</Sex>
</Employee>
<Employee>
<ID>3</ID>
<FName>Amber</FName>
<LName>Agar</LName>
<DOB>1971-12-05T00:00:00</DOB>
<Sex>77</Sex>
</Employee>
<Employee>
<ID>4</ID>
<FName>Kathy</FName>
<LName>Berry</LName>
<DOB>1976-06-11T00:00:00</DOB>
<Sex>70</Sex>
</Employee>
<Employee>
<ID>5</ID>
<FName>Lena</FName>
<LName>Bilton</LName>
<DOB>1978-11-05T00:00:00</DOB>
<Sex>70</Sex>
</Employee>
</ArrayOfEmployee>
通用实现将更简单并基于预期的结果类型。我正在使用此代码:
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace Rikrop.Core.Serialization.Xml
{
public static class XmlSerializers
{
private static readonly ConcurrentDictionary<Type, XmlSerializer> serializers = new ConcurrentDictionary<Type, XmlSerializer>();
private static readonly XmlSerializerNamespaces xns = new XmlSerializerNamespaces();
private static readonly UTF8Encoding defaultEncoding = new UTF8Encoding(false);
static XmlSerializers()
{
xns.Add("", "");
}
private static XmlSerializer GetSerializer(Type type, XmlRootAttribute xmlRoot = null)
{
return serializers.GetOrAdd(type, t => new XmlSerializer(t, xmlRoot));
}
public static byte[] SerializeToBytes<T>(T obj, bool omitXmlDeclaration = true, string customRootName = null, bool omitNamespaces = true, Encoding encoding = null)
{
if (ReferenceEquals(null, obj))
return null;
using (var ms = new MemoryStream())
{
var xmlSettings = new XmlWriterSettings
{
OmitXmlDeclaration = omitXmlDeclaration,
NewLineHandling = NewLineHandling.Entitize,
Indent = true,
Encoding = encoding ?? defaultEncoding
};
using (var xmlWriter = XmlWriter.Create(ms, xmlSettings))
{
var xmlRootNameAttribute = string.IsNullOrEmpty(customRootName) ? null : new XmlRootAttribute(customRootName);
GetSerializer(typeof(T), xmlRootNameAttribute).Serialize(xmlWriter, obj, omitNamespaces ? xns : null);
return ms.ToArray();
}
}
}
public static string Serialize<T>(T obj, bool omitNamespaces = true, Encoding encoding = null, bool omitXmlDeclaration = true, string customRootName = null)
{
var bytes = SerializeToBytes(obj, omitXmlDeclaration, customRootName, omitNamespaces, encoding);
return (encoding ?? defaultEncoding).GetString(bytes);
}
public static string SafeSerialize<T>(T obj, bool omitNamespaces = true, Encoding encoding = null, bool omitXmlDeclaration = true, string customRootName = null)
{
try
{
return Serialize(obj, omitNamespaces, encoding, omitXmlDeclaration, customRootName);
}
catch (Exception e)
{
// log error here
}
return null;
}
public static T SafeDeserialize<T>(byte[] serializedData, Encoding encoding = null, bool silentMode = false)
where T : class
{
try
{
return DeserializeFromBytes<T>(serializedData, encoding);
}
catch (Exception e)
{
if (!silentMode)
{
// log error here
}
}
return null;
}
public static T SafeDeserialize<T>(string serializedData, Encoding encoding = null, bool silentMode = false)
where T : class
{
try
{
return Deserialize<T>(serializedData, encoding);
}
catch (Exception e)
{
if (!silentMode)
{
// log error here
}
}
return null;
}
public static T DeserializeFromBytes<T>(byte[] serializedData, Encoding encoding = null) where T : class
{
using (var sr = new StreamReader(new MemoryStream(serializedData), encoding ?? defaultEncoding))
using (var xmlReader = XmlReader.Create(sr))
return (T) GetSerializer(typeof(T)).Deserialize(xmlReader);
}
public static T Deserialize<T>(string stringData, Encoding encoding = null) where T : class
{
var bytes = (encoding ?? defaultEncoding).GetBytes(stringData);
return DeserializeFromBytes<T>(bytes, encoding);
}
}
}
对于字节数组的序列化我使用上面的简短版本代码:
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace Rikrop.Core.Serialization.Xml
{
public static class XmlSerializers
{
private static readonly ConcurrentDictionary<Type, XmlSerializer> serializers = new ConcurrentDictionary<Type, XmlSerializer>();
private static readonly XmlSerializerNamespaces xnameSpace = new XmlSerializerNamespaces();
private static readonly UTF8Encoding defaultEncoding = new UTF8Encoding(false);
static XmlSerializers()
{
xnameSpace.Add("", "");
}
private static XmlSerializer GetSerializer(Type type)
{
return serializers.GetOrAdd(type, t => new XmlSerializer(t));
}
public static byte[] Serialize(object obj, bool omitNamespaces = false, Encoding encoding = null)
{
if (ReferenceEquals(null, obj))
return null;
using (var stream = new MemoryStream())
{
using (var xmlWriter = XmlWriter.Create(stream, new XmlWriterSettings { OmitXmlDeclaration = false, Encoding = encoding ?? defaultEncoding, Indent = true}))
{
GetSerializer(obj.GetType()).Serialize(xmlWriter, obj, omitNamespaces ? xnameSpace : null);
return stream.ToArray();
}
}
}
public static string SerializeToString(object obj, bool omitNamespaces = false, Encoding encoding = null)
{
var bytes = Serialize(obj, omitNamespaces, encoding);
return (encoding ?? defaultEncoding).GetString(bytes);
}
public static TData Deserialize<TData>(byte[] serializedData, Encoding encoding = null) where TData : class
{
using (var sr = new StreamReader(new MemoryStream(serializedData), encoding ?? defaultEncoding))
using (var xmlReader = XmlReader.Create(sr))
return (TData)GetSerializer(typeof(TData)).Deserialize(xmlReader);
}
public static TData DeserializeFromString<TData>(string stringData, Encoding encoding = null) where TData : class
{
var bytes = (encoding ?? defaultEncoding).GetBytes(stringData);
return Deserialize<TData>(bytes);
}
}
}