J'ai rencontré un problème et je me suis demandé s'il y avait une façon simple de le résoudre.Sérialiser une liste <string> et utiliser chaque chaîne comme xml Noeud
Ici, j'ai un modèle XML, définissant certaines propriétés et leurs valeurs.
<Properties>
<Property name="ID">10000</Property>
<Property name="Name">
<SubProperty name="FirstName">Foo</SubProperty>
<SubProperty name="LastName">Bar</SubProperty >
</Property>
</Properties>
Tout ce que je ce qui est d'extraire les propriétés/sous-propriétés définies dans le modèle pour générer un nouveau fichier XML, avec toutes les valeurs attachées, quelque chose comme
<Items>
<ID>10000</ID>
<Name>
<FirstName>Foo</FirstName>
<LastName>Bar</LastName>
</Name>
</Items>
Depuis que je ne connais pas le contenu du modèle lors de la conception, j'ai essayé de le charger et de créer une classe List en utilisant LINQ, mais je ne peux pas obtenir le résultat ci-dessus quand je le sérialise directement. Ainsi, au lieu de créer une classe List, j'ai créé un objet dynamique en utilisant Reflection.Emit, puis sérialisé l'objet en XML.
private static readonly XDocument doc = XDocument.Load("Template.xml");
static void Main(string[] args) {
var newType = CreateDynamicType();
var newObject = Activator.CreateInstance(newType);
var properties = newType.GetProperties();
foreach (var property in properties) {
// assign values
}
SerializeToXml(newObject);
}
private static Type CreateDynamicType() {
AssemblyName assemblyName = new AssemblyName() { Name = "DynamicTypeAdapter" };
AssemblyBuilder assembly =
Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder module =
assembly.DefineDynamicModule(assembly.GetName().Name, false);
TypeBuilder type = module.DefineType("Items", TypeAttributes.Public | TypeAttributes.Class);
foreach (var p in doc.Descendants("Property")) {
string pName = p.Attribute("name").Value;
TypeBuilder subType = module.DefineType(pName, TypeAttributes.Public | TypeAttributes.Class);
foreach (var sp in p.Descendants("SubProperty")) {
CreateDynamicProperty(subType, sp.Attribute("name").Value, typeof(string));
}
var propertyType = subType.CreateType();
CreateDynamicProperty(type, pName, propertyType);
}
return type.CreateType();
}
private static void CreateDynamicProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType) {
PropertyBuilder property = typeBuilder.DefineProperty(propertyName,
PropertyAttributes.None, propertyType, new Type[] { typeof(string) });
FieldBuilder field = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
MethodAttributes GetSetAttributes = MethodAttributes.Public | MethodAttributes.HideBySig;
MethodBuilder getMethod =
typeBuilder.DefineMethod("get_value", GetSetAttributes, propertyType, Type.EmptyTypes);
ILGenerator getIL = getMethod.GetILGenerator();
getIL.Emit(OpCodes.Ldarg_0);
getIL.Emit(OpCodes.Ldfld, field);
getIL.Emit(OpCodes.Ret);
MethodBuilder setMethod =
typeBuilder.DefineMethod("set_value", GetSetAttributes, null, new Type[] { typeof(string) });
ILGenerator setIL = setMethod.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldarg_1);
setIL.Emit(OpCodes.Stfld, field);
setIL.Emit(OpCodes.Ret);
property.SetGetMethod(getMethod);
property.SetSetMethod(setMethod);
}
Il fonctionne très bien, mais est-il un moyen simple de le faire? Un commentaire est apprécié. Merci
Vous avez présenté un problème, et certains échantillons XM L, mais j'ai encore du mal à comprendre ce que fait votre code. Pourriez-vous poster un exemple du code que vous avez actuellement? – jrista
Merci pour votre commentaire. J'ai modifié le contenu, désolé pour le code désordonné. – Gnavvy