嘿伙计们,我有一个使用XML保存数据的应用程序。我最近收到了一个无法打开她的数据文件的用户的错误报告。解析器在遇到错误字符时显然失败了。
幸运的是,我有她的数据文件的副本,所以我能够找到罪魁祸首,但我不明白它是什么,或者它是如何到达那里的。 (因为这是来自用户的所有键盘输入。)有问题的字符是:
attributeName="Some text then XXX"
根据十六进制编辑器,“XXX”在哪里:
0A 0A 00
就我所知,0A是一个换行符,但是那个空字符到底会怎么样?!这是我见过的第一个这种性质的错误。
答案 0 :(得分:2)
我认为您所看到的问题是一个鲜为人知的问题,但在XML中存在非常严重的缺陷。简而言之:xml值不能包含某些字符,不仅它们不能包含在xml文本中,而且甚至不能使用& #DDDD进行转义。符号
可以在此处找到有效的XML字符集:http://www.w3.org/TR/REC-xml/#charsets,它是:#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]。
这意味着如果您的字符串中没有包含在此charset中的任何字符,则无法将其序列化为XML值。存储此类字符串的唯一方法是将其序列化为base64作为二进制数据。
许多流行的框架(包括MSXML和.NET)都允许将不良数据放入XML值,然后拒绝反序列化此类XML。这是一个示例,屏幕截图:http://vvcap.net/db/Db94W-13uwCkNXSZTitO.htp和源代码:
using System;
using System.Xml.Serialization;
using System.Xml;
[Serializable] public class TestClass
{
[XmlAttribute]
public string Member { get; set; }
}
class Program
{
static void Main(string[] args)
{
var ser = new XmlSerializer(typeof(TestClass));
var tc = new TestClass() { Member = "zzz \x19 zzz" };
var stream = new System.IO.StringWriter();
ser.Serialize(stream, tc);
var xml = stream.ToString();
var stream2 = new System.IO.StringReader(stream.ToString());
var tc2 = ser.Deserialize(stream2);
}
}