VB.NET XMLWriter: how to change what's in the header?

I have a requirement to create an XML file - and the partner is pretty sticky in the header. Apparently the title should be just like this:

<?xml version="1.0"?> 

But whenever I create an XML file, I get extraneous properties as follows:

 <?xml version="1.0" encoding="utf-8" standalone="yes"?> 

The hacker in me wants to stop using XMLWriter to create the file so that I have more control over the header; "No problem, Iโ€™ll just write a loop that creates its own XML tags like StreamWriter or something like that, forget about this XMLWriter ...", but I have to admit that XMLWriter is pretty elegant to use so far; of course, there must be something where I can change the XMLWriterSettings object to say "stop putting your custom properties in the XML header, please," right?

Here is the corresponding 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 great; but I cannot find a way to manage the header. I can find a way to completely remove it, but thatโ€™s not what we want to do.

Edit: thanks for the help; while we removed WriteStartDocument, now it no longer displays standalone = yes. However, I cannot make it stop adding encoding. Any ideas?

+4
source share
5 answers

One way to do this is to take control of the initial processing yourself using the WriteProcessingInstruction method, as follows:

  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 

Please note that I also added the โ€œrootโ€ element if your dictionary contains more than one element (and I assume that none of the meanings of the dictionary word โ€œrootโ€ :)

+10
source

I know that several months have passed since the question was asked, however I feel obligated to mention the (old?) Solution that I stumbled over. It really eliminates all xmldeclaration, and all you need for dois is to rewrite only the declaration you need by writing out the recycling instructions.

XmlFragmentWriter - Omitting an Xml Declaration and 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 use 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 XMLSerializable

+2
source

Why do you think there are custom properties in the header?

WriteStartDocument writes a header with or without a standalone attribute. Your code adds an attribute that you said that your partner does not accept.

You did not show the code that was used to create "utf-16", but I suspect that he wrote StringWriter. Strings in .NET are always UNICODE, and you will always get utf-16 when writing to a string. If you are writing a stream, you can control the encoding.

+1
source

Necromancing.

You can create your own XmlTextWriter and override WriteStartDocument.

Example:

 public class XmlTextWriterIndentedStandaloneNo : System.Xml.XmlTextWriter { public bool bStandAlone = false; public bool bWriteStartDocument = true; public bool bOmitEncodingAndStandAlone = true; public XmlTextWriterIndentedStandaloneNo(System.IO.TextWriter w) : base(w) { Formatting = System.Xml.Formatting.Indented; } // End Constructor public XmlTextWriterIndentedStandaloneNo(string strFileName, System.Text.Encoding teEncoding) : base(strFileName, teEncoding) { Formatting = System.Xml.Formatting.Indented; } // End Constructor public XmlTextWriterIndentedStandaloneNo(System.IO.Stream w, System.Text.Encoding teEncoding) : base(w, teEncoding) { Formatting = System.Xml.Formatting.Indented; } // End Constructor public override void WriteStartDocument(bool standalone) { if (bWriteStartDocument) { if (bOmitEncodingAndStandAlone) { this.WriteProcessingInstruction("xml", "version='1.0'"); return; } // End if (bOmitEncodingAndStandAlone) base.WriteStartDocument(bStandAlone); } } // End Sub WriteStartDocument public override void WriteStartDocument() { // Suppress by ommitting WriteStartDocument if (bWriteStartDocument) { if (bOmitEncodingAndStandAlone) { this.WriteProcessingInstruction("xml", "version='1.0'"); return; } // End if (bOmitEncodingAndStandAlone) base.WriteStartDocument(bStandAlone); // False: Standalone="no" } // End if (bWriteStartDocument) } // End Sub WriteStartDocument } // End Class XmlTextWriterIndentedStandaloneNo 

Vb.net

 Public Class XmlTextWriterIndentedStandaloneNo Inherits System.Xml.XmlTextWriter Public bStandAlone As Boolean = False Public bWriteStartDocument As Boolean = True Public bOmitEncodingAndStandAlone As Boolean = True Public Sub New(w As System.IO.TextWriter) MyBase.New(w) Formatting = System.Xml.Formatting.Indented End Sub ' End Constructor Public Sub New(strFileName As String, teEncoding As System.Text.Encoding) MyBase.New(strFileName, teEncoding) Formatting = System.Xml.Formatting.Indented End Sub ' End Constructor Public Sub New(w As System.IO.Stream, teEncoding As System.Text.Encoding) MyBase.New(w, teEncoding) Formatting = System.Xml.Formatting.Indented End Sub ' End Constructor Public Overrides Sub WriteStartDocument(standalone As Boolean) If bOmitEncodingAndStandAlone Then Me.WriteProcessingInstruction("xml", "version='1.0'") Return End If ' End if (bOmitEncodingAndStandAlone) If bWriteStartDocument Then MyBase.WriteStartDocument(bStandAlone) End If End Sub ' End Sub WriteStartDocument Public Overrides Sub WriteStartDocument() If bOmitEncodingAndStandAlone Then Me.WriteProcessingInstruction("xml", "version='1.0'") Return End If ' End if (bOmitEncodingAndStandAlone) ' Suppress by ommitting WriteStartDocument If bWriteStartDocument Then ' False: Standalone="no" MyBase.WriteStartDocument(bStandAlone) End If ' End if (bWriteStartDocument) End Sub ' End Sub WriteStartDocument End Class ' End Class XmlTextWriterIndentedStandaloneNo 

Usage example:

 //using (System.Xml.XmlTextWriter wr = new System.Xml.XmlTextWriter(System.IO.Path.Combine(strBasePath, "TestFile.xml"), System.Text.Encoding.UTF8)) //using (System.Xml.XmlWriter wr = System.Xml.XmlWriter.Create(System.IO.Path.Combine(strBasePath, "TestFile.xml"), xwsSettings)) using (System.Xml.XmlWriter wr = new XmlTextWriterIndentedStandaloneNo(System.IO.Path.Combine(strBasePath, "TestFile.xml"), System.Text.Encoding.UTF8)) { //wr.Formatting = System.Xml.Formatting.None; // here the trick ! xdoc.Save(wr); wr.Flush(); wr.Close(); } // End Using wr 
0
source

It:

 XmlWriterSettings xmlWriterSettings = new XmlWriterSettings { OmitXmlDeclaration = true, }; 

will provide you with the following:

 <?xml version="1.0"?> 
-1
source

Source: https://habr.com/ru/post/1286583/


All Articles