I have a requirement to make an XML file - and the partner is rather sticky about the header. Apparently, the header must be exactly this:
<?xml version="1.0"?>
But whenever I create an XML file I get extraneous properties like this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
The hacker in me wants to stop using XMLWriter to make the file so that I have more control over the header; "no problem, I'll just write a loop that makes its own XML tags as a StreamWriter or something, forget this XMLWriter object..." but I must admit that XMLWriter has been rather elegant to use so far; surely there must be something where I can change the XMLWriterSettings object to say "stop putting your custom properties in to the XML header please", right?
Here's the relevant VB code:
Dim settings As New XmlWriterSettings()
settings.Indent = True
settings.IndentChars = " "
settings.NewLineChars = "\n"
Using writer As XmlWriter = XmlWriter.Create(strFileName, settings)
writer.WriteStartDocument(True)
For Each kvp As KeyValuePair(Of String, String) In dictArguments
Dim key As String = kvp.Key
Dim value As String = kvp.Value
writer.WriteStartElement(key)
writer.WriteString(value)
writer.WriteEndElement()
Next
End Using
Works perfectly; but I can't find a way to control the header. I can find a way to remove it entirely of course but that's not what we want to do.
Edit: thanks for the help; so far once we removed the WriteStartDocument it now no longer displays standalone = yes. I can't get it to stop adding the encoding however. Any ideas?
One way of doing this is to take control of the initial processing instruction yourself with the WriteProcessingInstruction method thus:
Dim settings As New XmlWriterSettings()
settings.Indent = True
settings.IndentChars = " "
Using writer As XmlWriter = XmlWriter.Create(strFileName, settings)
writer.WriteProcessingInstruction("xml", "version='1.0'")
writer.WriteStartElement("root")
For Each kvp As KeyValuePair(Of String, String) In dictArguments
Dim key As String = kvp.Key
Dim value As String = kvp.Value
writer.WriteStartElement(key)
writer.WriteString(value)
writer.WriteEndElement()
Next
writer.WriteEndElement()
End Using
Note that I've also added a "root" element in case your dictionary contains more than one element (and I'm guessing that none of the dictionary key values is "root" :)
I know its been a few months since the question was asked, however I feel obliged to mention a (long-standing?) solution that I stumbled accross. It does do away with the entire xmldeclaration, and all you need to dois re-write just the declaration you need by writting a proccesing instruction.
XmlFragmentWriter - Omiting the Xml Declaration and the XSD and XSI namespaces
And here is the class in VB
Imports System.Xml
Imports System.IO
Imports System.Text
Class XmlFragmentWriter
Inherits XmlTextWriter
Public Sub New(ByVal w As TextWriter)
MyBase.New(w)
End Sub
Public Sub New(ByVal w As Stream, ByVal encoding As Encoding)
MyBase.New(w, encoding)
End Sub
Public Sub New(ByVal filename As String, ByVal encoding As Encoding)
MyBase.New(New FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None), encoding)
End Sub
Private _skip As Boolean = False
Public Overrides Sub WriteStartAttribute(ByVal prefix As String, ByVal localName As String, ByVal ns As String)
' STEP 1 - Omits XSD and XSI declarations.
' From Kzu - http://weblogs.asp.net/cazzu/archive/2004/01/23/62141.aspx
If prefix = "xmlns" AndAlso (localName = "xsd" OrElse localName = "xsi") Then
_skip = True
Return
End If
MyBase.WriteStartAttribute(prefix, localName, ns)
End Sub
Public Overrides Sub WriteString(ByVal text As String)
If _skip Then
Return
End If
MyBase.WriteString(text)
End Sub
Public Overrides Sub WriteEndAttribute()
If _skip Then
' Reset the flag, so we keep writing.
_skip = False
Return
End If
MyBase.WriteEndAttribute()
End Sub
Public Overrides Sub WriteStartDocument()
' STEP 2: Do nothing so we omit the xml declaration.
End Sub
End Class
and the usage here:
Dim f As New XmlSerializer(GetType(OFXg)) Dim w As New XmlFragmentWriter("c:\books1.xml", Nothing) w.Formatting = Formatting.Indented w.WriteProcessingInstruction("xml", "version=""1.0""") f.Serialize(w, RTofx) w.Close()
Of Course the OFXg class is an XMLSerializable
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With