56

1 つの長い文字列ではなく、フォーマットされた XML を DataContractSerializer に吐き出させる簡単な方法はありますか? タグやコンテンツを変更したくないのですが、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>
4

5 に答える 5

93

benteweyが言うように、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);
于 2009-04-10T23:40:47.330 に答える
20

Indentのプロパティを見てみましょうXmlWriterSettings

更新:方法に関する MSDN の適切なリンクは次のとおりです。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; }
}
于 2009-04-10T23:05:14.483 に答える
7

XMLドキュメントの空白の調整には注意してください。空白を調整すると、人間にとってXMLが読みやすくなりますが、マシンの解析が妨げられる可能性があります。

XML標準によれば、空白はデフォルトで重要です。言い換えれば、XMLに関する限り、空白はコンテンツです。

適切にフォーマットされたXMLをXMLドキュメントオブジェクトにフィードすると、スペースや改行が含まれていないバージョンとは異なる結果が得られます。フォーマットされたバージョンに追加のテキストノードが追加されます。

XMLホワイトスペースに関するこのMSDNの記事には、ホワイトスペースがいかにトリッキーであるかを示すいくつかの例があります。

人間が消費するためだけにXMLをフォーマットしている場合、それは問題ではありません。ただし、フォーマットされたドキュメントをラウンドトリップしようとすると、問題が発生する可能性があります。

DataContractSerializerを使用する主な利点の1つは、オブジェクトをシリアル化し、XMLをシームレスに逆シリアル化できることであるため、通常は、醜い出力をそのままにしておくのが最善です。

私は通常、出力をNotePad ++に貼り付け、デバッグ目的で読み取りたい場合は、その上でXML整頓マクロを実行します。

于 2010-02-19T20:00:36.587 に答える
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);
        }
    }
于 2009-11-16T08:47:04.317 に答える
0

ここに投稿された XmlWriter を使用する他のサンプルに基づいて、ストリーム (および具体的には Ionic.Zip ライブラリ) で動作するバージョン ( http://ClipFlair.codeplex.comから) を示します。フォーマットを適用する (条件付きコンパイルを使用 - #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
    }

    //...

  }

}
于 2013-02-22T14:45:24.000 に答える