vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Erstellen von dynamischen Kontextmen?s - wann immer Sie sie brauchen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2018
 
zurück
Rubrik: Dateisystem · XML   |   VB-Versionen: VB2005, VB2008, VB201023.05.11
XML mit StringWriter und der gewünschten Kodierung

Haben Sie sich auch schon einmal darüber geärgert, dass wenn Sie ein XML-File mittels eines StringBuilders erstellen das Encoding auf UTF-16 steht?

Autor:   Marcus JacobBewertung:     [ Jetzt bewerten ]Views:  8.085 
www.jacob-software-development.deSystem:  Win2k, WinXP, Vista, Win7, Win8, Win10kein Beispielprojekt 

Ein bisschen Grundlagen:
Das Standard-Encoding eines Strings in .NET ist UTF-16. Es gibt durchaus einige Diskussionen zu diesem Thema. Ich will nicht in die Details gehen, abgesehen von einigen seltenen Gelegenheiten, Fehler und Merkwürdigkeiten, sind Zeichenfolgen in. NET wirklich intern UTF-16 kodiert. (siehe MSDN)

Immer wenn Sie Strings benutzen und die Notwendigkeit besteht, diese in einen Stream zu wandeln oder ein ByteArray in einen String, müssen Sie ein Encoding angeben.

Die Standardkodierung für XML ist UTF-8 oder UTF-16. Jeder XML-Parser prüft hierzu die ersten Bytes auf das Vorhandensein einer Byte-Order-Mark (BOM). Diese muss benutzt werden, um die korrekte Kodierung des Dokuments zu erhalten. Wenn das Dokument mit 0xFF 0xFF 0xFE oder 0xFE beginnt dann ist die Kodierung UTF-16, wenn es mit 0xEF 0xBB 0xBF beginnt dann UTF-8. Ist keine BOM vorhanden muss das erste Zeichen ein "<"-Zeichen sein, welches jeweils unterschiedlich kodiert ist. Anhand dessen wird die Kodierung erkannt.

Nach der Logik des XML-Standards, muss die Codierung in der XML-Deklaration mit der Kodierung des Dokuments übereinstimmen. Die Zeichenfolgen werden in .NET als UTF-16 gespeichert, so dass die logische und einzige Wahl, welche man hat (hätte), folgende Deklaration ist:

<? xml version = "1.0" encoding = "UTF-16"?>

Folgender Code demonstriert dies:

Private Function BuildXML() As String
  Dim document As New XmlDocument()
  Dim builder As New StringBuilder()
  Dim inputXML As String = "<root><Element1>Text1</Element1><Element2>Text2</Element2></root>"
 
  document.Load(New StringReader(inputXml))
 
  Using writer As New XmlTextWriter(New StringWriter(builder))
    writer.Formatting = Formatting.Indented
    document.Save(writer)
  End Using
 
  Return builder.ToString()
End Function

Beim Ausführen erhalten wir folgendes:

<?xml version="1.0" encoding="utf-16"?>
<root>
  <Element1>Text1</Element1>
  <Element2>Text2</Element2>
</root>

Wie wir es uns schon gedacht haben: Encoding = UTF-16.

Wie kriegen wir jetzt hier eine UTF-8-Kodierung hin? Der "Übeltäter" ist der StringWriter. Er hat eine feste Kodierung implementiert. (Wer möchte kann dies mittels Reflector nachvollziehen.)
Und hier schreiben wir unseren eigenen erweiterten StringWriter, dem wir die Kodierung mitgeben können welche wir möchten. Dazu folgende Klasse:

Imports System.Text
Imports System.io
 
Public Class ExtStringWriter
  Inherits StringWriter
  Private _Encoding As Encoding
 
  Public Sub New(ByVal encoding As Encoding)
    MyBase.New()
    _Encoding = encoding
  End Sub
 
  Public Sub New(ByVal formatProvider As IFormatProvider, _
    ByVal encoding As Encoding)
 
    MyBase.New(formatProvider)
    _Encoding = encoding
  End Sub
 
  Public Sub New(ByVal sb As StringBuilder, _
    ByVal encoding As Encoding)
 
    MyBase.New(sb)
    _Encoding = encoding
  End Sub
 
  Public Sub New(ByVal sb As StringBuilder, _
    ByVal formatProvider As IFormatProvider, ByVal encoding As Encoding)
 
    MyBase.New(sb, formatProvider)
    _Encoding = encoding
  End Sub
 
  Public Overrides ReadOnly Property Encoding() As Encoding
    Get
      Return _Encoding
    End Get
  End Property
End Class

Nun haben wir die Möglichkeit das Encoding selbst zu bestimmen. Mit dem erweiterten StringWriter sieht unser Beispiel von oben nun wie folgt aus:

Private Function BuildXML() As String
  Dim document As New XmlDocument()
  Dim builder As New StringBuilder()
  Dim inputXML As String = "<root><Element1>Text1</Element1><Element2>Text2</Element2></root>"
 
  document.Load(New StringReader(inputXml))
 
  Using writer As New XmlTextWriter(New ExtStringWriter(builder, Encoding.UTF8))
    writer.Formatting = Formatting.Indented
    document.Save(writer)
  End Using
 
  Return builder.ToString()
End Function

Und hier die Ausgabe:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <Element1>Text1</Element1>
  <Element2>Text2</Element2>
</root>

Also: Geht doch!

Dieser Tipp wurde bereits 8.085 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Neue Diskussion eröffnen

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2018 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel