write read node leer ejemplo create crear c# xml

read - xml c# ejemplo



C#: creación de instancias de clases de XML (8)

Lo que tengo es una colección de clases que implementan la misma interfaz pero que pueden ser bastante diferentes bajo el capó. Quiero tener un control de archivo de configuración que de las clases va a la colección al iniciar el programa, tomando algo que se ve así:

<class1 prop1="foo" prop2="bar"/>

y convirtiendo eso en:

blah = new class1(); blah.prop1="foo"; blah.prop2="bar";

De una manera muy genérica Lo que no sé hacer es tomar la cadena prop1 en el archivo de configuración y convertirla en el prop1 a la propiedad en el código. ¿Hay alguna meta-programación en C # para permitir eso?


Puede ser más fácil serializar las clases a / desde xml, simplemente puede pasar el XmlReader (que está leyendo su archivo de configuración) al deserializador y hará el resto por usted.

Este es un buen artículo sobre serialización

Editar

Una cosa que me gustaría añadir, aunque la reflexión sea poderosa, requiere que sepas algunas cosas sobre el tipo, como parámetros, etc.

Serializar a XML no necesita nada de eso, y aún puede tener seguridad de tipo al asegurarse de escribir el nombre de tipo completo en el archivo XML, por lo que el mismo tipo se carga automáticamente.


Reflexión es lo que quieres Reflection + TypeConverter. No tienes mucho más tiempo para explicar, solo busca en Google y deberías estar bien encaminado. O simplemente puede usar el serializador xml, pero luego debe adherirse a un formato, pero funciona muy bien.


Un montón de instalaciones de metaprogramación.

Específicamente, puede obtener una referencia al ensamblado que contiene estas clases, y luego obtener fácilmente el Type de clase de su nombre. Ver método Assembly.GetType (String) .

A partir de ahí, puede instanciar la clase usando el Activator o el constructor del Type mismo. Ver Activator.CreateInstance Method .

Una vez que tenga una instancia, puede establecer propiedades de nuevo utilizando el objeto Type . Consulte el método Type.GetProperty y / o el método Type.GetField junto con el método PropertyInfo.SetValue .


La reflexión te permite hacer eso. También puede consultar XML Serialization .

Type type = blah.GetType(); PropertyInfo prop = type.GetProperty("prop1"); prop.SetValue(blah, "foo", null);


Reflection o XML-serialization es lo que estás buscando.

Usando el reflejo, puedes buscar el tipo usando algo como esto

public IYourInterface GetClass(string className) { foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { foreach (Type type in asm.GetTypes()) { if (type.Name == className) return Activator.CreateInstance(type) as IYourInterface; } } return null; }

Tenga en cuenta que esto pasará por todos los ensamblajes. Es posible que desee reducirlo para incluir solo el ensamblaje que se está ejecutando actualmente.

Para asignar valores de propiedades, también usa la reflexión. Algo a lo largo de las líneas de

IYourInterface o = GetClass("class1"); o.GetType().GetProperty("prop1").SetValue(o, "foo", null);

Si bien la reflexión puede ser la solución más flexible, también debe consultar la serialización XML para omitir el trabajo pesado usted mismo.


También sugeriría la serialización de Xml como otros ya han mencionado. Aquí hay una muestra que armé para demostrar. Los atributos se usan para conectar los nombres del Xml a los nombres y tipos de propiedades reales en la estructura de datos. Los atributos también enumeran todos los tipos permitidos que pueden ir a la colección Things . Todo en esta colección debe tener una clase base común. Usted dijo que ya tiene una interfaz común, pero puede que tenga que cambiarla por una clase base abstracta porque este ejemplo de código no funcionó inmediatamente cuando Thing era una interfaz.

using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using System.IO; namespace ConsoleApplication1 { class Program { static void Main() { string xml = "<?xml version=/"1.0/"?>" + "<config>" + "<stuff>" + " <class1 prop1=/"foo/" prop2=/"bar/"></class1>" + " <class2 prop1=/"FOO/" prop2=/"BAR/" prop3=/"42/"></class2>" + "</stuff>" + "</config>"; StringReader sr = new StringReader(xml); XmlSerializer xs = new XmlSerializer(typeof(ThingCollection)); ThingCollection tc = (ThingCollection)xs.Deserialize(sr); foreach (Thing t in tc.Things) { Console.WriteLine(t.ToString()); } } } public abstract class Thing { } [XmlType(TypeName="class1")] public class SomeThing : Thing { private string pn1; private string pn2; public SomeThing() { } [XmlAttribute("prop1")] public string PropertyNumber1 { get { return pn1; } set { pn1 = value; } } [XmlAttribute("prop2")] public string AnotherProperty { get { return pn2; } set { pn2 = value; } } } [XmlType(TypeName="class2")] public class SomeThingElse : SomeThing { private int answer; public SomeThingElse() { } [XmlAttribute("prop3")] public int TheAnswer { get { return answer; } set { answer =value; } } } [XmlType(TypeName = "config")] public class ThingCollection { private List<Thing> things; public ThingCollection() { Things = new List<Thing>(); } [XmlArray("stuff")] [XmlArrayItem(typeof(SomeThing))] [XmlArrayItem(typeof(SomeThingElse))] public List<Thing> Things { get { return things; } set { things = value; } } } }


Creo que puedes utilizar Dynamics aquí. Cree ExpandoObject, se puede usar como diccionario para configurar propiedades de xml config.