c# - XmlWriter के साथ कि अन्य utf-16 को एक्सएमएल में एक एन्कोडिंग विशेषता कैसे डालनी है?




encoding (4)

मुझे कुछ XmlDocument बनाने का फ़ंक्शन मिल गया है:

public string CreateOutputXmlString(ICollection<Field> fields)
{
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;
    settings.Encoding = Encoding.GetEncoding("windows-1250");

    StringBuilder builder = new StringBuilder();
    XmlWriter writer = XmlWriter.Create(builder, settings);

    writer.WriteStartDocument();
    writer.WriteStartElement("data");
    foreach (Field field in fields)
    {
        writer.WriteStartElement("item");
        writer.WriteAttributeString("name", field.Id);
        writer.WriteAttributeString("value", field.Value);
        writer.WriteEndElement();
    }
    writer.WriteEndElement();
    writer.Flush();
    writer.Close();

    return builder.ToString();
}

मैं एक एन्कोडिंग सेट करता हूं लेकिन जब मैं एक्सएमएलआरआईटर बनाता है तो इसमें यूटीएफ -16 एन्कोडिंग होता है मुझे पता है कि स्ट्रिंग्स (और स्ट्रिंगबिलर मुझे लगता है) यूटएफ -16 में एन्कोडेड हैं और आप इसे बदल नहीं सकते हैं।
तो मैं कैसे आसानी से इस एक्सएमएल एन्कोडिंग विशेषता सेट कर सकते हैं "windows-1250" पर सेट? यह भी इस एन्कोडिंग में एन्कोडेड नहीं होना चाहिए, यह सिर्फ निर्दिष्ट विशेषता है

संपादित करें: इसे नेट 2.0 में होना चाहिए ताकि किसी नए फ्रेमवर्क तत्वों का उपयोग नहीं किया जा सके।


मैं वास्तव में MemoryStream के साथ समस्या हल:

public static string CreateOutputXmlString(ICollection<Field> fields)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = Encoding.GetEncoding("windows-1250");

            MemoryStream memStream = new MemoryStream();
            XmlWriter writer = XmlWriter.Create(memStream, settings);

            writer.WriteStartDocument();
            writer.WriteStartElement("data");
            foreach (Field field in fields)
            {
                writer.WriteStartElement("item");
                writer.WriteAttributeString("name", field.Id);
                writer.WriteAttributeString("value", field.Value);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
            writer.Flush();
            writer.Close();

            writer.Flush();
            writer.Close();

            string xml = Encoding.GetEncoding("windows-1250").GetString(memStream.ToArray());

            memStream.Close();
            memStream.Dispose();

            return xml;
        }

बस कुछ अतिरिक्त स्पष्टीकरण क्यों यह ऐसा है

स्ट्रिंग अक्षर के अनुक्रम हैं, बाइट्स नहीं। स्ट्रिंग्स, प्रति, "एन्कोडेड" नहीं हैं, क्योंकि वे अक्षर का उपयोग कर रहे हैं, जो कि यूनिकोड कोडपॉइंट के रूप में संग्रहीत हैं। एन्कोडिंग स्ट्रिंग स्तर पर ज्ञान नहीं बनाता है।

एक एन्कोडिंग, बाइट्स के अनुक्रम (बाइट-आधारित सिस्टम जैसे फाइल सिस्टम या मेमोरी पर भंडारण के लिए) के कोडपॉइंट (वर्ण) के एक मैपिंग से है। फ्रेमवर्क आपको एन्कोडिंग निर्दिष्ट करने नहीं देता है, जब तक कि कोई बाध्यता कारण नहीं है, जैसे कि 16-बिट कोडपॉइंट बाइट-आधारित संग्रहण पर फिट हो।

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

यदि आप एक एन्कोडिंग का उपयोग करना चाहते हैं, तो XmlWriter को एक स्ट्रीम पर लिखना होगा।

समाधान के बारे में जिसे आपने स्मैशस्ट्रीम के साथ मिला, कोई अपराध नहीं करना था, लेकिन यह सिर्फ हथियारों के चारों ओर फड़फड़ाता है और गर्म हवा चलती है आप अपने कोड बिंदुओं को 'windows-1252' के साथ एन्कोड कर रहे हैं, और फिर इसे कोडपॉइंट्स को वापस पार्स कर रहे हैं। हो सकता है कि एकमात्र परिवर्तन यह है कि वर्णों को परिभाषित नहीं किया गया है, Windows-1252 में एक '?' प्रक्रिया में चरित्र

मेरे लिए, सही समाधान निम्न एक हो सकता है आपके फ़ंक्शन के उपयोग के आधार पर, आप अपने फ़ंक्शन के लिए एक पैरामीटर के रूप में एक स्ट्रीम पारित कर सकते हैं, ताकि कॉलर यह निर्णय लेता है कि उसे मेमोरी या किसी फ़ाइल पर लिखा जाना चाहिए। तो यह इस प्रकार लिखा जाएगा:


        public static void WriteFieldsAsXmlDocument(ICollection fields, Stream outStream)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = Encoding.GetEncoding("windows-1250");

            using(XmlWriter writer = XmlWriter.Create(outStream, settings)) {
                writer.WriteStartDocument();
                writer.WriteStartElement("data");
                foreach (Field field in fields)
                {
                    writer.WriteStartElement("item");
                    writer.WriteAttributeString("name", field.Id);
                    writer.WriteAttributeString("value", field.Value);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }
        }

मैं स्ट्रिंग को एक चर में आउटपुट करके फिर यूटीएफ -8 (मेरे एप की जरूरत यूटीएफ 8 एन्कोडिंग) के साथ यूटीएफ -16 के किसी भी संदर्भ को बदलने के द्वारा हल किया। चूंकि आप फ़ंक्शन का उपयोग कर रहे हैं, इसलिए आप कुछ इसी तरह कर सकते हैं। मैं ज्यादातर VB.net का उपयोग करता हूं, लेकिन मुझे लगता है कि सी # इस तरह से कुछ दिखाई देगा।

return builder.ToString().Replace("utf-16", "utf-8");

आपको उपयुक्त एन्कोडिंग के साथ स्ट्रिंगव्राटर का उपयोग करना होगा। दुर्भाग्य से स्ट्रिंग वाइटर आपको एन्कोडिंग को सीधे निर्दिष्ट करने नहीं देता है, इसलिए आपको इस प्रकार एक क्लास की आवश्यकता है:

public sealed class StringWriterWithEncoding : StringWriter
{
    private readonly Encoding encoding;

    public StringWriterWithEncoding (Encoding encoding)
    {
        this.encoding = encoding;
    }

    public override Encoding Encoding
    {
        get { return encoding; }
    }
}

( यह प्रश्न समान है, लेकिन काफी एक डुप्लिकेट नहीं है।)

संपादित करें: टिप्पणी का उत्तर देने के लिए: StringWriterWithEncoding को XmlWriter.Cryate के लिए StringBuilder के बजाय पास करें, फिर इसके अंत में ToString () को कॉल करें





xmlwriter