2010-09-03 26 views
5

Tengo el siguiente xml que contiene un espacio en blanco Field1Value. Cuando deserializo ese xml, pierdo el carácter de espacio único. El valor de Request.Field2 es "". ¿Es esto un error en el serializador xml? ¿Alguien puede recomendar una solución/solución para mantener este espacio?XmlSerializer y WhiteSpace incrustado

... 
      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; 
      } 

Respuesta

0

Quizás el atributo xml: space puede ayudar configurándolo en 'preserve'. Ver this article como punto de partida.

3

No, esto no es un error, pero el comportamiento esperado. A menos que opte por preservar espacio, XML es procesadores (es decir, las aplicaciones que leen y escriben XML) se supone que deben normalizar los espacios en blanco. Consulte la sección 2.1 de la especificación XML 1.1 here.

Para conservar el espacio en blanco, debe incluir el atributo xml:space="preserve". De ahí que el XML debe tener este aspecto:

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

simplemente me encontré con este problema. En mi caso, el XML es generado por el control del código I, así que pude agregar el atributo xml: space = preserve. Estaba usando IXmlSerializable (por una buena razón que no entraré aquí). Así es como lo hice, en caso de que sea útil para alguien (es difícil encontrar ejemplos de gran parte de esta serialización/deserialización Xml). El método WriteXml() utiliza este método WriteSettings() para implementar IXmlSerializable.

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(); 
     } 
    } 

Esto me da XML que tiene este aspecto (elemento que encierra escrita encerrando objeto, no el método WriteSettings arriba):

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

leí esto en el uso del mismo código que tenía antes y el XmlReader respeta el xml: espacio = preservar atributo, por ejemplo:

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

puede utilizar el XmlReader para cargar el xml con IngoreWhitespace establece en false

new XmlSerializer(typeof(Request)).Deserialize(XmlReader.Create(_memoryStream, new XmlReaderSettings { IgnoreWhitespace = false })) as Request; 
Cuestiones relacionadas