XmlTextWriter 不支持XmlWriterSettings 中的所有选项。该类最初是为在 .Net 1.x 中编写 XML 而创建的,但在 .Net 2.0 中已弃用 XmlWriter.Create(),如 docs 中所述:
从 .NET Framework 2.0 开始,我们建议您改用 System.Xml.XmlWriter 类。
对XmlWriterSettings 的完全支持从未添加到旧的XmlTextWriter 中,反之亦然。这可以通过检查参考源来确认。
例如,对于CloseOutput,如果您查看reference source for XmlTextWriter.Close(),则底层文本编写器将无条件关闭:
public override void Close() {
try {
AutoCompleteAll();
}
catch { // never fail
}
finally {
this.currentState = State.Closed;
textWriter.Close();
}
}
与XmlUtf8RawTextWriter.Close()(此类是XmlWriter.Create() 返回的XML 编写器之一)比较,其中底层文本编写器有条件地关闭:
public override void Close() {
try {
FlushBuffer();
FlushEncoder();
}
finally {
// Future calls to Close or Flush shouldn't write to Stream or Writer
writeToNull = true;
if ( stream != null ) {
try {
stream.Flush();
}
finally {
try {
if ( closeOutput ) {
stream.Close();
}
}
finally {
stream = null;
}
}
}
}
}
(但是,您始终可以使用Is there any way to close a StreamWriter without closing its BaseStream? 的答案之一构造一个不关闭底层流的StreamWriter。)
同样XmlTextWriter.WriteStartDocument() 似乎没有不发出 XML 声明的选项:
public override void WriteStartDocument() {
StartDocument(-1);
}
// Writes out the XML declaration with the version "1.0" and the standalone attribute.
public override void WriteStartDocument(bool standalone) {
StartDocument(standalone ? 1 : 0);
}
void StartDocument(int standalone) {
try {
if (this.currentState != State.Start) {
throw new InvalidOperationException(Res.GetString(Res.Xml_NotTheFirst));
}
this.stateTable = stateTableDocument;
this.currentState = State.Prolog;
StringBuilder bufBld = new StringBuilder(128);
bufBld.Append("version=" + quoteChar + "1.0" + quoteChar);
if (this.encoding != null) {
bufBld.Append(" encoding=");
bufBld.Append(quoteChar);
bufBld.Append(this.encoding.WebName);
bufBld.Append(quoteChar);
}
if (standalone >= 0) {
bufBld.Append(" standalone=");
bufBld.Append(quoteChar);
bufBld.Append(standalone == 0 ? "no" : "yes");
bufBld.Append(quoteChar);
}
InternalWriteProcessingInstruction("xml", bufBld.ToString());
}
catch {
currentState = State.Error;
throw;
}
}
void InternalWriteProcessingInstruction(string name, string text) {
textWriter.Write("<?");
ValidateName(name, false);
textWriter.Write(name);
textWriter.Write(' ');
if (null != text) {
xmlEncoder.WriteRawWithSurrogateChecking(text);
}
textWriter.Write("?>");
}
似乎必须调用StartDocument() 来初始化编写器的内部状态,但在调用时,总是会写入一个 XML 声明。
作为替代方案,您是否考虑过使用 decorator pattern 并将从 XmlWriter.Create() 返回的编写器包装在装饰器中,例如如this answer 至How can I stop empty XML elements self-closing using XmlDocument in C# 所示?这将允许您在将输出传递给底层 XmlWriter 之前对其进行自定义,类似于您的 XmlTextWriter 的子类可以在传递给基类的方法之前自定义输出。