11

In the following code I want to set "standalone = yes" to the xml, how can I do this?

Dim settings As New Xml.XmlWriterSettings
settings.Encoding = encoding

Using stream As New IO.MemoryStream, xtWriter As Xml.XmlWriter = _
    Xml.XmlWriter.Create(stream, settings)
    serializer.Serialize(xtWriter, obj)
    Return encoding.GetString(stream.ToArray())
End Using

For example, I have this:

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

But I want this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
casperOne
  • 73,706
  • 19
  • 184
  • 253
Mr Shoubs
  • 14,629
  • 17
  • 68
  • 107

2 Answers2

22

I've found a much more elegant way of doing this: simply call WriteStartDocument(true) on your XmlWriter instance - this code serializes data and outputs the resulting XML to console.

First, if you're using a StringWriter you need to tweak it a bit to force UTF-8, but keep this in mind:

When serialising an XML document to a .NET string, the encoding must be set to UTF-16. Strings are stored as UTF-16 internally, so this is the only encoding that makes sense. If you want to store data in a different encoding, you use a byte array instead.

public sealed class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding { get { return Encoding.UTF8; } }
}
using (var sw = new Utf8StringWriter())
using (var xw= XmlWriter.Create(sw, new XmlWriterSettings{Indent = true}))
{
    xw.WriteStartDocument(true); // that bool parameter is called "standalone"

    var namespaces = new XmlSerializerNamespaces();
    namespaces.Add(string.Empty, string.Empty);

    var xmlSerializer = new XmlSerializer(typeof(data));
    xmlSerializer.Serialize(xw, data);

    Console.WriteLine(sw.ToString());
}

WriteStartDocument(true) really feels like the idiomatic way of specifying standalone=true. The output heading looks like this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
Community
  • 1
  • 1
Mathieu Guindon
  • 69,817
  • 8
  • 107
  • 235
  • 2
    Perhaps `xw.WriteStartDocument(standalone:=true)` would be a good use of named args? – RubberDuck Nov 27 '15 at 19:45
  • 4
    In this code example, looks like 'namespaces' variable as a 3rd parameter to Serialize function was missed? I think xmlSerializer.Serialize(xw, data) should be changed to xmlSerializer.Serialize(xw, data, namespaces) if you want name spaces to be removed. Thanks. – Diwakar Padmaraja Apr 18 '18 at 16:26
  • @DiwakarPadmaraja possibly - the variable seems useless.... but the serialization works as intended as-is anyway. – Mathieu Guindon Apr 18 '18 at 16:29
7

If you want to do this then you'll need to use WriteProcessingInstruction method and manually write it out.

    Using stream As New IO.MemoryStream, xtWriter As Xml.XmlWriter = Xml.XmlWriter.Create(stream, settings)
        xtWriter.WriteProcessingInstruction("xml", "version=""1.0"" encoding=""UTF-8"" standalone=""yes""")
        serializer.Serialize(xtWriter, obj)
        Return encoding.GetString(stream.ToArray())
    End Using
Chris Haas
  • 53,986
  • 12
  • 141
  • 274