2010-10-27 12 views
7

deserializing जब निर्दिष्ट एन्कोडिंग को अनदेखा मैं एक सॉकेट पर बाहरी इंटरफेस से प्राप्त कुछ एक्सएमएल पढ़ने की कोशिश कर रहा हूँ। समस्या यह है कि एन्कोडिंग को XML-header में गलत निर्दिष्ट किया गया है (यह आईएसओ -885 9 -1 कहता है, लेकिन यह utf-16BE है)। यह दस्तावेज है कि एन्कोडिंग utf-16BE है, लेकिन स्पष्ट रूप से वे सही एन्कोडिंग सेट करना भूल गए हैं। जब मैं मैं इस तरह एक StringReader का उपयोग deserializeएक्सएमएल

एन्कोडिंग की अनदेखी करने के लिए:

private static T DeserializeXmlData<T>(byte[] xmlData) 
    { 
     var xmlString = Encoding.BigEndianUnicode.GetString(xmlData); 
     using (var reader = new StringReader(xmlString)) 
     { 
      reader.ReadLine(); // Eat header line 
      using (var xmlReader = XmlReader.Create(reader)) 
      { 
       var serializer = new XmlSerializer(typeof(T)); 
       return (T)serializer.Deserialize(xmlReader); 
      } 
     } 
    } 

ऊपर वास्तव में ठीक काम करता है, लेकिन मैं हिस्सा है जहां मैं सिर्फ ReadLine फोन करके हेडर लाइन को छोड़ पसंद नहीं है। क्या एक्सएमएल-हेडर में निर्दिष्ट एन्कोडिंग को बाईपास करने के लिए कोई कम भंगुर तरीका है? StreamReader

साथ

समाधान एक StreamReader उपयोग करके, मैं एन्कोडिंग एक्सएमएल-शीर्षलेख में निर्दिष्ट ओवरराइड कर सकते हैं। XmlReaderSettings.IgnoreProcessingInstructions निर्दिष्ट करना या कोई फर्क नहीं पड़ता। दिलचस्प बात यह है कि StreamReader निर्दिष्ट एन्कोडिंग को अनदेखा करता है यदि उसे यूनिकोड बाइट-ऑर्डर चिह्न मिलता है।

संक्षिप्त करने के लिए:

  • XmlReader एक TextReader साथ आरंभ नहीं हो जाता है, तो एक्सएमएल हेडर एन्कोडिंग नजरअंदाज कर दिया है।
  • यदि कोई स्ट्रिंग रीडर का उपयोग किया जाता है, तो एक यूनिकोड बाइट-ऑर्डर चिह्न मौजूद होने पर XmlReader विफल हो जाता है।
  • यदि स्ट्रीमर रीडर का उपयोग किया जाता है, तो यूनिकोड बाइट-ऑर्डर चिह्न StreamReader एन्कोडिंग को ओवरराइड करता है।
  • XmlReaderSettings.IgnoreProcessingInstructions = TrueReader का उपयोग करते समय कोई फर्क नहीं पड़ता है।

निष्कर्ष में, सबसे मजबूत समाधान StreamReader का उपयोग करना प्रतीत होता है, क्योंकि यह मौजूद होने पर बाइट-ऑर्डर चिह्न का उपयोग करता है।

private static T DeserializeXmlData<T>(byte[] xmlData) 
    { 
     using (var xmlDataStream = new MemoryStream(xmlData)) 
     { 
      using (var reader = new StreamReader(xmlDataStream, Encoding.BigEndianUnicode)) 
      { 
       using (var xmlReader = XmlReader.Create(reader)) 
       { 
        var serializer = new XmlSerializer(typeof (T)); 
        return (T) serializer.Deserialize(xmlReader); 
       } 
      } 
     } 
    } 

उत्तर

2

मुझे लगता है कि मैं सिर्फ एक StreamReader, सही एन्कोडिंग के साथ निर्माण किया का उपयोग करें और XmlReader.Create (TextStream) विधि करने के लिए कि दे देते हैं:

using (var sr = new StreamReader(@"c:\temp\bad.xml", Encoding.BigEndianUnicode)) { 
    using (var xr = XmlReader.Create(sr, new XmlReaderSettings())) { 
     // etc... 
    } 
} 
1

कोई अन्य प्रासंगिक प्रोसेसिंग निर्देश देखते हैं, तो आप सिर्फ उन्हें XmlReaderSettings.IgnoreProcessingInstructions की स्थापना द्वारा अनदेखा कर सकते हैं।

+1

वाह! मैं फिर "सत्य" एन्कोडिंग कैसे निर्दिष्ट करूं? (एक स्ट्रिंग रीडर पर आधारित एक एक्सएमएल रीडर इग्नोर प्रोसेसिंग इंस्ट्रक्शन के साथ भी एक अपवाद फेंकता है)। – Holstebroe