Late answer to an old question, but I shall try to provide more details than the other answers.
The thing you ask about, is called an XML declaration.
First of all, the XDocument
has a property Declaration
of type XDeclaration
for this. You can either user another overload of the XDocument
constructor:
var xdoc = new XDocument(
new XDeclaration("1.0", null, null), // <--- here
new XDocumentType("Response", null, null, "\n"), ...
);
or set the property later:
xdoc.Declaration = new XDeclaration("1.0", null, null);
But depending on how you save or write your XDocument
later, the declaration (or parts of it) may be ignored. More on that later.
The XML declaration can have a number of appearances. Here are some valid examples:
<?xml version="1.0"?> new XDeclaration("1.0", null, null)
<?xml version="1.1"?> new XDeclaration("1.1", null, null)
<?xml version="1.0" encoding="us-ascii"?> new XDeclaration("1.0", "us-ascii", null)
<?xml version="1.0" encoding="utf-8"?> new XDeclaration("1.0", "utf-8", null)
<?xml version="1.0" encoding="utf-16"?> new XDeclaration("1.0", "utf-16", null)
<?xml version="1.0" encoding="utf-8" standalone="no"?> new XDeclaration("1.0", "utf-8", "no")
<?xml version="1.0" encoding="utf-8" standalone="yes"?> new XDeclaration("1.0", "utf-8", "yes")
<?xml version="1.0" standalone="yes"?> new XDeclaration("1.0", null, "yes")
Note that XDeclaration
will happily accept invalid arguments, so it is up to you to get it right.
In many cases the first one, <?xml version="1.0"?>
, the form you ask for, is perfect (it is not needed to give encoding
if it is just UTF-8 (including ASCII), and it is not needed to specify standalone
if its intended value is "no"
or if there are no DTDs).
Note that xdoc.ToString()
goes do the override from the XNode
base class (in my version of .NET) and does not include the XML declaration. You can easily enough create a method to deal with that, like this:
public static string ToStringWithDecl(this XDocument d)
=> $"{d.Declaration}{Environment.NewLine}{d}";
Some of the other answers indicate that the XDeclaration
will be respected if you use xdoc.Save
or xdoc.WriteTo
methods, but that is not quite true:
- They might include an XML declaration even if you have none in your
XDocument
- They might specify the encoding used by the target file, stream, writer, string builder etc. instead of the encoding you gave, or instead of omitting the encoding if you did that in your
XDeclaration
- They might change your version from e.g.
1.1
into 1.0
Of course, when you save/write to a file, it is a good thing that the declaration matches the true encoding of that file!
But sometimes when you write to a string in mememory, you do not want the utf-16
(even if you realize that .NET strings are in UTF-16 internally). You can use the extension method above instead. Or you can use the following hacked version of the method from EricSch's answer:
string xdocString;
using (var hackedWriter = new SuppressEncodingStringWriter())
{
xdoc.Save(hackedWriter);
xdocString = hackedWriter.ToString();
}
where you have:
// a string writer which claims its encoding is null in order to omit encoding in XML declarations
class SuppressEncodingStringWriter : StringWriter
{
public sealed override Encoding Encoding => null;
}
Addition. Whoever updated the type StringWriter
(and its base type TextWriter
) to use nuallable reference types, decided that properties such as Encoding
and FormatProvider
should not be nullable. Maybe that was unfortunate? Anyway, if you have nullable reference types turned on, you may need to write null!
instead of just null
.