2010-05-04 6 views

Répondre

19

Voici un moyen hack-ish de le faire sans avoir à charger l'intégralité de la chaîne de sortie dans 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 - Je ne pense pas que ce soit vraiment hackish du tout. Peut-être plus de travail que je ne le ferais. Mais, à la fin, il dit quel format la sortie devrait être avant de faire le travail. Ce n'est pas un hack. Un hack serait de tout arracher après le fait etc. –

+1

Je suis d'accord avec Andrew que c'est hackish. Sauf si je fais quelque chose de mal, tous mes éléments ont l'attribut 'xmlns = ""'. Aurait préféré que ce ne soit pas présent du tout. –

+0

** aucune manipulation XmlDocument/XmlNode ** – Kiquenet

-2
+2

Non. Cela produira un document xml valide qui inclut la déclaration XML et les références d'espace de noms. Je veux seulement un fragment. – Emmanuel

+0

À mon humble avis, mieux supprimer la réponse car non valable pour la question. http://stackoverflow.com/help/how-to-answer – Kiquenet

1

Vous devriez être en mesure juste sérialisation comme vous le faites habituellement, puis utiliser la propriété Root du document résultant.

Vous devrez peut-être d'abord effacer les attributs de l'élément.

+1

+1 Cela me semble bon, mais ce que je n'ai pas expliqué dans ma question, c'est que je préfèrerais produire un flux et non un XmlDocument. – Emmanuel

0

Par la façon dont c'est génial. J'ai implémenté ce code pour le rendre facile à utiliser avec des fragments xml en tant que classes rapidement et ensuite vous pouvez simplement remplacer le noeud lorsque vous avez terminé. Cela rend la transition entre le code et le xml ultra-facile.

Commencez par créer des méthodes d'extension.

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; 
    } 
} 

Suivant Mettre en oeuvre la (interface marqueur - Je sais que vous n'êtes pas censé mais je pense que c'est la raison parfaite pour elle.) Interface nécessaire

public interface ISerializableFragment 
{ 
} 

Maintenant, tout ce que vous avez à faire est décorer toute classe Serializable, vous voulez convertir en un fragment XElement, avec l'interface.

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

Enfin, testez le code.

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

Merci encore pour ce code incroyablement utile.

+1

Il y avait sur le problème que j'ai eu immédiatement en essayant cela dans mon propre projet. Avec un extrait de texte qui suivait exactement le nom correct, comme dans l'exemple que j'ai fourni, le code fonctionnait parfaitement. J'avais un nom de classe qui n'avait pas le même nom que l'élément racine. La réponse consistait simplement à ajouter XmlRootAttribute sur la classe et à l'appeler de la même manière que le nom de l'élément racine dans le fichier XML. Cela a fonctionné sans faille. Vous pouvez également être assuré que tous les éléments existants dans le document xmldocument qui ne sont pas exprimés dans la définition de classe ne rompent pas l'analyse. – jwize