我有以下包含空格Field1Value的xml。当我反序列化该xml时,我失去了单个空格字符。 Request.Field2的值为“”。这是xml序列化程序中的错误吗? 任何人都可以推荐一个解决方案/解决方法来保留这个空间吗?
...
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 :(得分:3)
不,这不是一个错误,而是预期的行为。除非您选择保留空间,否则XML是处理器(即读取和写入XML的应用程序)应该规范化空白。请参阅XML 1.1规范here的第2.1节。
要保留空白,您必须包含xml:space="preserve"
属性。因此,XML应如下所示:
<Request>
<Field1>Field1Value</Field1>
<!-- spaces inside Field2 will be preserved -->
<Field2 xml:space="preserve"> </Field2>
</Request>
答案 1 :(得分:3)
您可以使用XmlReader加载xml,并将IngoreWhitespace设置为false
new XmlSerializer(typeof(Request)).Deserialize(XmlReader.Create(_memoryStream, new XmlReaderSettings { IgnoreWhitespace = false })) as Request;
答案 2 :(得分:0)
也许xml:space属性可以通过将其设置为“保留”来提供帮助。请参阅this article作为起点。
答案 3 :(得分:0)
我只是在研究处理保留空白的问题,这个答案在这方面很有用:How do I preserve whitespace characters when parsing XML from C# LINQ
答案 4 :(得分:0)
我刚遇到这个问题。在我的例子中,XML是由我控制的代码生成的,所以我能够添加xml:space = preserve属性。我正在使用IXmlSerializable(有充分的理由我不会去这里)。这是我如何做到的,如果这对某人有帮助(很难找到大部分Xml序列化/反序列化的例子)。这个WriteSettings()方法由我的WriteXml()方法调用,实现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();
}
}
这给了我看起来像这样的XML(用封闭对象写的封闭元素,而不是上面的WriteSettings方法):
<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>
我使用与之前相同的代码读取此内容,并且XmlReader遵循xml:space = preserve属性,例如:
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
}
}