Подтвердить что ты не робот

Форматирование XML, созданного 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>
4b9b3361

Ответ 1

Как говорит 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);

Ответ 2

Посмотрите на свойство Indent XmlWriterSettings

Обновление: Вот хорошая ссылка из MSDN на Как указать формат вывода на XmlWriter

Кроме того, здесь приведен пример:

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

Ответ 3

Будьте внимательны при настройке пробелов в документах XML! Настройка пробелов сделает XML более читаемым для нас людей, но он может помешать разбору машин.

В соответствии с стандартом XML, по умолчанию значение пробела является значительным. Другими словами, что касается XML, то пустое пространство является содержимым.

Если вы подаете свой хорошо отформатированный XML в объект XML-документа, вы получите другой результат, чем версия, в которой нет пробелов или разрывов строк. Вы получите дополнительные текстовые узлы, добавленные в форматированную версию.

В этой статье MSDN на XML White Space есть несколько примеров, показывающих, насколько может быть сложное белое пространство.

Если вы форматируете XML только для потребления человеком, это не имеет значения. Но если вы попытаетесь обойти свой отформатированный документ, вы можете столкнуться с проблемами.

Поскольку одним из основных преимуществ использования DataContractSerializer является возможность сериализации объектов и десериализации XML без проблем, обычно лучше оставить только уродливый результат.

Я обычно вставляю вывод в NotePad ++ и запускаю над ним макрос, ориентированный на XML, когда я хочу его прочитать для целей отладки.

Ответ 4

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

Ответ 5

на основе других образцов, размещенных здесь, которые используют 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
    }

    //...

  }

}