2010-05-04 14 views

Respuesta

19

Aquí es una manera hack-ish de hacerlo sin tener que cargar toda la cadena de salida en un XmlDocument:

using System; 
using System.Text; 
using System.Xml; 
using System.Xml.Serialization; 

public class Example 
{ 
    public String Name { get; set; } 

    static void Main() 
    { 
     Example example = new Example { Name = "Foo" }; 

     XmlSerializer serializer = new XmlSerializer(typeof(Example)); 

     XmlSerializerNamespaces emptyNamespace = new XmlSerializerNamespaces(); 
     emptyNamespace.Add(String.Empty, String.Empty); 

     StringBuilder output = new StringBuilder(); 

     XmlWriter writer = XmlWriter.Create(output, 
      new XmlWriterSettings { OmitXmlDeclaration = true }); 
     serializer.Serialize(writer, example, emptyNamespace); 

     Console.WriteLine(output.ToString()); 
    } 
} 
+0

+1 - No creo que sea realmente hackish en absoluto. Tal vez más trabajo de configuración de lo que me gustaría hacer. Pero, al final, le dice qué formato debe tener la salida antes de que haga el trabajo. Eso no es un truco. Un truco sería quitar todo después del hecho, etc. –

+1

Estoy de acuerdo con Andrew en que esto es un hack. A menos que esté haciendo algo mal, todos mis elementos tienen el atributo 'xmlns =' '' '. Hubiera preferido que esto no estuviera presente en absoluto. –

+0

** no manipulaciones XmlDocument/XmlNode ** – Kiquenet

-2
+2

No. Esto producirá un documento XML válido que incluye la declaración XML y las referencias del espacio de nombres. Solo quiero un fragmento – Emmanuel

+0

en mi humilde opinión, mejor borre la respuesta porque no es válida para la pregunta. http://stackoverflow.com/help/how-to-answer – Kiquenet

1

Usted debe ser capaz de serializar al igual que lo hace normalmente, y luego utilizar la propiedad Root del documento resultante.

Es posible que primero tenga que borrar los atributos del elemento.

+1

+1 Me parece bien, pero lo que no explique en mi pregunta es que preferiría producir un flujo y no un XmlDocument. – Emmanuel

0

Por cierto esto es impresionante. Implementé este código para facilitar el trabajo con fragmentos xml como clases rápidamente y luego puedes simplemente reemplazar el nodo cuando haya terminado. Esto hace que la transición entre el código y xml sea muy fácil.

Primero cree algunos métodos de extensión.

public static class SerializableFragmentExtensions 
{ 
    public static XElement ToElement(this ISerializableFragment iSerializableFragment) 
    { 
     var serializer = new XmlSerializer(iSerializableFragment.GetType()); 
     var emptyNamespace = new XmlSerializerNamespaces(); 
     emptyNamespace.Add(String.Empty, String.Empty); 

     var output = new StringBuilder(); 

     var writer = XmlWriter.Create(output, 
      new XmlWriterSettings { OmitXmlDeclaration = true }); 
     serializer.Serialize(writer, iSerializableFragment, emptyNamespace); 
     return XElement.Parse(output.ToString(), LoadOptions.None); 
    } 
    public static T ToObject<T>(this XElement xElement) 
    { 
     var serializer = new XmlSerializer(typeof (T)); 
     var reader = xElement.CreateReader(); 
     var obj = (T) serializer.Deserialize(reader); 
     return obj; 
    } 
} 

Siguiente implementar la interfaz requerida (interfaz de marcador - Te conozco se supone que no, pero creo que esta es la razón perfecta para él.)

public interface ISerializableFragment 
{ 
} 

Ahora todo lo que tiene que hacer es decorar cualquier clase de Serializable, desea convertir a un XElement Fragment, con la interfaz.

[Serializable] 
public class SomeSerializableClass : ISerializableFragment 
{ 
    [XmlAttribute] 
    public string SomeData { get; set; } 
} 

Finalmente, pruebe el código.

static void Main(string[] args) 
    { 
     var someSerializableClassObj = new SomeSerializableClass() {SomeData = "Testing"}; 
     var element = someSerializableClass.ToElement(); 
     var backToSomeSerializableClassObj = element.ToObject<SomeSerializableClass>(); 
    } 

Gracias de nuevo por este código increíblemente útil.

+1

Hubo un problema que tuve inmediatamente al intentar esto en mi propio proyecto. Con un fragmento de texto que siguió exactamente al nombre correcto, como en el ejemplo que proporcioné, el código funcionó a la perfección. Tenía un nombre de clase que no tenía el mismo nombre que el elemento raíz. La respuesta fue simplemente agregar XmlRootAttribute en la clase y darle el mismo nombre que el nombre del elemento raíz en el xml. Esto funcionó sin defectos. También puede estar seguro de que cualquier elemento que exista en el documento xml que no esté expresado en la definición de clase no interrumpirá el análisis sintáctico. – jwize