2009-06-01 11 views
20

मैं इस तरह एक्सएमएल उत्पन्न करने के लिए कोशिश कर रहा हूँ:नेट एक्सएमएल क्रमबद्धता

<?xml version="1.0"?> 
<!DOCTYPE APIRequest SYSTEM 
"https://url"> 
<APIRequest> 
    <Head> 
     <Key>123</Key> 
    </Head> 
    <ObjectClass> 
    <Field>Value</Field 
    </ObjectClass> 
</APIRequest> 

मैं एक वर्ग है (objectClass) XMLSerialization के साथ सजाया इस तरह जिम्मेदार बताते हैं:

[XmlRoot("ObjectClass")] 
public class ObjectClass 
{ 
    [XmlElement("Field")] 
    public string Field { get; set; } 
} 

और मेरा वास्तव में हैकी सहज विचार यह सोचने के लिए सोचा गया है कि जब मैं धारावाहिक करता हूं:

ObjectClass inst = new ObjectClass(); 
XmlSerializer serializer = new XmlSerializer(inst.GetType(), ""); 

StringWriter w = new StringWriter(); 
w.WriteLine(@"<?xml version=""1.0""?>"); 
w.WriteLine("<!DOCTYPE APIRequest SYSTEM"); 
w.WriteLine(@"""https://url"">"); 
w.WriteLine("<APIRequest>"); 
w.WriteLine("<Head>"); 
w.WriteLine(@"<Field>Value</Field>"); 
w.WriteLine(@"</Head>"); 

XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
ns.Add("", ""); 
serializer.Serialize(w, inst, ns); 

w.WriteLine("</APIRequest>"); 

बहरहाल, यह इस तरह एक्सएमएल उत्पन्न करता है:

<?xml version="1.0"?> 
<!DOCTYPE APIRequest SYSTEM 
"https://url"> 
<APIRequest> 
    <Head> 
     <Key>123</Key> 
    </Head> 
    <?xml version="1.0" encoding="utf-16"?> 
    <ObjectClass> 
    <Field>Value</Field> 
    </ObjectClass> 
</APIRequest> 

अर्थात serialize बयान स्वचालित रूप से एक < एक्सएमएल पाठ घोषणा जोड़ रहा है?।

मुझे पता है कि मैं इस गलत पर हमला कर रहा हूं तो क्या कोई मुझे सही दिशा में इंगित कर सकता है?

एक नोट के रूप में, मुझे नहीं लगता कि यह केवल एक ऑब्जेक्ट क्लास के साथ एक एपीआईआरक्वेट क्लास बनाने के लिए व्यावहारिक समझ देगा (क्योंकि ऑब्जेक्ट क्लास के 20 अलग-अलग प्रकार कहते हैं जिन्हें प्रत्येक को उनके आसपास इस बॉयलरप्लेट की आवश्यकता होती है) लेकिन मुझे सही करें अगर मैं गलत हूँ।

+0

स्वचालित रूप से शामिल है? आप घोषणा को मैन्युअल रूप से जोड़ रहे हैं: w.WriteLine (@ ""); – Cerebrus

+1

@ सेरेब्रस, वह टैग के अंदर आंतरिक नहीं चाहता है। – sisve

+0

हाँ, यह इसे साफ़ करने के लिए धन्यवाद है :-) –

उत्तर

24

स्ट्रिंग concatenation का उपयोग कर कभी भी एक्सएमएल का निर्माण नहीं। यह बुरा है।

आउटपुट:

<?xml version="1.0" encoding="utf-16"?> 
<!DOCTYPE APIRequest SYSTEM "https://url"> 
<APIRequest> 
    <Head> 
    <Key>123</Key> 
    </Head> 
    <ObjectClass> 
    <Field>Value</Field> 
    </ObjectClass> 
</APIRequest> 

कोड:

using System; 
using System.Diagnostics; 
using System.Text; 
using System.Xml; 
using System.Xml.Serialization; 

public static class Program { 
    public static void Main() { 
     var obj = new ObjectClass { Field = "Value" }; 

     var settings = new XmlWriterSettings { 
      Indent = true 
     }; 

     var xml = new StringBuilder(); 
     using (var writer = XmlWriter.Create(xml, settings)) { 
      Debug.Assert(writer != null); 

      writer.WriteDocType("APIRequest", null, "https://url", null); 
      writer.WriteStartElement("APIRequest"); 
      writer.WriteStartElement("Head"); 
      writer.WriteElementString("Key", "123"); 
      writer.WriteEndElement(); // </Head> 

      var nsSerializer = new XmlSerializerNamespaces(); 
      nsSerializer.Add("", ""); 

      var xmlSerializer = new XmlSerializer(obj.GetType(), ""); 
      xmlSerializer.Serialize(writer, obj, nsSerializer); 

      writer.WriteEndElement(); // </APIRequest> 
     } 

     Console.WriteLine(xml.ToString()); 
     Console.ReadLine(); 
    } 
} 

[XmlRoot("ObjectClass")] 
public class ObjectClass { 
    [XmlElement("Field")] 
    public string Field { get; set; } 
} 
+0

धन्यवाद, मुझे पता था कि स्ट्रिंग कॉन्सैट खराब था लेकिन मैंने सोचा कि यह कम से कम काम करेगा - मुझे नहीं लगता! धन्यवाद :-) –

+0

बस चेक किया गया - धन्यवाद ढेर! –

+0

मैं यह बुरा नहीं कहूंगा। इसे पसंद नहीं किया जाता है, लेकिन यदि आपके पास ऐसी स्थितियां हैं जहां प्रदर्शन महत्वपूर्ण है और आपने लेखक को उस प्रदर्शन हिट के स्रोत के रूप में पहचाना है, तो स्ट्रिंग कॉन्सटेनेशन का उपयोग करना एक जबरदस्त जीत हो सकता है। बेशक, यह परिस्थितित्मक है, और मैं लगभग * हमेशा * हमेशा 'एक्सएमएलवाइटर' का उपयोग करता हूं, लेकिन * कुछ * मामलों में, यह उचित है। – casperOne

1

XML घोषणा न करने का विकल्प अपने स्वयं के XmlTextWriter प्राप्त।

Private Class MyXmlTextWriter 
Inherits XmlTextWriter 
Sub New(ByVal sb As StringBuilder) 
    MyBase.New(New StringWriter(sb)) 
End Sub 
Sub New(ByVal w As TextWriter) 
    MyBase.New(w) 
End Sub 

Public Overrides Sub WriteStartDocument() 
    ' Don't emit XML declaration 
End Sub 
Public Overrides Sub WriteStartDocument(ByVal standalone As Boolean) 
    ' Don't emit XML declaration 
End Sub 
End Class 

व्युत्पन्न MyXmlTextWriter के उदाहरण के साथ Serialize को कॉल करें।

Dim tw As New MyXmlTextWriter(sb) 
Dim objXmlSerializer As New XmlSerializer(type) 
objXmlSerializer.Serialize(tw, obj) 
+2

@ डौग डी: मुझे विश्वास है कि आप इसे बेहतर समाधान मानते हैं। –

1

Scott Hanselman's इस पर एक अच्छी पोस्ट मिली। मैंने थोड़ी देर पहले केज़ू के उदाहरण (जिसे स्कॉट का ब्लॉग इंगित किया) का उपयोग किया और यह बहुत अच्छा काम किया।

+2

@ टोन: एक मेई-बहुत? यह एक महीने पहले डौग डी ने कहा था। -1। –

-2

एक लाइनर, एक स्ट्रिंग से पहली पंक्ति को हटाने के लिए:

String.Join("\n", strXML.Split('\n').Skip(1).ToArray()) 

सुरुचिपूर्ण, लेकिन संक्षिप्त नहीं।

+1

-1: यह कैसे मदद करता है? –

30

इस प्रयास करें:

internal static string ToXml(object obj) 
{ 
    string retval = null; 
    if (obj != null) 
    { 
    StringBuilder sb = new StringBuilder(); 
    using(XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings() { OmitXmlDeclaration = true })) 
    { 
     new XmlSerializer(obj.GetType()).Serialize(writer, obj); 
    } 
    retval = sb.ToString(); 
    } 
    return retval; 
} 
2

आप प्रदर्शन के कारणों आदि आप यह कर सकते हैं के लिए एक xml लेखक पर भरोसा नहीं करना चाहते हैं:।

// Read into memory stream and set namespaces to empty strings 
XmlSerializerNamespaces nsSerializer = new XmlSerializerNamespaces(); 
nsSerializer.Add(string.Empty, string.Empty); 
XmlSerializer xs = new XmlSerializer(typeof(Model.AudioItem)); 
xs.Serialize(ms, item, nsSerializer); 

// Read into UTF-8 stream and read off first line (i.e "<?xml version="1.0"?>") 
StreamReader sr = new StreamReader(ms); 
ms.Position = 0; 
sr.ReadLine(); 

sr.ReadToEnd() ToString () अब नग्न serialization

+0

रीडलाइन चाल के लिए गंदा, और फिर भी चालाक लगता है। मुझें यह पसंद है। इंडेंटिंग और इस तरह के साथ कोई चिंता? – sirthomas

-1
if (!string.IsNullOrEmpty(strXML) && strXML.Contains(@"<?xml")) 
strXML = strXML.Remove(0, strXML.IndexOf(@"?>", 0) + 2); 
+0

strXML = strXML.Remove (0, sXMLContent.IndexOf (@ "?>", 0) + 2); – sas

+1

क्या आप कृपया अपना उत्तर समझा सकते हैं? – CoderPi

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