2010-09-03 18 views
5

मेरे पास निम्न xml है जिसमें एक सफेद स्थान Field1Value है। जब मैं उस एक्सएमएल को deserialize मैं एकल अंतरिक्ष चरित्र खो देते हैं। Request.Field2 का मान "" है। क्या यह xml serializer में एक बग है? क्या कोई भी इस जगह को रखने के लिए समाधान/समाधान की सिफारिश कर सकता है?XmlSerializer और एम्बेडेड व्हाइटस्पेस

... 
      var encoding = new System.Text.UTF8Encoding(); 
      var _xmlData = "<Request><Field1>Field1Value</Field1><Field2> </Field2></Request>"; 
      var _xmlDataAsByteArray = new byte[_xmlData.Length]; 
      _xmlDataAsByteArray = encoding.GetBytes(_xmlData); 

      var _memoryStream = new MemoryStream(_xmlDataAsByteArray); 

      var _XmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(Request)); 

      Request _request = _XmlSerializer.Deserialize(_memoryStream) as Request; 

    ... 
     public class Request 
      { 
       public string Field1; 
       public string Field2; 
      } 

उत्तर

0

शायद एक्सएमएल: स्पेस एट्रिब्यूट इसे 'संरक्षित' करने के लिए सेट करके मदद कर सकता है। शुरुआती बिंदु के रूप में this article देखें।

3

नहीं, यह एक बग नहीं है, लेकिन अपेक्षित व्यवहार है। जब तक आप अंतरिक्ष को संरक्षित करने के लिए ऑप्ट-इन नहीं करते हैं, एक्सएमएल प्रोसेसर है (यानी एक्सएम पढ़ने और लिखने वाले ऐप्स) को व्हाइटस्पेस सामान्यीकृत किया जाता है। एक्सएमएल 1.1 विनिर्देश here के सेक्शन 2.1 देखें।

व्हाइटस्पेस को संरक्षित करने के लिए आपको xml:space="preserve" विशेषता शामिल करना होगा। इसलिए एक्सएमएल इस तरह दिखना चाहिए:

<Request> 
    <Field1>Field1Value</Field1> 
    <!-- spaces inside Field2 will be preserved --> 
    <Field2 xml:space="preserve"> </Field2> 
</Request> 
0

मैं सिर्फ इस समस्या का सामना करना पड़ा। मेरे मामले में एक्सएमएल कोड I नियंत्रण द्वारा उत्पन्न होता है, इसलिए मैं xml: space = preserve संरक्षित करने में सक्षम था। मैं IXmlSerializable का उपयोग कर रहा था (एक अच्छे कारण के लिए कि मैं यहां नहीं जाऊंगा)। यहां बताया गया है कि मैंने इसे कैसे किया है, अगर यह किसी के लिए सहायक है (इस एक्सएमएल क्रमबद्धता/deserialization के उदाहरणों को खोजने में मुश्किल है)। यह WriteSettings() विधि को IXmlSerializable लागू करने वाली मेरी WriteXml() विधि द्वारा बुलाया जाता है।

<ResourceSettings> 
    <Setting> 
    <SettingType>SomeSettingName</SettingType> 
    <SettingValue>1</SettingValue> 
    </Setting> 
    <Setting> 
    <SettingType>AnotherSettingName</SettingType> 
    <SettingValue xml:space="preserve"> </SettingValue> 
    </Setting> 
    <Setting> 
    <SettingType>ADifferentSettingName</SettingType> 
    <SettingValue>some other value</SettingValue> 
    </Setting> 
</ResourceSettings> 

मैं एक ही कोड मैं पहले था उसका उपयोग करके इस पढ़ सकते हैं और:

public static void WriteSettings(XmlWriter writer, Dictionary<string, string> settings) 
    { 
     foreach (string key in settings.Keys) 
     { 
      string value = settings[key]; 
      writer.WriteStartElement("Setting"); 
      writer.WriteElementString("SettingType", key); 

      //writer.WriteElementString("SettingValue", value); 
      // I replaced the above line, which I had previously, 
      // with the below 5 lines. 
      writer.WriteStartElement("SettingValue"); 
      if (value != value.Trim()) 
       writer.WriteAttributeString("xml", "space", null, "preserve"); 
      writer.WriteString(value); 
      writer.WriteEndElement(); 

      writer.WriteEndElement(); 
     } 
    } 

यह मैं एक्सएमएल है कि इस (संलग्न वस्तु enclosing, नहीं WriteSettings उपरोक्त विधि द्वारा लिखित तत्व) की तरह दिखता है देता है XmlReader का सम्मान करता है xml: space = बनाए रखने विशेषता, जैसे:

public void ReadXml(XmlReader reader) 
    { 
     _cache = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); 
     if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "ResourceSettings") 
     { 
      // Deal with the case where there are no settings 
      if (reader.ReadToDescendant("Setting")) 
      { 
       while (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "Setting") 
       { 
        reader.ReadStartElement("Setting"); 
        string key = reader.ReadElementString("SettingType"); 
        string value = reader.ReadElementString("SettingValue"); 
        reader.ReadEndElement(); 
        _cache.Add(key, value); 
       } 
      } 
      reader.Read(); // move past container 
     } 
    } 
3

आप IngoreWhitespace साथ एक्सएमएल झूठी

+०१२३५१६४१० करने के लिए सेट लोड करने के लिए उपयोग कर सकते हैं XmlReader
new XmlSerializer(typeof(Request)).Deserialize(XmlReader.Create(_memoryStream, new XmlReaderSettings { IgnoreWhitespace = false })) as Request;