2009-03-23 12 views
2

Ich habe SQL-Tabelle, die eine varchar (8) -Spalte hat, die gelegentlich Binärdaten enthält. (0x01, 0x02, etc ...). (Ändern des Formats oder der Inhalt der Spalte ist keine Option.)XML-Reader in SQL-Tabelle, die ungültiges XML zurückgibt

Als ich in den SQL Server 2005 Management Studio gehen und führen Sie die Abfrage:

select * 
from mytable 
where clientID = 431620 
for xml auto 

ich nützliche Ergebnisse zu erzielen. Beachten Sie, wie proc_counts codiert ist:

<mytable clientID="431620" recno="19014235" pdate="2008-03-04T00:00:00" 
    proc_counts="&#x1;&#x1;&#x2;&#x1;" otherstuff="foobar" 
    date="2008-02-17T00:00:00"/> 

Perfekt gültige XML, AFAIK. Nun, wenn ich C# -Code eigentlich schreibe diese Zeile zu lesen, ich bin immer eine Ausnahme während ReadOuterXml:

SqlCommand cmd = new SqlCommand("select * from testing xml auto", connection); 
using (XmlReader xrd = cmd.ExecuteXmlReader()) 
{ 
    xrd.Read(); 
    while (xrd.ReadState != ReadState.EndOfFile) 
    { 
     string s = xrd.ReadOuterXml(); 
     records.Add(s); 
    } 
} 

Dies wirft: XmlException unhandled war. '', hexadezimaler Wert 0x01 ist ein ungültiges Zeichen. Ich wollen die XML von oben, aber nicht genügend Google-Fu, um herauszufinden, warum ich es nicht bekomme. Vorschläge?


Um eine Tabelle mit dieser Art von Daten, diese Transact SQL-Code funktioniert in SSMS zu erstellen:

create table testing 
(clientid int, proc_counts varchar(8)); 
insert into testing values (1, 'normal'); 
insert into testing values (2, char(65) + char(1) + char(65)); 
select * from testing for xml auto; 

Update: Post-mortem und Abhilfe

Dommer ist wahrscheinlich richtig, dass es die Normalization Eigenschaft in der XmlTextReader ist, die mir Probleme gibt. Die Sache ist (wie Sie aus den Kommentaren sehen können) Ich fand es ziemlich unmöglich, von einem (SqlCommand).ExecuteXmlReader() zu irgendetwas, das mich in die Nähe der Normalization Eigenschaft eines XmlTextReader gehen kann. Oftmals war die Microsoft-Dokumentation widersprüchlich oder einfach falsch.

So entschied ich mich für einen Workaround. Wenn ich einfach einen SqlDataReader benutze, um die Ausgabe aufzusaugen, ist alles in Ordnung. Das XML sieht perfekt aus und analysiert sehr gut.

StringBuilder sb = new StringBuilder(); 
using(SqlDataReader dr = cmd.ExecuteReader()) 
{ 
    while(rdr.Read()) 
     sb.Append((string)rdr[0]); 
} 

Antwort

4

Es ist mit der XmlTextReader.Normalization-Eigenschaft zu tun. Diese Eigenschaft wird auf "false" gesetzt, wenn Sie explizit einen XmlTextReader erstellen, sodass die "ungültigen" Zeichen decodiert werden. Wenn der XmlTextReader implizit erstellt wird, wird Normalisierung auf True festgelegt.

Die Liegenschaft befindet sich hier diskutiert:

http://msdn.microsoft.com/en-us/library/system.xml.xmltextreader.normalization.aspx

Wenn Sie die Verarbeitung „von Hand“ zu tun - das heißt eine XmlTextReader schaffen - ich denke, Sie werden den Fehler zu vermeiden.

UPDATE:

Änderungen in den neueren Versionen des Frameworks bedeuten, dass "XmlReaderSettings.CheckCharacters = false" der richtige Weg sein kann 2.0+ in ASP.NET zu gehen.Ein XmlReaderSettings-Objekt kann an XmlReader.Create übergeben werden.

+0

Das Holen von der cmd.ExecuteXmlReader() zu einem XmlTextReader wurde kurz in http://msdn.microsoft.com/en-us/library/aa336091(VS.71).aspx erwähnt, aber es ist falsch - Sie können nicht casten so: XmlTextReader xrd = (XmlTextReader) cmd.ExecuteXmlReader(). Es ist eine Laufzeitausnahme. –

+0

Nein, es scheint sich geändert zu haben ... wie üblich- :-(. Ich habe eine meiner alten Apps angeschaut. Es gibt eine Diskussion hier: http://social.msdn.microsoft.com/Forums/en -US/xmlandnetfx/thread/6248ed59-fe45-458b-95fc-755f7616b11e/ – dommer

+0

Ich kann in XmlReader, nur nicht XmlTextReader werfen.Dies ist neu, weil es Referenzen gibt in der Lage zu sein, direkt in älteren MS-Dokumenten zu werfen. ExecuteXmlReader gibt Typ XmlTextReaderImpl und das kann nicht in XmlTextReader umgewandelt werden, das ich gefunden habe. –

1

Die Ausnahme sagt Ihnen die Wahrheit. SQL Server ermöglicht scheinbar die Anzeige ungültigen XML. Versuchen Sie dies:

select * from mytable where clientID = 431620 for xml auto, BINARY BASE64 
+0

Sollte "binary base64" sein und das ist es immer noch nicht. Gleiche Ausnahme ausgelöst. –

+0

Dies muss auf der * Leser * -Seite sein, weil ich sicher bin, dass das Management Studio mein SQL nicht für mich neu schreibt. –