Странные символы в XML-файле (из пользовательского ввода?)

StackOverflow https://stackoverflow.com/questions/4609346

Вопрос

Эй, ребята, у меня есть приложение, которое сохраняет данные с помощью XML.Недавно я получил сообщение об ошибке от пользователя, который не может открыть свой файл данных.Анализатор, по-видимому, потерпел неудачу, когда столкнулся с плохим символом.

К счастью, у меня есть копия ее файла с данными, так что я смог найти преступника, но я не понимаю, что это такое и как оно туда попало.(Поскольку это все ввод с клавиатуры пользователем.) Недопустимыми символами являются:

attributeName="Some text then XXX"

Где находится "XXX", согласно шестнадцатеричному редактору:

0A 0A 00

0A - это перевод строки, насколько я могу судить, но как, черт возьми, там окажется нулевой символ?!Это первая ошибка, которую я увидел подобного рода.

Это было полезно?

Решение

Я думаю, проблема, которую вы видите, является малоизвестным, но очень серьезным недостатком XML.В двух словах:значения xml не могут содержать определенные символы, и они не только не могут содержаться в тексте xml, но их даже нельзя экранировать с помощью &#DDDD;обозначение.

Допустимую кодировку XML можно найти здесь: http://www.w3.org/TR/REC-xml/#charsets, и это так:#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF].

Это означает, что если ваша строка содержит какой-либо символ, не включенный в эту кодировку, он не может быть сериализован в 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);
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top