2010-09-03 9 views
5

Ich habe die folgende XML, die ein White Space Field1Value enthält. Wenn ich dieses XML deserialisiere, verliere ich das einzelne Leerzeichen. Der Wert von Request.Field2 ist "". Ist das ein Fehler im XML-Serializer? Kann jemand eine Lösung/einen Workaround empfehlen, um diesen Raum zu behalten?XmlSerializer und eingebetteter WhiteSpace

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

Antwort

0

Vielleicht kann das xml: space-Attribut helfen, indem es auf 'preserve' setzt. Siehe this article als Ausgangspunkt.

3

Nein, das ist kein Fehler, sondern erwartetes Verhalten. Wenn Sie sich nicht für die Bewahrung von Speicherplatz entscheiden, sollten XML-Prozessoren (d. H. Die Apps, die XML lesen und schreiben) normalize whitespace sein. Siehe Abschnitt 2.1 der XML 1.1-Spezifikation here.

Um den Leerraum zu erhalten, müssen Sie das Attribut xml:space="preserve" einschließen. Daher soll die XML wie folgt aussehen:

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

ich gerade auf dieses Problem gestoßen. In meinem Fall wird der XML-Code vom Code generiert, den ich kontrolliere, sodass ich das xml: space = preserve-Attribut hinzufügen konnte. Ich habe IXmlSerializable verwendet (aus einem guten Grund, dass ich hier nicht eingehen werde). Hier ist, wie ich es getan habe, falls dies für jemanden hilfreich ist (es ist schwer, Beispiele für viele dieser Xml-Serialisierung/Deserialisierung zu finden). Diese WriteSettings() -Methode wird von meiner WriteXml() - Methode aufgerufen, die IXmlSerializable implementiert.

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

Das gibt mir XML-Code, wie diese (durch Einschließen Objekt geschrieben umschließenden Element, nicht die write Methode oben) aussieht:

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

Ich lese diese den gleichen Code in Verwendung ich vorher hatte und die XmlReader respektiert die xml: space = bewahren Attribut, zB:

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

Sie den XmlReader können die xml mit IngoreWhitespace auf false

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