C # XmlWriter и недопустимые символы UTF8 - PullRequest
5 голосов
/ 09 декабря 2010

Мы создали модульный тест, который использует следующие методы для генерации случайного текста UTF8:

        private static Random _rand = new Random(Environment.TickCount);

        public static byte CreateByte()
        {
            return (byte)_rand.Next(byte.MinValue, byte.MaxValue + 1);
        }

        public static byte[] CreateByteArray(int length)
        {
            return Repeat(CreateByte, length).ToArray();
        }

        public static string CreateUtf8String(int length)
        {
            return Encoding.UTF8.GetString(CreateByteArray(length));
        }

        private static IEnumerable<T> Repeat<T>(Func<T> func, int count)
        {
            for (int i = 0; i < count; i++)
            {
                yield return func();
            }
        }

При отправке случайных строк UTF8 в нашу бизнес-логику XmlWriter записывает сгенерированную строку и может завершиться с ошибкой:

Test method UnitTest.Utf8 threw exception: 
System.ArgumentException: ' ', hexadecimal value 0x0E, is an invalid character.

System.Xml.XmlUtf8RawTextWriter.InvalidXmlChar(Int32 ch, Byte* pDst, Boolean entitize)
System.Xml.XmlUtf8RawTextWriter.WriteAttributeTextBlock(Char* pSrc, Char* pSrcEnd)
System.Xml.XmlUtf8RawTextWriter.WriteString(String text)
System.Xml.XmlUtf8RawTextWriterIndent.WriteString(String text)
System.Xml.XmlWellFormedWriter.WriteString(String text)
System.Xml.XmlWriter.WriteAttributeString(String localName, String value)

Мы хотим поддерживать любую возможную строку, которую нужно передать, и хотим, чтобы эти недопустимые символы каким-либо образом экранировались.

XmlWriter уже экранирует такие вещи, как &, <,> и т. Д.,как мы можем иметь дело с другими недопустимыми символами, такими как управляющие символы и т. д.?

PS - дайте мне знать, если наш генератор UTF8 имеет недостатки (я уже вижу, где я не должен позволять ему генерировать '\ 0'))

Ответы [ 4 ]

7 голосов
/ 09 декабря 2010

Класс XmlConvert имеет множество полезных методов (например, EncodeName, IsXmlChar, ...) для проверки того, что вы создаете действительный Xml.

6 голосов
/ 09 декабря 2010

Ваш генератор UTF-8 имеет недостатки.Есть много байтовых последовательностей, которые являются недопустимыми кодировками UTF-8.

Лучший способ генерировать допустимые случайные кодировки UTF-8 - генерировать случайные символы, помещать их в строку и затем кодироватьстрока в UTF-8.

5 голосов
/ 09 декабря 2010

Есть две проблемы:

  1. Не все символы допустимы для XML, даже экранированные.Для XML 1.0 единственными символами со значением кодовой точки Unicode меньше 0x0020, которые являются действительными, являются TAB (&#9;), LF (&#10;) и CR (&#13;).См. XML 1.0, Раздел 2.2, Символы .

    Для XML 1.1, который поддерживается относительно немногими системами, любой символ, кроме NUL, может быть экранирован таким образом.

  2. Не все последовательности байтов действительны для UTF-8.Например, согласно спецификации , «значения октетов от C0, C1, F5 до FF никогда не появляются».Возможно, вам было бы лучше просто создать String символов и игнорировать UTF-8 или создать String, преобразовать его в UTF-8 и обратно, если вы действительно в кодировке.

2 голосов
/ 09 декабря 2010

Марк указывает, что не каждая последовательность байтов является допустимой последовательностью UTF-8.

Я хотел бы добавить, что не каждый символ может существовать в документе XML.Только допустимы некоторые символы , и это верно, даже если они закодированы как числовая ссылка на символ .

Обновление: Если вы хотитедля кодирования произвольных двоичных данных в XML, затем используйте Base64 или другую кодировку перед записью их в XML.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...