晚回答一个旧问题,但我会尽量提供比其他答案更详细的细节。
您所询问的东西称为
XML声明。
首先,
XDocument
具有类型为
XDeclaration
的属性
Declaration
。您可以使用
XDocument
构造函数的另一个重载:
var xdoc = new XDocument(
new XDeclaration("1.0", null, null),
new XDocumentType("Response", null, null, "\n"), ...
);
或者稍后设置该属性:
xdoc.Declaration = new XDeclaration("1.0", null, null);
但是取决于你如何在之后保存或写入XDocument
,声明(或其中的部分)可能会被忽略。稍后再详细说明。
XML声明可以有多种外观。以下是一些有效的示例:
<?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")
请注意XDeclaration
会接受无效的参数,因此你需要确保参数正确。
在许多情况下,第一个形式为<?xml version="1.0"?>
的请求是完美的(如果只是UTF-8(包括ASCII),则不需要提供encoding
,如果其预期值为"no"
或者没有DTD,则不需要指定standalone
)。
请注意,在我的.NET版本中,xdoc.ToString()
从XNode
基类中覆盖,并且不包括XML声明。你可以轻松地创建一个方法来处理它,像这样:
public static string ToStringWithDecl(this XDocument d)
=> $"{d.Declaration}{Environment.NewLine}{d}"
其他答案中有些人表示,如果您使用xdoc.Save
或xdoc.WriteTo
方法,则将尊重XDeclaration
,但这并不完全正确:
- 即使
XDocument
中没有XML声明,它们也可能包含XML声明。
- 它们可能指定目标文件、流、写入器、字符串构建器等使用的编码,而不是您提供的编码,或者特意省略编码。
- 它们可能会更改您的版本,例如将其从
1.1
更改为1.0
。
当然,当您保存/写入文件时,声明与该文件的实际编码匹配是一件好事!
但是有时候当您在内存中写入字符串时,您可能不希望使用utf-16
(即使您意识到.NET字符串在内部是UTF-16)。您可以使用上面的扩展方法。或者您可以使用以下来自EricSch答案的修改版方法:
string xdocString;
using (var hackedWriter = new SuppressEncodingStringWriter())
{
xdoc.Save(hackedWriter);
xdocString = hackedWriter.ToString();
}
你有:
class SuppressEncodingStringWriter : StringWriter
{
public sealed override Encoding Encoding => null;
}
添加。谁更新了类型StringWriter
(及其基类型TextWriter
)以使用可空引用类型,决定像Encoding
和FormatProvider
这样的属性不应该是可空的。也许这很不幸?无论如何,如果您打开了可为空引用类型,则可能需要编写null!
而不仅仅是null
。