Как предотвратить появление недопустимых символов в моем XML при извлечении его из SQL Server - PullRequest
1 голос
/ 24 августа 2010

Иногда строковые значения свойств в моих классах становятся нечетными. Они содержат недопустимые символы и отображаются так (с полями):

123[]45[]6789

Я предполагаю, что это нелегальные / нераспознанные персонажи. Я сериализую все свои объекты в XML, а затем загружаю их через веб-сервис. Когда я получаю их снова, некоторые символы заменяются странностями. Чаще всего это происходит с дефисами и тире, набранными с помощью Word. Это причина этого?

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

Ответы [ 5 ]

3 голосов
/ 24 августа 2010

Первое, что нужно запомнить, это то, что не существует такого понятия, как «специальный символ» или «недопустимый символ».Существуют символы, которые являются особыми в определенных обстоятельствах, они не являются символами, но обычно не существует «специальных символов» или «недопустимых символов».

Здесь у вас есть либо:

  1. Совершенно нормальные символы, для которых ваш шрифт не имеет глифа.
  2. Совершенно нормальные символы, которые нельзя распечатать (например, управляющие символы).
  3. Артефакт работы отладчика.

Прежде всего, нужно выяснить, что это за персонаж.Найдите целочисленное значение символа, а затем найдите его.

Важным для поиска является U + FFFD (�), так как он иногда используется, когда декодер получает набор байтов, которые делаютнет смысла в контексте кодировки, которую он пытается использовать (например, 0x80, за которым следует 0x20, не имеет смысла в UTF-8, и один из возможных ответов - использовать U + FFFD в качестве маркера «что-то странное здесь», другие возможные ответы:выдает ошибку, а также молча игнорирует ошибку или пытается угадать намерение, хотя последние два вызывают проблемы с безопасностью).

Как только вы это выяснили, вы можете начать рассуждать о том, почему это происходитесли это не ожидаетсяМожет ли это быть проблемой с кодированием (записанная кодировка не считана)?Может ли оно быть на самом деле предназначено, чтобы быть там?Может ли это быть что-то еще?Вы не можете начать отвечать на этот вопрос, пока не получите больше информации об ошибке.

Наконец, есть вопрос, что с этим делать.Надеемся, что это будет очевидно из ответов, которые вы нашли в своем исследовании выше.Возможно, ответ будет «ничего, что хорошо», возможно, что-то простое или что-то сложное.Пока не могу сказать.

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

3 голосов
/ 24 августа 2010

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

Убедитесь, что сам документ XML хранится с использованием правильной кодировки для поддержки символов, которые необходимо сохранить.Затем убедитесь, что при чтении файла вы используете ту же кодировку, что и документ, т. Е. Если ваш XML-документ хранится в формате UTF-8, вам необходимо убедиться, что вы читаете его в кодировке UTF-8.

1 голос
/ 24 августа 2010

Посмотрите глубже на самих персонажей, каковы точные значения символов?

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

edit, nope

В вашем примере я бырискну предположить, что вы видите встроенных символов новой строки.

1 голос
/ 24 августа 2010

Определить разрешенные символы и заблокировать все остальное, т. Е .:

// only lowercase letters and digits
if(Regex.IsMatch(yourString, @"^[a-z0-9]*$"))
{
    // allowed
}

Но я думаю, что ваша проблема может лежать где-то еще, потому что вы говорите, что это происходит от сериализации (допустимой) строки, а затем десериализации (недействительной) строки. Возможно, вы используете сериализацию по умолчанию и не применяете правильную реализацию ISerializable для ваших классов (или правильное использование атрибутов Serializable), что приводит к сериализации свойств или полей, которые вы не хотите использовать. сериализованная.

PS: другие упоминали о проблемах кодирования, что является возможной причиной и может означать, что вы вообще не можете прочитать данные. В отношении кодирования есть одно простое правило: везде используйте одну и ту же кодировку (потоки, база данных, xml) и указывайте . Если нет, используется кодировка по умолчанию, которая может отличаться в зависимости от системы.


Редактировать: возможное решение

Исходя из новой информации (см. Ветку под оригинальным вопросом), совершенно очевидно, что проблема связана с кодированием. В OP упоминается, что он появляется с черточками, которые часто заменяются симпатичными черточками, такими как "-" (—), когда используются в какой-то необычной среде редактирования. Поскольку кажется, что существует некоторая неясность в том, как заставить SQL Server принимать правильно закодированные строки, вы также можете решить эту проблему в своем XML.

Когда вы создаете свой XML, просто измените кодировку на максимально возможную (US-ASCII). Это автоматически заставит создателя XML использовать правильные числовые объекты. Когда вы десериализуете, это будет правильно проанализировано в ваших строках без лишних слов. Что-то вроде этого:

Stream stream = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.ASCII;
XmlWriter writer = XmlWriter.Create(stream, settings);
// make sure to output the xml-prolog header

Но помните об использовании StringBuilder или StringWriter, потому что он установлен на использование UTF-16, и XmlWriter всегда будет писать в этой кодировке, больше информации об этой проблеме в моем блоге, который не совместим с SQL Server.

Примечание: при использовании кодировки ASCII будет закодирован любой символ выше 0x7F. Итак, é будет выглядеть как &#xE9, а тире может выглядеть как &#x2014, но это означает то же самое, и вам не следует об этом беспокоиться. Каждый инструмент с поддержкой XML будет правильно интерпретировать этот ввод.

Примечание 2: место, где вы хотите изменить способ написания XML, - это веб-служба, о которой вы говорите, которая получает XML и затем сохраняет его в базе данных SQL Server. Перед сохранением в SQL Server, изменения должны быть применены. Раньше в цепочке бесполезно.

0 голосов
/ 16 апреля 2013
public static T DeserializeFromXml<T>(string xml)
        {
            T result;
            XmlSerializerFactory serializerFactory = new XmlSerializerFactory();
            XmlSerializer serializer =serializerFactory.CreateSerializer(typeof(T));

            using (StringReader sr3 = new StringReader(xml))
            {
                XmlReaderSettings settings = new XmlReaderSettings()
                {
                    CheckCharacters = false // default value is true;
                };

                using (XmlReader xr3 = XmlTextReader.Create(sr3, settings))
                {
                    result = (T)serializer.Deserialize(xr3);
                }
            }

            return result;
        }
...