Existe-t-il un moyen simple d’obliger DataContractSerializer à cracher du XML formaté plutôt qu’une longue chaîne? Je ne veux pas changer les balises ou le contenu de quelque manière que ce soit, juste lui faire ajouter des sauts de ligne et une indentation pour rendre le XML plus lisible
<tagA>
<tagB>This is</tagB>
<tagC>Much</tagC>
<tagD>
<tagE>easier to read</tagE>
</tagD>
</tagA>
<tagA><tagB>This is</tagB><tagC>Much</tagC><tagD><tagE>harder to read</tagE></tagD></tagA>
Comme Bendewey le dit, XmlWriterSettings est ce dont vous avez besoin - par exemple. quelque chose comme
var ds = new DataContractSerializer(typeof(Foo));
var settings = new XmlWriterSettings { Indent = true };
using (var w = XmlWriter.Create("fooOutput.xml", settings))
ds.WriteObject(w, someFoos);
Examinez la propriété Indent
de/ XmlWriterSettings
Update: Voici un bon lien de MSDN sur Comment: spécifier le format de sortie sur XmlWriter
De plus, voici un exemple:
class Program
{
static void Main(string[] args)
{
var Mark = new Person()
{
Name = "Mark",
Email = "[email protected]"
};
var serializer = new DataContractSerializer(typeof(Person));
var settings = new XmlWriterSettings()
{
Indent = true,
IndentChars = "\t"
};
using (var writer = XmlWriter.Create(Console.Out, settings))
{
serializer.WriteObject(writer, Mark);
}
Console.ReadLine();
}
}
public class Person
{
public string Name { get; set; }
public string Email { get; set; }
}
Faites attention à ajuster les espaces dans les documents XML! En ajustant les espaces, le XML sera plus lisible pour nous, mais cela peut interférer avec l'analyse de la machine.
Selon le standard XML , les espaces sont significatifs par défaut. En d'autres termes, en ce qui concerne XML, espace blanc est contenu.
Si vous insérez votre XML bien formaté dans un objet Document XML, vous obtiendrez un résultat différent de celui de la version ne contenant ni espace ni saut de ligne. Vous aurez des nœuds de texte supplémentaires ajoutés à la version qui a été formatée.
Cet article MSDN sur Espace blanc XML contient plusieurs exemples qui montrent à quel point un espace blanc peut être délicat.
Si vous formatez le XML uniquement pour la consommation humaine, peu importe. Mais si vous essayez d’aller-retour votre document formaté, vous risquez de rencontrer des problèmes.
Comme l'un des principaux avantages de l'utilisation de DataContractSerializer est la possibilité de sérialiser des objets et de désérialiser XML de manière transparente, il est généralement préférable de laisser la sortie laide seule.
En général, je colle la sortie dans Bloc-notes ++ et j'exécute une macro de rangement XML lorsque je souhaite la lire à des fins de débogage.
public static string SerializeEntity<T>(T source)
{
using (MemoryStream ms = new MemoryStream())
{
NetDataContractSerializer serializer = new NetDataContractSerializer();
serializer.Serialize(ms, source);
return System.Text.Encoding.ASCII.GetString(ms.ToArray());
}
}
public static T DeSerializeEntity<T>(string xml)
{
using (MemoryStream ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(xml)))
{
NetDataContractSerializer serializer = new NetDataContractSerializer();
return (T)serializer.Deserialize(ms);
}
}
sur la base des autres exemples publiés ici qui utilisent XmlWriter, voici une version (de http://ClipFlair.codeplex.com ) qui fonctionne avec les flux (et la bibliothèque Ionic.Zip en particulier) et montre également comment le code est lorsque vous n'appliquez pas de mise en forme (à l'aide de la compilation conditionnelle - commentez le #define pour qu'il écrive du XML non formaté)
#define WRITE_FORMATTED_XML
using System.Xml;
namespace ClipFlair.Windows
{
public partial class BaseWindow : FloatingWindow
{
//...
#if WRITE_FORMATTED_XML
private static XmlWriterSettings XML_WRITER_SETTINGS = new XmlWriterSettings() { Indent=true, IndentChars=" "};
#endif
//...
public virtual void SaveOptions(ZipFile Zip, string zipFolder = "") //THIS IS THE CORE SAVING LOGIC
{
if (SavingOptions != null) SavingOptions(this, null); //notify any listeners
View.Busy = true;
try
{
ZipEntry optionsXML = Zip.AddEntry(zipFolder + "/" + View.GetType().FullName + ".options.xml",
new WriteDelegate((entryName, stream) =>
{
DataContractSerializer serializer = new DataContractSerializer(View.GetType()); //assuming current View isn't null
#if WRITE_FORMATTED_XML
using (XmlWriter writer = XmlWriter.Create(stream, XML_WRITER_SETTINGS))
serializer.WriteObject(writer, View);
#else
serializer.WriteObject(stream, View);
#endif
}));
}
catch (Exception e)
{
MessageBox.Show("ClipFlair options save failed: " + e.Message); //TODO: find the parent window
}
finally
{
View.Busy = false; //in any case (error or not) clear the Busy flag
}
if (SavedOptions != null) SavedOptions(this, null); //notify any listeners
}
//...
}
}