Verwenden von StringWriter für die XML-Serialisierung

99

Ich suche derzeit nach einer einfachen Möglichkeit, Objekte zu serialisieren (in C # 3).

Ich habe einige Beispiele gegoogelt und mir etwas ausgedacht wie:

MemoryStream memoryStream = new MemoryStream ( );
XmlSerializer xs = new XmlSerializer ( typeof ( MyObject) );
XmlTextWriter xmlTextWriter = new XmlTextWriter ( memoryStream, Encoding.UTF8 );
xs.Serialize ( xmlTextWriter, myObject);
string result = Encoding.UTF8.GetString(memoryStream .ToArray());

Nachdem ich diese Frage gelesen hatte , fragte ich mich, warum ich nicht StringWriter benutze. Es scheint viel einfacher.

XmlSerializer ser = new XmlSerializer(typeof(MyObject));
StringWriter writer = new StringWriter();
ser.Serialize(writer, myObject);
serializedValue = writer.ToString();

Ein weiteres Problem war, dass das erste Beispiel XML generierte, das ich nicht einfach in eine XML-Spalte der SQL Server 2005-Datenbank schreiben konnte.

Die erste Frage lautet: Gibt es einen Grund, warum ich StringWriter nicht zum Serialisieren eines Objekts verwenden sollte, wenn ich es anschließend als Zeichenfolge benötige? Ich habe beim Googeln mit StringWriter nie ein Ergebnis gefunden.

Das zweite ist natürlich: Wenn Sie es nicht mit StringWriter machen sollten (aus welchen Gründen auch immer), was wäre ein guter und korrekter Weg?


Zusatz:

Wie bereits in beiden Antworten erwähnt, werde ich weiter auf das XML-zu-DB-Problem eingehen.

Beim Schreiben in die Datenbank habe ich folgende Ausnahme erhalten:

System.Data.SqlClient.SqlException: XML-Analyse: Zeile 1, Zeichen 38, Codierung kann nicht geändert werden

Für String

<?xml version="1.0" encoding="utf-8"?><test/>

Ich habe die aus dem XmlTextWriter erstellte Zeichenfolge genommen und dort einfach als XML eingefügt. Dieser funktionierte nicht (auch nicht beim manuellen Einfügen in die DB).

Danach habe ich versucht, manuell einzufügen (nur INSERT INTO schreiben ...) mit encoding = "utf-16", was ebenfalls fehlgeschlagen ist. Das Entfernen der Codierung hat dann völlig funktioniert. Nach diesem Ergebnis wechselte ich zurück zum StringWriter-Code und voila - es hat funktioniert.

Problem: Ich verstehe nicht wirklich warum.

bei Christian Hayter: Bei diesen Tests bin ich mir nicht sicher, ob ich utf-16 verwenden muss, um in die DB zu schreiben. Würde es dann nicht funktionieren, die Codierung auf UTF-16 (im XML-Tag) zu setzen?

StampedeXV
quelle
1
Ich mache persönliche Erfahrungen. SQL Server akzeptiert nur UTF-16. Wenn Sie etwas anderes übergeben, sind Sie dem SQL Server-XML-Parser und seinen Versuchen, die Daten zu konvertieren, ausgeliefert. Anstatt zu versuchen, einen Weg zu finden, es zu täuschen, übergebe ich es einfach direkt an UTF-16, was immer funktionieren wird.
Christian Hayter
Wie schreibst du das in die Datenbank? Übergeben Sie ihm eine Zeichenfolge oder ein Array von Bytes oder schreiben Sie in einen Stream? Wenn es sich um eine der beiden letztgenannten Formen handelt, müssen Sie sicherstellen, dass Ihre deklarierte Codierung mit der tatsächlichen Codierung Ihrer Binärdaten übereinstimmt.
Jon Skeet
Puh. Der manuelle Versuch habe ich als Abfrage im MS SQL Management Studio gemacht. Die "codierten" Versuche wurden in eine Zeichenfolge geschrieben, die dann an einen O / R-Mapper übergeben wurde, der als Zeichenfolge schreibt (soweit ich folgen konnte). Tatsächlich übergebe ich die Zeichenfolge, die in den beiden in meiner Frage angegebenen Beispielen erstellt wurde.
StampedeXV
Zu Ihrer Information
ziesemer
1
Ich ändere meine akzeptierte Antwort, da ich glaube, dass sie meine Frage tatsächlich beantwortet. Obwohl die anderen Antworten mir geholfen haben, meine Arbeit fortzusetzen, denke ich, dass Solomons Antwort zum Zweck von Stackoverflow anderen helfen wird, besser zu verstehen, was passiert ist. [Haftungsausschluss]: Ich habe keine Zeit gefunden, die Antwort wirklich zu überprüfen.
StampedeXV

Antworten:

1

<TL; DR> Das Problem ist eigentlich recht einfach: Sie stimmen die deklarierte Codierung (in der XML-Deklaration) nicht mit dem Datentyp des Eingabeparameters ab. Wenn Sie <?xml version="1.0" encoding="utf-8"?><test/>die Zeichenfolge manuell hinzugefügt haben und dann deklarieren SqlParameter, dass sie vom Typ ist, SqlDbType.Xmloder SqlDbType.NVarCharwenn der Fehler "Codierung kann nicht geändert werden" angezeigt wird. Wenn Sie dann manuell über T-SQL einfügen, haben Sie, da Sie die deklarierte Codierung auf "Umgestellt" geändert haben utf-16, eindeutig eine VARCHARZeichenfolge eingefügt (ohne ein "N" in Großbuchstaben, daher eine 8-Bit-Codierung wie UTF-8). und nicht einNVARCHAR Zeichenfolge (mit einem vorangestellten "N" in Großbuchstaben, daher die 16-Bit-UTF-16-LE-Codierung).

Das Update sollte so einfach sein wie:

  1. Im ersten Fall beim Hinzufügen der Erklärung encoding="utf-8" : Fügen Sie einfach nicht die XML-Deklaration hinzu.
  2. Im zweiten Fall beim Hinzufügen der Erklärung encoding="utf-16":
    1. Fügen Sie einfach nicht die XML-Deklaration ODER hinzu
    2. Fügen Sie einfach ein "N" zum Eingabeparametertyp hinzu: SqlDbType.NVarCharanstelle von SqlDbType.VarChar:-) (oder wechseln Sie möglicherweise sogar zu "Verwenden" SqlDbType.Xml)

(Detaillierte Antwort ist unten)


Alle Antworten hier sind zu kompliziert und unnötig (unabhängig von den 121 und 184 Up-Votes für Christians bzw. Jons Antworten). Sie stellen möglicherweise Arbeitscode bereit, aber keiner von ihnen beantwortet die Frage tatsächlich. Das Problem ist, dass niemand die Frage wirklich verstanden hat, die letztendlich die Funktionsweise des XML-Datentyps in SQL Server betrifft. Nichts gegen diese beiden eindeutig intelligenten Leute, aber diese Frage hat wenig bis gar nichts mit der Serialisierung in XML zu tun. Das Speichern von XML-Daten in SQL Server ist viel einfacher als hier impliziert.

Es spielt keine Rolle, wie das XML erstellt wird, solange Sie die Regeln zum Erstellen von XML-Daten in SQL Server befolgen. Ich habe eine ausführlichere Erklärung (einschließlich eines funktionierenden Beispielcodes zur Veranschaulichung der unten aufgeführten Punkte) in einer Antwort auf diese Frage: So lösen Sie den Fehler "Die Codierung kann nicht umgeschaltet werden" beim Einfügen von XML in SQL Server , aber die Grundlagen sind:

  1. Die XML-Deklaration ist optional
  2. Der XML-Datentyp speichert Zeichenfolgen immer als UCS-2 / UTF-16 LE
  3. Wenn Ihr XML UCS-2 / UTF-16 LE ist, dann haben Sie:
    1. Übergeben Sie die Daten entweder als NVARCHAR(MAX)oder XML/ SqlDbType.NVarChar(maxsize = -1) oderSqlDbType.Xml , oder wenn Sie ein Zeichenfolgenliteral verwenden, muss ein Großbuchstabe "N" vorangestellt werden.
    2. Wenn Sie die XML-Deklaration angeben, muss diese entweder "UCS-2" oder "UTF-16" sein (hier kein wirklicher Unterschied).
  4. Wenn Ihr XML 8-Bit-codiert ist (z. B. "UTF-8" / "iso-8859-1" / "Windows-1252"), dann haben Sie:
    1. Die XML-Deklaration muss angegeben werden, wenn sich die Codierung von der Codepage unterscheidet, die in der Standardkollatierung der Datenbank angegeben ist
    2. Sie müssen die Daten als VARCHAR(MAX)/ SqlDbType.VarChar(maxsize = -1) übergeben. Wenn Sie ein Zeichenfolgenliteral verwenden, darf diesem kein Großbuchstaben "N" vorangestellt werden.
    3. Unabhängig davon, welche 8-Bit-Codierung verwendet wird, muss die in der XML-Deklaration angegebene "Codierung" mit der tatsächlichen Codierung der Bytes übereinstimmen.
    4. Die 8-Bit-Codierung wird vom XML-Datentyp in UTF-16 LE konvertiert

Unter Berücksichtigung der oben genannten Punkte und angesichts der Tatsache, dass Zeichenfolgen in .NET immer UTF-16 LE / UCS-2 LE sind (es gibt keinen Unterschied zwischen diesen in Bezug auf die Codierung), können wir Ihre Fragen beantworten:

Gibt es einen Grund, warum ich StringWriter nicht zum Serialisieren eines Objekts verwenden sollte, wenn ich es anschließend als Zeichenfolge benötige?

Nein, Ihr StringWriterCode scheint in Ordnung zu sein (zumindest sehe ich keine Probleme bei meinen eingeschränkten Tests mit dem 2. Codeblock aus der Frage).

Würde es dann nicht funktionieren, die Codierung auf UTF-16 (im XML-Tag) zu setzen?

Die XML-Deklaration muss nicht angegeben werden. Wenn es fehlt, wird angenommen, dass die Codierung UTF-16 LE ist, wenn Sie die Zeichenfolge als NVARCHAR(dh SqlDbType.NVarChar) oder XML(dh SqlDbType.Xml) an SQL Server übergeben . Es wird angenommen, dass die Codierung die Standard-8-Bit-Codepage ist, wenn sie als VARCHAR(dh SqlDbType.VarChar) übergeben wird. Wenn Sie Nicht-Standard-ASCII-Zeichen (dh Werte 128 und höher) haben und als übergebenVARCHAR , wird wahrscheinlich "?" für BMP-Zeichen und "??" Für zusätzliche Zeichen konvertiert SQL Server die UTF-16-Zeichenfolge aus .NET in eine 8-Bit-Zeichenfolge der aktuellen Codepage der Datenbank, bevor sie wieder in UTF-16 / UCS-2 konvertiert wird. Aber Sie sollten keine Fehler bekommen.

Wenn Sie andererseits die XML-Deklaration angeben, müssen Sie mit dem passenden 8-Bit- oder 16-Bit-Datentyp an SQL Server übergeben. Wenn Sie also eine Erklärung haben, dass die Codierung entweder UCS-2 oder UTF-16 ist, müssen Sie als SqlDbType.NVarCharoder übergeben SqlDbType.Xml. Oder, wenn Sie eine Erklärung haben die besagt , dass die Codierung eine der 8-Bit - Optionen (dh UTF-8, Windows-1252, iso-8859-1etc), dann Sie müssen in so passieren SqlDbType.VarChar. Wenn die deklarierte Codierung nicht mit dem richtigen SQL Server-Datentyp mit 8 oder 16 Bit übereinstimmt, wird der Fehler "Codierung kann nicht geändert werden" angezeigt.

Zum Beispiel habe StringWriterich unter Verwendung Ihres basierten Serialisierungscodes einfach die resultierende Zeichenfolge des XML gedruckt und in SSMS verwendet. Wie Sie unten sehen können, ist die XML-Deklaration enthalten (da StringWriteres keine Option zum OmitXmlDeclarationLiken XmlWritergibt), was kein Problem darstellt, solange Sie die Zeichenfolge als korrekten SQL Server-Datentyp übergeben:

-- Upper-case "N" prefix == NVARCHAR, hence no error:
DECLARE @Xml XML = N'<?xml version="1.0" encoding="utf-16"?>
<string>Test ሴ😸</string>';
SELECT @Xml;
-- <string>Test ሴ😸</string>

Wie Sie sehen können, werden sogar Zeichen behandelt, die über das Standard-ASCII hinausgehen, vorausgesetzt, es handelt sich um den BMP- 😸Codepunkt U + 1234 und den zusätzlichen Zeichencodepunkt U + 1F638. Allerdings Folgendes:

-- No upper-case "N" prefix on the string literal, hence VARCHAR:
DECLARE @Xml XML = '<?xml version="1.0" encoding="utf-16"?>
<string>Test ሴ😸</string>';

führt zu folgendem Fehler:

Msg 9402, Level 16, State 1, Line XXXXX
XML parsing: line 1, character 39, unable to switch the encoding

Abgesehen von all diesen Erklärungen lautet die vollständige Lösung Ihrer ursprünglichen Frage:

Sie haben die Zeichenfolge eindeutig als übergeben SqlDbType.VarChar. Wechseln Sie zu SqlDbType.NVarCharund es funktioniert, ohne dass Sie den zusätzlichen Schritt zum Entfernen der XML-Deklaration ausführen müssen. Dies wird dem Beibehalten SqlDbType.VarCharund Entfernen der XML-Deklaration vorgezogen, da diese Lösung Datenverlust verhindert, wenn das XML Nicht-Standard-ASCII-Zeichen enthält. Beispielsweise:

-- No upper-case "N" prefix on the string literal == VARCHAR, and no XML declaration:
DECLARE @Xml2 XML = '<string>Test ሴ😸</string>';
SELECT @Xml2;
-- <string>Test ???</string>

Wie Sie sehen können, gibt es diesmal keinen Fehler, aber jetzt gibt es Datenverlust 🙀.

Solomon Rutzky
quelle
Ich glaube, ich war der Grund für diese überkomplizierten Antworten, da ich im Grunde zwei Fragen in einer hatte. Ich mag Ihre prägnante Antwort sehr und werde sie das nächste Mal ausprobieren, wenn ich XML in der Datenbank speichern muss. Wenn ich das richtig sehe: Sie haben die Herausforderungen beim Speichern von XML in DB erklärt. Jon Skeet fasste Probleme mit der Verwendung von StringWriter bei der Arbeit mit XML zusammen (außer UTF-16), und Christian Hayter bietet eine gute Möglichkeit, einfach damit zu arbeiten.
StampedeXV
@StampedeXV Ich habe meine Antwort aktualisiert (ein paar Änderungen aus Gründen der Klarheit + neue Dinge, um die Punkte besser zu veranschaulichen). Hoffentlich ist es jetzt klarer, dass beide Antworten für sich genommen gut sind, aber in keiner Weise notwendig sind, um Ihre Frage zu beantworten. Sie befassen sich mit der XML-Serialisierung in C # / .NET, aber bei dieser Frage geht es wirklich um das Speichern von XML in SQL Server. Sie bieten Informationen, die gut zu wissen sind und möglicherweise besseren Code enthalten als Sie ursprünglich angegeben haben, aber keiner von ihnen (oder einer der anderen hier) ist wirklich themenbezogen. Aber das ist nicht gut dokumentiert, daher die Verwirrung.
Solomon Rutzky
@StampedeXV Haben meine Überarbeitungen Sinn gemacht? Ich habe gerade einen Zusammenfassungsabschnitt oben hinzugefügt, der möglicherweise klarer ist. Lange Rede, kurzer Sinn: Wenn nicht noch etwas passiert ist, von dem Sie keine Details in die Frage aufgenommen haben, sieht es so aus, als ob Ihr Code zu 99% korrekt war und wahrscheinlich durch Hinzufügen eines einzelnen Großbuchstabens behoben werden konnte. " N ". Es ist kein spezielles Codierungsmaterial erforderlich, und Christians Code ist nett, aber meine Tests zeigen, dass er eine Serialisierung zurückgibt, die mit Ihrem zweiten Codeblock identisch ist, außer dass Ihre nach der XML-Deklaration eine CRLF einfügt. Ich wette du hast zu SqlDbType.NVarCharoder gewechselt Xml.
Solomon Rutzky
Ich versuche immer noch, die Zeit zu finden, es selbst zu überprüfen. Es klingt sicherlich gut und logisch, ist sich aber nicht sicher, ob dies ausreichen würde, um eine akzeptierte Antwort zu ändern.
StampedeXV
216

Ein Problem StringWriterbesteht darin, dass Sie standardmäßig nicht die Codierung festlegen können, für die angekündigt wird. Sie können also ein XML-Dokument erhalten, das die Codierung als UTF-16 ankündigt. Dies bedeutet, dass Sie es als UTF-16 codieren müssen, wenn Sie dies tun schreibe es in eine Datei. Ich habe eine kleine Klasse, die mir dabei hilft:

public sealed class StringWriterWithEncoding : StringWriter
{
    public override Encoding Encoding { get; }

    public StringWriterWithEncoding (Encoding encoding)
    {
        Encoding = encoding;
    }    
}

Oder wenn Sie nur UTF-8 benötigen (das ist alles, was ich oft brauche):

public sealed class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding => Encoding.UTF8;
}

Warum Sie Ihr XML nicht in der Datenbank speichern konnten, müssen Sie uns näher erläutern, was passiert ist, als Sie es versucht haben, damit wir es diagnostizieren / beheben können.

Jon Skeet
quelle
Ich ging jetzt näher auf das Datenbankproblem ein. Siehe Frage.
StampedeXV
4
Traurig StringWriter, dass die Kodierung nicht berücksichtigt wird, aber trotzdem, danke für eine nette kleine Methode :)
Chau
2
Und "XML-Analyse: Zeile 1, Zeichen 38, Codierung kann nicht geändert werden" kann durch "settings.Indent = false; settings.OmitXmlDeclaration = false;"
MGE
Normalerweise umgehe ich das, indem ich einfach a MemoryStreamund a StreamWritermit der richtigen Codierung verwende. StreamWriter ist schließlich ein TextWriter(der Typ, der XmlWriter.Createerwartet) mit anpassbarer Codierung.
Nyerguds
2
@Nyerguds: Erstellen Sie also ein Nuget-Paket mit solchen Dingen, dann ist es immer leicht zu erreichen. Ich würde das lieber tun, als die Lesbarkeit von Code zu beeinträchtigen, bei der es im Wesentlichen um eine andere Anforderung geht.
Jon Skeet
126

Beim Serialisieren eines XML-Dokuments in eine .NET-Zeichenfolge muss die Codierung auf UTF-16 festgelegt werden. Zeichenfolgen werden intern als UTF-16 gespeichert, daher ist dies die einzige sinnvolle Codierung. Wenn Sie Daten in einer anderen Codierung speichern möchten, verwenden Sie stattdessen ein Byte-Array.

SQL Server arbeitet nach einem ähnlichen Prinzip. Jede in eine xmlSpalte übergebene Zeichenfolge muss als UTF-16 codiert werden. SQL Server lehnt alle Zeichenfolgen ab, in denen in der XML-Deklaration kein UTF-16 angegeben ist. Wenn die XML-Deklaration nicht vorhanden ist, muss der XML-Standard standardmäßig UTF-8 verwenden, sodass SQL Server dies ebenfalls ablehnt.

Vor diesem Hintergrund finden Sie hier einige nützliche Methoden für die Konvertierung.

public static string Serialize<T>(T value) {

    if(value == null) {
        return null;
    }

    XmlSerializer serializer = new XmlSerializer(typeof(T));

    XmlWriterSettings settings = new XmlWriterSettings()
    {
        Encoding = new UnicodeEncoding(false, false), // no BOM in a .NET string
        Indent = false,
        OmitXmlDeclaration = false
    };

    using(StringWriter textWriter = new StringWriter()) {
        using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) {
            serializer.Serialize(xmlWriter, value);
        }
        return textWriter.ToString();
    }
}

public static T Deserialize<T>(string xml) {

    if(string.IsNullOrEmpty(xml)) {
        return default(T);
    }

    XmlSerializer serializer = new XmlSerializer(typeof(T));

    XmlReaderSettings settings = new XmlReaderSettings();
    // No settings need modifying here

    using(StringReader textReader = new StringReader(xml)) {
        using(XmlReader xmlReader = XmlReader.Create(textReader, settings)) {
            return (T) serializer.Deserialize(xmlReader);
        }
    }
}
Christian Hayter
quelle
Siehe Fragezusatz. Ich verstehe meine Testergebnisse nicht, es scheint Ihrer Aussage zu widersprechen, dass die DB immer UTF-16 will / nimmt / braucht.
StampedeXV
9
Sie müssen nicht als UTF-16 codieren - aber Sie müssen sicherstellen, dass die von Ihnen verwendete Codierung den StringWriterErwartungen entspricht. Siehe meine Antwort. Das interne Speicherformat spielt hier keine Rolle.
Jon Skeet
ok das verstehe ich In meinem neuen Beispiel: Wenn die Codierung vollständig weggelassen wurde, hat die Datenbank selbst entschieden, welche Codierung verwendet wurde - deshalb hat sie funktioniert. Verstehe ich es jetzt richtig?
StampedeXV
1
@SteveC: Entschuldigung, mein Fehler. Ich habe den Code von VB von Hand konvertiert, der Nothingimplizit in einen beliebigen Typ konvertierbar ist. Ich habe den DeserializeCode korrigiert . Die SerializeWarnung muss nur für Resharper gelten, der Compiler selbst hat keine Einwände und es ist legal, dies zu tun.
Christian Hayter
1
Nach Jon Skeets Kommentar ist UTF-16 nicht erforderlich. Ein konkretes Beispiel hierfür finden Sie unter stackoverflow.com/a/8998183/751158 .
ziesemer
20

Achten Sie zunächst darauf, alte Beispiele zu finden. Sie haben eine gefunden, die verwendet XmlTextWriterwird und ab .NET 2.0 veraltet ist. XmlWriter.Createsollte stattdessen verwendet werden.

Hier ist ein Beispiel für die Serialisierung eines Objekts in eine XML-Spalte:

public void SerializeToXmlColumn(object obj)
{
    using (var outputStream = new MemoryStream())
    {
        using (var writer = XmlWriter.Create(outputStream))
        {
            var serializer = new XmlSerializer(obj.GetType());
            serializer.Serialize(writer, obj);
        }

        outputStream.Position = 0;
        using (var conn = new SqlConnection(Settings.Default.ConnectionString))
        {
            conn.Open();

            const string INSERT_COMMAND = @"INSERT INTO XmlStore (Data) VALUES (@Data)";
            using (var cmd = new SqlCommand(INSERT_COMMAND, conn))
            {
                using (var reader = XmlReader.Create(outputStream))
                {
                    var xml = new SqlXml(reader);

                    cmd.Parameters.Clear();
                    cmd.Parameters.AddWithValue("@Data", xml);
                    cmd.ExecuteNonQuery();
                }
            }
        }
    }
}
John Saunders
quelle
2
Ich kann dies nur einmal abstimmen, aber dies verdient die beste Antwort hier. Am Ende spielt es keine Rolle, welche Codierung deklariert oder verwendet wird, solange XmlReadersie analysiert werden kann. Es wird vorab analysiert an die Datenbank gesendet, und dann muss die Datenbank nichts über Zeichencodierungen wissen - UTF-16 oder andere. Beachten Sie insbesondere, dass die XML-Deklarationen nicht einmal mit den Daten in der Datenbank beibehalten werden, unabhängig davon, mit welcher Methode sie eingefügt werden. Machen Sie keine Verschwendung, indem Sie XML durch zusätzliche Konvertierungen ausführen, wie in anderen Antworten hier und anderswo gezeigt.
ziesemer
1
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;
}
Mashudu Nemukuka
quelle
-1

Möglicherweise wurde es an anderer Stelle behandelt, aber durch einfaches Ändern der Codierungszeile der XML-Quelle in 'utf-16' kann das XML in den XML-Datentyp eines SQL Servers eingefügt werden.

using (DataSetTableAdapters.SQSTableAdapter tbl_SQS = new DataSetTableAdapters.SQSTableAdapter())
{
    try
    {
        bodyXML = @"<?xml version="1.0" encoding="UTF-8" standalone="yes"?><test></test>";
        bodyXMLutf16 = bodyXML.Replace("UTF-8", "UTF-16");
        tbl_SQS.Insert(messageID, receiptHandle, md5OfBody, bodyXMLutf16, sourceType);
    }
    catch (System.Data.SqlClient.SqlException ex)
    {
        Console.WriteLine(ex.Message);
        Console.ReadLine();
    }
}

Das Ergebnis ist, dass der gesamte XML-Text in das Datentypfeld 'xml' eingefügt wird, die Zeile 'header' jedoch entfernt wird. Was Sie in dem resultierenden Datensatz sehen, ist gerecht

<test></test>

Die Verwendung der im Eintrag "Beantwortet" beschriebenen Serialisierungsmethode ist eine Möglichkeit, den ursprünglichen Header in das Zielfeld aufzunehmen. Das Ergebnis ist jedoch, dass der verbleibende XML-Text in einem XML- <string></string>Tag enthalten ist.

Der Tabellenadapter im Code ist eine Klasse, die automatisch mit dem Visual Studio 2013-Assistenten "Neue Datenquelle hinzufügen:" erstellt wird. Die fünf Parameter der Methode "Methode einfügen" werden Feldern in einer SQL Server-Tabelle zugeordnet.

DLG
quelle
2
Ersetzen? Das ist urkomisch.
mgilberties
2
Ernsthaft - tu das nicht. Je. Was wäre, wenn ich eine Prosa in meine XML-Datei aufnehmen wollte, in der "UTF-8" erwähnt wird? Sie haben gerade meine Daten in etwas geändert, das ich nicht gesagt habe!
Tim Abell
2
Vielen Dank, dass Sie auf einen Fehler im Code hingewiesen haben. Anstelle von bodyXML.Replace ("UTF-8", "UTF-16") sollte Code vorhanden sein, der sich auf den XML-Header konzentriert und UTF-8 in UTF-16 ändert. Ich wollte wirklich darauf hinweisen, indem ich diese Änderung im Header des Quell-XML vorgenommen habe. Dann kann der XML-Text mithilfe eines XML-Datentypfelds in einen SQL-Tabellendatensatz eingefügt und der Header entfernt werden. Aus Gründen, an die ich mich jetzt nicht erinnere (vor vier Jahren!), War das Ergebnis damals etwas Nützliches. Und ja, dummer Fehler mit 'Ersetzen'. Es passiert.
DLG