it-swarm.dev

Formátování XML vytvořené pomocí DataContractSerializer

Existuje snadný způsob, jak dostat DataContractSerializer plivat ve formátu XML spíše než jeden dlouhý řetězec? Nechci v žádném případě měnit tagy ani obsah, prostě přidejte konce řádků a odsazení, aby byl XML lépe čitelný?

<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>
54
Eric Anastas

Jak říká bendewey, XmlWriterSettings je to, co potřebujete - např. něco jako

var ds = new DataContractSerializer(typeof(Foo));

var settings = new XmlWriterSettings { Indent = true };

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

Podívejte se na vlastnost Indent objektu XmlWriterSettings

Update: Zde je dobrý odkaz z MSDN na Jak: Specifikovat výstupní formát na XmlWriter

Dále je zde ukázka:

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

Buďte opatrní při úpravě mezer v dokumentech XML! Úprava mezer způsobí, že XML bude pro nás lidem lépe čitelný, ale může rušit analýzu stroje.

Podle standardu XML ​​ , mezery jsou ve výchozím nastavení významné. Jinými slovy, pokud jde o XML, prázdné místo je obsah.

Pokud nakreslíte pěkně formátovaný XML do objektu XML dokumentu, získáte jiný výsledek než verze, která v něm nemá žádné mezery ani konce řádků. Do verze, která byla naformátována, přidáte další textové uzly.

Tento článek MSDN o White White Space má několik příkladů, které ukazují, jak složité bílé místo může být.

Pokud formátujete XML pouze pro lidskou spotřebu, nezáleží na tom. Pokud se však pokusíte zaokrouhlit svůj formátovaný dokument, můžete narazit na potíže. 

Vzhledem k tomu, že jedním z klíčových primárních výhod používání DataContractSerializer je schopnost serializovat objekty a deserializovat XML hladce, je obvykle nejlepší nechat ošklivý výstup sám.

Obvykle vkládám výstup do NotePad ++ a spouštím nad ním XML-uklizené makro, když si ho chci přečíst pro účely ladění.

7
dthrasher
    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);
        }
    }
2
Amit Bagga

na základě dalších vzorků zde publikovaných, které používají XmlWriter, zde je verze (z http://ClipFlair.codeplex.com ), která pracuje s proudy (a knihovnou Ionic.Zip) a také ukazuje, jak je kód když nepoužijete formátování (pomocí podmíněné kompilace - stačí komentovat znak #define, aby byl zapsán formátovaný 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
    }

    //...

  }

}
0
George Birbilis