格式化DataContractSerializer创建的XML

时间:2009-04-10 22:56:25

标签: c# xml formatting datacontractserializer

有没有一种简单的方法可以让DataContractSerializer吐出格式化的XML而不是一个长字符串?我不想以任何方式更改标签或内容,只是让它添加换行符和缩进以使XML更具可读性?

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

5 个答案:

答案 0 :(得分:86)

正如bendewey所说,XmlWriterSettings就是你所需要的 - 例如

之类的东西
var ds = new DataContractSerializer(typeof(Foo));

var settings = new XmlWriterSettings { Indent = true };

using (var w = XmlWriter.Create("fooOutput.xml", settings))
    ds.WriteObject(w, someFoos);

答案 1 :(得分:19)

查看XmlWriterSettings

Indent属性

更新:以下是MSDN在How to: Specify the Output format on the XmlWriter上的一个很好的链接

此外,这是一个示例:

class Program
{
    static void Main(string[] args)
    {
        var Mark = new Person()
        {
            Name = "Mark",
            Email = "mark@example.com"
        };

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

答案 2 :(得分:7)

小心调整XML文档中的空格!调整空格将使XML对我们人类更具可读性,但它可能会干扰机器解析。

根据XML standard,空格在默认情况下很重要。换句话说,就XML而言,空格是内容

如果将格式良好的XML提供给XML Document对象,则会得到与其中没有空格或换行符的版本不同的结果。您将获得添加到已格式化版本的其他文本节点。

这篇关于XML White Space的MSDN文章有几个例子说明了白色空间是多么棘手。

如果您仅为人类消费格式化XML,则无关紧要。但是,如果您尝试往返格式化文档,则可能会遇到麻烦。

由于使用DataContractSerializer的一个主要优点是能够序列化对象并无缝地反序列化 ,所以通常最好不要单独留下丑陋的输出。

我通常将输出粘贴到NotePad ++中,当我想读取它以进行调试时,在它上面运行一个XML-tidy宏。

答案 3 :(得分:2)

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

答案 4 :(得分:0)

基于此处发布的其他使用XmlWriter的示例,这里是一个版本(来自http://ClipFlair.codeplex.com),可以使用流(特定于Ionic.Zip库),还可以显示代码是什么时候应用格式(使用条件编译 - 只需注释#define以使其写入未格式化的XML)

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

    //...

  }

}