2009-04-10 8 views
51

द्वारा बनाए गए एक्सएमएल का स्वरूपण क्या डेटाकंट्रैक्टसाइराइज़र को स्वरूपित एक्सएमएल को थूकने के लिए एक आसान स्ट्रिंग प्राप्त करने का कोई आसान तरीका है? मैं किसी भी तरह से टैग या सामग्री को बदलना नहीं चाहता हूं, क्या एक्सएमएल को और अधिक पठनीय बनाने के लिए बस लाइन ब्रेक और इंडेंटेशन जोड़ना है?DataContractSerializer

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

यह थोड़ा देरी है, लेकिन मैंने अपनी पोस्ट में एक अपडेट जोड़ा। – bendewey

उत्तर

83

जैसा कि बेंडवे कहते हैं, 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); 
19

की XmlWriterSettings

अद्यतन Indent संपत्ति पर एक नज़र डालें:

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; } 
} 
:
यहाँ How to: Specify the Output format on the XmlWriter

साथ ही पर MSDN से एक अच्छा कड़ी है, यहाँ एक नमूना है

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

क्या यह यूटीएफ 8 नहीं होना चाहिए, ASCII नहीं? –

7

कुछ XML दस्तावेज़ों में खाली स्थान के समायोजन के बारे में सावधान रहें! व्हाइटस्पेस को समायोजित करने से एक्सएमएल हमारे लिए मनुष्यों को अधिक पठनीय बना देगा, लेकिन यह मशीन पार्सिंग में हस्तक्षेप कर सकता है।

XML standard के अनुसार, व्हाइटस्पेस डिफ़ॉल्ट रूप से महत्वपूर्ण है। दूसरे शब्दों में, जहां तक ​​एक्सएमएल का संबंध है, सफेद स्थान सामग्री है।

यदि आप अपने अच्छी तरह से स्वरूपित XML को किसी XML दस्तावेज़ ऑब्जेक्ट में फ़ीड करते हैं, तो आपको उस संस्करण के मुकाबले एक अलग परिणाम मिलेगा जिसमें इसमें कोई रिक्त स्थान या लाइन ब्रेक नहीं है। आपको प्रारूप में जोड़े गए अतिरिक्त टेक्स्ट नोड्स मिलेगा जिन्हें प्रारूपित किया गया है।

XML White Space पर यह एमएसडीएन आलेख कई उदाहरण हैं जो दिखाते हैं कि कितनी मुश्किल सफेद जगह हो सकती है।

यदि आप केवल मानव उपभोग के लिए एक्सएमएल स्वरूपित कर रहे हैं, तो इससे कोई फर्क नहीं पड़ता। लेकिन यदि आप अपने स्वरूपित दस्तावेज़ को राउंड-ट्रिप करने का प्रयास करते हैं, तो आप परेशानी में भाग सकते हैं।

DataContractSerializer का उपयोग कर के प्रमुख प्राथमिक लाभों में से एक के बाद से वस्तुओं को क्रमानुसार और एक्सएमएल मूल deserialize करने की क्षमता है, यह अकेला बदसूरत उत्पादन छोड़ने के लिए आमतौर पर सबसे अच्छा है है।

मैं आमतौर पर आउटपुट को नोटपैड ++ में पेस्ट करता हूं और जब मैं इसे डिबगिंग उद्देश्यों के लिए पढ़ना चाहता हूं तो उस पर एक XML-tidy मैक्रो चलाएं।

+0

नोटपैड ++ के लिए शॉर्टकट एक XML-tidy मैक्रो देखें http://stackoverflow.com/questions/8170740/reindent-xml-via-keyboard-shortcut –

+0

"बाहरी" तत्व होने वाली सफेद जगह महत्वपूर्ण सफेद जगह नहीं है; यह सामग्री मॉडल (जैसे तत्व बनाम मिश्रित सामग्री) के आधार पर मुश्किल हो जाता है, और निश्चित रूप से किसी तत्व के भीतर व्हाइटस्पेस या विशेषता _is_ महत्वपूर्ण है, इसलिए बहु-पंक्ति तत्व सामग्री का कोई इंडेंटिंग नहीं है!मुझे लगता है कि 'DataContractSerializer' को अपनी रचना के "इंडेंट" दस्तावेजों को deserializing कोई समस्या नहीं है। –

0

यहां पोस्ट किए गए अन्य नमूनों के आधार पर XmlWriter का उपयोग करने के लिए, यहां एक संस्करण (http://ClipFlair.codeplex.com से) है जो धाराओं (और विशिष्ट में Ionic.Zip लाइब्रेरी) के साथ काम करता है और यह भी दिखाता है कि जब कोड स्वरूपण लागू नहीं होता है तो कोड कैसा होता है (सशर्त संकलन का उपयोग करके - बस इसे परिभाषित करने के लिए #define पर टिप्पणी करें।

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

    //... 

    } 

} 
संबंधित मुद्दे