我浏览了很多与此主题相关的问题。
但似乎我有一个独特的例子,我们从XmlTextWriter继承一个类,这使得无法使用XmlWriter.Create()方法用XmlWriterSettings实例化XmlWriter。
所以问题 - 是否有办法为继承的实例指定XmitWriterSettings,如OmitXmlDeclaration,DoNotEscapeUriAttributes和CloseOutput?
注意:我在继承的类中使用了Formatting属性,但除非通过XmlWriterSettings设置,否则找不到上面提到的属性。
答案 0 :(得分:0)
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
的子类在传递给基类的方法之前可以自定义输出。