Фильтрация недопустимых символов XML в .NET - PullRequest
6 голосов
/ 29 апреля 2009

У меня есть хранимая процедура XML в MS SQL 2005, которую я использую SqlCommand.ExecuteXmlReader, чтобы получить XmlReader, затем анализировать данные и формировать документ XML. Проблема в том, что данные в SQL содержат некоторые двоичные символы, которые недопустимы в XML-документе UTF-8, поэтому возникает исключение.

Кто-нибудь еще имел дело с этой проблемой? Я подумал о том, чтобы фильтровать данные при вводе в БД, но тогда я должен был бы поместить фильтрацию повсюду, и каждый символ должен был бы быть проверен.

Любые другие предложения?

EDIT: Данные обычно хранятся в столбцах varchar различной длины. Данные на самом деле вводятся пользователями в веб-формах (приложение ASP .NET). Так что иногда они копируют-вставляют из MS Word или чего-то еще, и это помещает эти странные двоичные символы в.

Ответы [ 5 ]

1 голос
/ 02 июня 2009

Я видел, как DotNet SqlClient "скремблирует" данные из столбцов nvarchar в базе данных, наша теория , которая была как-то связана с "суррогатными кодовыми точками", см .:

http://www.siao2.com/2005/07/27/444101.aspx

http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=rzaaxsurrogate.htm

http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/admin/c0004816.htm

SqlClient, казалось, "интерпретировал" некоторые байты, имея в виду, что наш Xml больше не был хорошо сформирован, преобразование в nvarchar (max), казалось, остановило это (хотя это оказало влияние на производительность):

SELECT CONVERT(NVARCHAR(MAX), MyValue) FROM ...

Обратите внимание, что вам нужно использовать NVARCHAR (MAX), NVARCHAR (N) не работает.

Мы также обнаружили, что поставщик OleDB также работает правильно (хотя он медленнее, чем SqlClient).

0 голосов
/ 29 апреля 2009

Как ваша хранимая процедура создает XML? Если вы используете какой-либо параметр FOR XML в SQL Server, двоичные символы в текстовых полях будут правильно экранированы:

CREATE TABLE test (
   id int identity(1,1) not null primary key, 
   data nvarchar(50))
INSERT INTO test (data) values (char(0))
SELECT * FROM test FOR XML RAW

производит:

<row ID="1" data="&#x0;" />
0 голосов
/ 29 апреля 2009

Это вопрос кодирования? Или xml просто искажен? Если уродливый, я не могу помочь. Но для кодирования ... к сожалению, ExecuteXmlReader не позволяет вам указать кодировку, но вы можете обрабатывать данные как BLOB и обрабатывать их отдельно с вашей собственной кодировкой и XmlReader?

Если данные большие, вы, вероятно, захотите использовать ExecuteReader с CommandBehavior.SequentialAccess и записать их во временный файл (Path.GetTempFileName()) - затем обработать этот файл как Stream с XmlReader.

0 голосов
/ 29 апреля 2009

Я уже абстрагировался от создания объектов SqlParameter повсюду в приложении, поэтому в этот момент я буду чистить ввод. Мой метод абстракции создает и возвращает объект SqlParameter для использования в вызове хранимой процедуры. Если это varchar, который хочет вызывающий объект, я переберу каждый символ строки, которую они хотят преобразовать в объект SqlParameter, и отфильтрую эти недопустимые двоичные символы XML. Это исключит попадание неверных данных в базу данных.

0 голосов
/ 29 апреля 2009

Как плохие данные попали в базу данных? Вы используете столбец XML?

Вы можете поместить фильтрацию (на самом деле это называется «проверка») в хранимые процедуры, используемые для ввода данных в базу данных, или вы можете добавить триггеры для проверки данных независимо от их происхождения.

В общем, не допускайте попадания неверных данных в базу данных!

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