2009-04-29 6 views
6

Mam procedurę składowaną XML w MS SQL 2005, której używam SqlCommand.ExecuteXmlReader, aby pobrać XmlReader, a następnie przeanalizować dane i utworzyć dokument XML. Problem polega na tym, że dane w SQL zawierają pewne znaki binarne, które są nielegalne w dokumencie XML UTF-8, więc zgłoszony zostanie wyjątek.Filtrowanie niedozwolonych znaków XML w .NET

Czy ktoś inny poradził sobie z tym problemem? Zastanawiałem się nad filtrowaniem danych na temat danych wejściowych do DB, ale wtedy musiałbym umieścić filtrowanie wszędzie, a każda postać musiałaby zostać sprawdzona.

Jakieś inne sugestie?

EDYCJA: Dane są zwykle przechowywane w kolumnach varchar o różnej długości. Dane są faktycznie wprowadzane przez użytkowników na formularzach internetowych (aplikacja ASP .NET). Tak więc czasami kopiują-wklejają z MS Worda lub coś takiego, i umieszcza te dziwne znaki binarne w.

Odpowiedz

0

Wyodrębniłem już tworzenie obiektów SqlParameter w całej aplikacji, więc w tym momencie wyzeruję dane wejściowe. Moja metoda abstrakcji tworzy i zwraca obiekt SqlParameter do użycia w wywołaniu procedury przechowywanej. Jeśli jest to varchar, którego chce wywoływać, przeszukuję każdy znak ciągu znaków, który chcą przekształcić w obiekt SqlParameter i odfiltrowuję te niedozwolone binarne znaki XML. To wyeliminuje złe dane z wejścia do bazy danych.

0

W jaki sposób złe dane trafiły do ​​bazy danych? Czy używasz kolumny XML?

Możesz umieścić filtrowanie (to się nazywa "sprawdzanie poprawności") w procedurach przechowywanych używanych do wprowadzania danych do bazy danych, lub możesz dodać wyzwalacze, aby sprawdzić dane bez względu na to skąd pochodzi.

Ogólnie nie zezwalaj na pobieranie błędnych danych do bazy danych!

+0

Dane są danymi użytkownika zapisanymi w kolumnach varchar w bazie danych. –

0

Czy to kwestia kodowania? Lub jest xml tylko źle sformułowane? Jeśli zostanie zniekształcony, nie mogę pomóc. Ale do kodowania ... niefortunne jest to, że ExecuteXmlReader nie pozwala na określenie kodowania, ale można traktować dane jako BLOB i przetwarzać je oddzielnie za pomocą własnego kodowania i XmlReader?

Jeśli dane są duże, to prawdopodobnie chcesz użyć ExecuteReader z CommandBehavior.SequentialAccess i zapisać go do pliku tymczasowego (Path.GetTempFileName()) - wówczas proces ten plik jako Stream z XmlReader.

0

W jaki sposób procedura składowana generuje kod XML?Jeśli używasz któregokolwiek z opcji FOR XML w SQL Server, znaków binarnych w polach tekstowych zostaną właściwie uciekł:

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 

produkuje:

<row ID="1" data="&#x0;" /> 
+0

Używam "For Xml Explicit" –

+0

To nie powinno mieć znaczenia; FOR XML EXPLICIT odpowiednio ucieka również z binarnych znaków XML. –

1

ja widziałem „wyścig” DotNet SqlClient dane z kolumny nvarchar w bazie danych, nasz teoria że był jej coś zrobić z „zastępczych punktów kodowych”, patrz:

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 wydawało się „zinterpretować” niektórych bajtów meaing że nasz XML został już dobrze uformowane, konwersja do nvarchar (max) wydawało się powstrzymać (chociaż ten miał wpływ na wydajność):

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

należy pamiętać, że trzeba użyć nvarchar (max), nvarchar (N) nie robi praca.

Odkryliśmy również, że dostawca OleDB działa również poprawnie (chociaż jest wolniejszy niż SqlClient).