C# 不带xsd.exe的XML序列化和模式
我使用XML序列化读取配置POCO 要在VisualStudio中获得对XML文件的intellisense支持,我需要一个模式文件。我可以用xsd.exe mylibrary.dll创建模式,这很好C# 不带xsd.exe的XML序列化和模式,c#,xml-serialization,C#,Xml Serialization,我使用XML序列化读取配置POCO 要在VisualStudio中获得对XML文件的intellisense支持,我需要一个模式文件。我可以用xsd.exe mylibrary.dll创建模式,这很好 但是,如果我将对象序列化到文件系统,我希望始终创建模式。有没有不使用xsd.exe的方法?看看这个类。我记不起确切的细节,但该名称空间中有足够的功能来满足您的要求。谢谢,这对我来说是正确的方式。 解决方案: XmlReflectionImporter importer = new XmlRefle
但是,如果我将对象序列化到文件系统,我希望始终创建模式。有没有不使用xsd.exe的方法?看看这个类。我记不起确切的细节,但该名称空间中有足够的功能来满足您的要求。谢谢,这对我来说是正确的方式。 解决方案:
XmlReflectionImporter importer = new XmlReflectionImporter();
XmlSchemas schemas = new XmlSchemas();
XmlSchemaExporter exporter = new XmlSchemaExporter(schemas);
Type type = toSerialize.GetType();
XmlTypeMapping map = importer.ImportTypeMapping(type);
exporter.ExportTypeMapping(map);
TextWriter tw = new StreamWriter(fileName + ".xsd");
schemas[0].Write(tw);
tw.Close();
上面由Will发布的解决方案工作得非常好,只是我意识到生成的模式没有反映不同类成员上的属性。例如,使用序列化提示属性修饰的类(请参见下面的示例)将无法正确呈现
public class Test
{
[XmlAttribute()]
public string Attribute { get; set; }
public string Description { get; set; }
[XmlArray(ElementName = "Customers")]
[XmlArrayItem(ElementName = "Customer")]
public List<CustomerClass> blah { get; set; }
}
公共类测试
{
[XmlAttribute()]
公共字符串属性{get;set;}
公共字符串说明{get;set;}
[XmlArray(ElementName=“客户”)]
[XmlArrayItem(ElementName=“客户”)]
公共列表blah{get;set;}
}
为了解决这个问题,我创建了几个助手函数,这些函数使用反射遍历类层次结构,读取属性,并填充可以传递到XmlReflectionImporter的XmlAttributeOverrides对象
public static void AttachXmlAttributes(XmlAttributeOverrides xao, Type t)
{
List<Type> types = new List<Type>();
AttachXmlAttributes(xao, types, t);
}
public static void AttachXmlAttributes(XmlAttributeOverrides xao, List<Type> all, Type t)
{
if(all.Contains(t))
return;
else
all.Add(t);
XmlAttributes list1 = GetAttributeList(t.GetCustomAttributes(false));
xao.Add(t, list1);
foreach (var prop in t.GetProperties())
{
XmlAttributes list2 = GetAttributeList(prop.GetCustomAttributes(false));
xao.Add(t, prop.Name, list2);
AttachXmlAttributes(xao, all, prop.PropertyType);
}
}
private static XmlAttributes GetAttributeList(object[] attributes)
{
XmlAttributes list = new XmlAttributes();
foreach (var attribute in attributes)
{
Type type = attribute.GetType();
if (type.Name == "XmlAttributeAttribute") list.XmlAttribute = (XmlAttributeAttribute)attribute;
else if (type.Name == "XmlArrayAttribute") list.XmlArray = (XmlArrayAttribute)attribute;
else if (type.Name == "XmlArrayItemAttribute") list.XmlArrayItems.Add((XmlArrayItemAttribute)attribute);
}
return list;
}
public static string GetSchema<T>()
{
XmlAttributeOverrides xao = new XmlAttributeOverrides();
AttachXmlAttributes(xao, typeof(T));
XmlReflectionImporter importer = new XmlReflectionImporter(xao);
XmlSchemas schemas = new XmlSchemas();
XmlSchemaExporter exporter = new XmlSchemaExporter(schemas);
XmlTypeMapping map = importer.ImportTypeMapping(typeof(T));
exporter.ExportTypeMapping(map);
using (MemoryStream ms = new MemoryStream())
{
schemas[0].Write(ms);
ms.Position = 0;
return new StreamReader(ms).ReadToEnd();
}
}
publicstaticvoidattachxmldattributes(xmldattributeoverridesxao,类型t)
{
列表类型=新列表();
AttachXmlAttributes(xao、类型、t);
}
公共静态void AttachXmlAttributes(XmlAttributeOverrides xao,List all,类型t)
{
如果(全部包含(t))
返回;
其他的
全部。添加(t);
XmlAttributes列表1=GetAttributeList(t.GetCustomAttributes(false));
xao.Add(t,列表1);
foreach(t.GetProperties()中的var prop)
{
XmlAttributes列表2=GetAttributeList(prop.GetCustomAttributes(false));
xao.Add(t,prop.Name,list2);
AttachXmlAttributes(xao、all、prop.PropertyType);
}
}
私有静态XmlAttributes GetAttributeList(对象[]属性)
{
XmlAttributes列表=新的XmlAttributes();
foreach(属性中的var属性)
{
Type Type=attribute.GetType();
if(type.Name==“XmlAttributeAttribute”)list.XmlAttribute=(XmlAttributeAttribute)属性;
else if(type.Name==“XmlArrayAttribute”)list.XmlArray=(XmlArrayAttribute)属性;
else if(type.Name==“XmlArrayItemAttribute”)list.XmlArrayItems.Add((XmlArrayItemAttribute)属性);
}
退货清单;
}
公共静态字符串GetSchema()
{
XmlAttributeOverrides xao=新的XmlAttributeOverrides();
AttachXmlAttributes(xao,typeof(T));
XmlReflectionImporter导入器=新的XmlReflectionImporter(xao);
XmlSchemas=新的XmlSchemas();
XmlSchemaExporter exporter=新的XmlSchemaExporter(模式);
XmlTypeMapping map=importer.ImportTypeMapping(typeof(T));
exporter.ExportTypeMapping(地图);
使用(MemoryStream ms=new MemoryStream())
{
架构[0]。写入(毫秒);
ms.Position=0;
返回新的StreamReader(ms).ReadToEnd();
}
}
希望这对其他人有所帮助。对Matt Murrell版本的改进:对嵌套属性用户类型(例如CustomerClass属性)递归应用XmlAttributes
private static void attachxmldattributes(xmldattributeoverrides xao,List all,Type t)
{
如果(全部包含(t))
{
返回;
}
其他的
{
全部。添加(t);
}
var list1=GetAttributeList(t.GetCustomAttributes(false));
xao.Add(t,列表1);
foreach(t.GetProperties()中的var prop)
{
var propType=prop.PropertyType;
if(propType.IsGenericType)//是列表吗?
{
var args=propType.GetGenericArguments();
if(args!=null&&args.Length==1)
{
var genType=args[0];
if(genType.Name.ToLower()!=“对象”)
{
var list2=GetAttributeList(prop.GetCustomAttributes(false));
xao.Add(t,prop.Name,list2);
AttachXmlAttributes(xao、all、genType);
}
}
}
其他的
{
var list2=GetAttributeList(prop.GetCustomAttributes(false));
xao.Add(t,prop.Name,list2);
AttachXmlAttributes(xao、all、prop.PropertyType);
}
}
}
私有静态XmlAttributes GetAttributeList(对象[]属性)
{
var list=新的XmlAttributes();
foreach(属性中的var attr)
{
Type Type=attr.GetType();
开关(类型.名称)
{
案例“XmlAttributeAttribute”:
list.xmldattribute=(xmldattributeattribute)attr;
打破
案例“XmlRootAttribute”:
list.XmlRoot=(XmlRootAttribute)attr;
打破
案例“XmlElementAttribute”:
list.xmlements.Add((xmlementAttribute)attr);
打破
案例“XmlArrayAttribute”:
list.XmlArray=(XmlArrayAttribute)attr;
打破
案例“XmlArrayItemAttribute”:
list.XmlArrayItems.Add((XmlArrayItemAttribute)attr);
打破
}
}
退货清单;
}
现在我看到您编写了代码,它“看起来”就像我以前做的那样(只是想不起来在哪里!)如何递归地为嵌套属性用户类型应用XmlAttributes?例如CustomerClass?
private static void AttachXmlAttributes(XmlAttributeOverrides xao, List<Type> all, Type t)
{
if (all.Contains(t))
{
return;
}
else
{
all.Add(t);
}
var list1 = GetAttributeList(t.GetCustomAttributes(false));
xao.Add(t, list1);
foreach (var prop in t.GetProperties())
{
var propType = prop.PropertyType;
if (propType.IsGenericType) // is list?
{
var args = propType.GetGenericArguments();
if (args != null && args.Length == 1)
{
var genType = args[0];
if (genType.Name.ToLower() != "object")
{
var list2 = GetAttributeList(prop.GetCustomAttributes(false));
xao.Add(t, prop.Name, list2);
AttachXmlAttributes(xao, all, genType);
}
}
}
else
{
var list2 = GetAttributeList(prop.GetCustomAttributes(false));
xao.Add(t, prop.Name, list2);
AttachXmlAttributes(xao, all, prop.PropertyType);
}
}
}
private static XmlAttributes GetAttributeList(object[] attributes)
{
var list = new XmlAttributes();
foreach (var attr in attributes)
{
Type type = attr.GetType();
switch (type.Name)
{
case "XmlAttributeAttribute":
list.XmlAttribute = (XmlAttributeAttribute)attr;
break;
case "XmlRootAttribute":
list.XmlRoot = (XmlRootAttribute)attr;
break;
case "XmlElementAttribute":
list.XmlElements.Add((XmlElementAttribute)attr);
break;
case "XmlArrayAttribute":
list.XmlArray = (XmlArrayAttribute)attr;
break;
case "XmlArrayItemAttribute":
list.XmlArrayItems.Add((XmlArrayItemAttribute)attr);
break;
}
}
return list;
}