XML Encoding woes...

T

Terry Olsen

I use the following code to create an XML string:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim tw As New StringWriter
Dim xml As New XmlTextWriter(tw)
xml.WriteStartDocument()
xml.WriteStartElement("StartElement")
xml.WriteElementString("ElementString", "TheElement")
xml.WriteEndElement()
xml.WriteEndDocument()
xml.Close()
MsgBox(tw.ToString)
End Sub

This produces

<?xml version="1.0" encoding="utf-16"?>
<StartElement>
<ElementString>TheElement</ElementString>
</StartElement>

I need the encoding to say "utf-8", but I can't get it to work.

among other things, I've tried adding

xml.Settings.Encoding = New UTF8Encoding(False)

directly after Dim'ing the xml object, but it throws the "Object reference
not set to an instance" error.

Need some guidance on this one.
 
T

Terry Olsen

Yes, but they require that I write to a Stream, and not a StringWriter,
which makes things a little more difficult. How can I use a Stream to write
a string? I don't want to have to declare a large byte array.
 
G

GhostInAK

Hello Terry,
As you no doubt noticed the XMLStringWriter ctor has an overload that takes
a TextWriter. This is the only overload that does not take an Encoding parameter
(besidesthe default ctor) because it is assumed that the TextWriter will
implement the correct Encoding. TextWriter is declared MustInherit (Abstract
in C#).

So... Create a new class (I suggest naming it UTF8TextWriter). Inherit from
System.IO.TextWriter. You will have to implement the Encoding proeprty (which
is declared MustOverride in the base). Return the correct Encoding (as a
member variable (field)).

Then pass an instance of this new class to the XMLStringWriter's ctor. Presto,
voila, abracadabra! :)

Enjoy,
-Boo
 
M

Michel Posseth [MCP]

I had this problem to ,,, so after some strugling i solved it like this

i created a encodedstringwriter

here is my full implementation , use the parts you like / strip what you
don`t need

Imports System.Text
Imports System.IO

Namespace Text

'''<summary>

''' Implementeerd een stringwriter waarbij je zelf de encoding kunt kiezen

''' de data wordt opgeslagen in een stringbuilder

''' </summary>

Public Class EncodedStringWriter

Inherits StringWriter

'Private property setter

Private _Encoding As Encoding

Public Sub New(ByVal sb As StringBuilder, ByVal Encoding As Encoding)

MyBase.New(sb)

_Encoding = Encoding

End Sub

''' <summary>

'''

''' </summary>

''' <value></value>

''' <doc>

''' <summary>getter voor de string encoding </summary>

''' <returns>de Encoding waarin wordt geschreven </returns>

''' <filterpriority>1</filterpriority>

''' </doc>

Public Overrides ReadOnly Property Encoding() As Encoding

Get

Return _Encoding

End Get

End Property

End Class

End Namespace


Now in my XML base Class

Option Explicit On
Option Strict On

Imports System.Xml

Imports System.Text

Imports System.IO

Public MustInherit Class ClsXMLBase

Public Structure XMLElement

Dim ElementName As String

Dim ElementValue As String

End Structure

Public Sub New()

'-- default

Init()

End Sub

Public Sub New(ByVal XMLRootName As String)

RootNodeName = XMLRootName

Init()

End Sub

Private Mvar_XMLDoc As XmlTextWriter

Private Mvar_sb As StringBuilder

Public Property ObjXML() As XmlTextWriter

Get

If IsNothing(Mvar_XMLDoc) Then

Init()

End If

Return Mvar_XMLDoc

End Get

Set(ByVal value As XmlTextWriter)

Mvar_XMLDoc = value

End Set

End Property

Private Mvar_RootNodeName As String = "MyRootnode"

''' <summary>

''' Getter Setter voor de rootnode naam

''' </summary>

''' <value>De naam van de rootnode .</value>

Public Property RootNodeName() As String

Get

Return Mvar_RootNodeName

End Get

Set(ByVal value As String)

Mvar_RootNodeName = value

End Set

End Property

Public Overridable Sub Reset()

Init()

End Sub

Private Sub Init()

Mvar_sb = New StringBuilder(500)

Mvar_XMLDoc = New XmlTextWriter(New Text.EncodedStringWriter(Mvar_sb,
Encoding.UTF8))

Mvar_XMLDoc.Formatting = Formatting.Indented

Mvar_XMLDoc.Indentation = 2

Mvar_XMLDoc.WriteStartDocument()

Mvar_XMLDoc.WriteStartElement(RootNodeName)

EndWritten = False

End Sub

''' <summary>

''' sluit de instance van het XML object en alle onderliggende streams

''' </summary>

Public Sub Close()

Mvar_XMLDoc.Close()

End Sub

''' <summary>

''' geeft de XML terug als een string

''' </summary>

''' <returns>string data </returns>

Public Function XMLToString() As String

If Not EndWritten Then WriteEndDocument()

Return Mvar_sb.ToString

End Function

Private EndWritten As Boolean

Private Sub WriteEndDocument()

Mvar_XMLDoc.WriteEndElement()

Mvar_XMLDoc.WriteEndDocument()

EndWritten = True

End Sub

End Class



and finally your worker class

ption Explicit On

Option Strict On

Public Class clsYourWorkerclass

Inherits ClsXMLBase

#Region " constructors "

''' <summary>

''' Initializeeerd een nieuwe instance van de class.

''' Overloaded

''' </summary>

''' <param name="RootNodeName">Naam van de rootnode ( standaard is NeProS )
..</param>

Public Sub New(ByVal RootNodeName As String)

MyBase.New(RootNodeName)

End Sub

#End Region

''' <summary>

''' Schrijft het XML document naar een file

''' </summary>

''' <param name="TargetPath">het doel path (VB: C:\test.xml ) </param>

Public Sub WriteXMLDocAsFile(ByVal TargetPath As String)

My.Computer.FileSystem.WriteAllText(TargetPath, MyBase.XMLToString, False)

End Sub



End class


use the mybase prefix to see all methods of the xml doc

you have now a reusable xml document wich you can use with anny encoding you
like


regards

Michel Posseth [MCP]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top