You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XmlTextWriter.WriteValue写入失败后重置并重试写入?

解决XmlTextWriter异常后无法重置的问题

这个问题我之前也碰到过——XmlTextWriter一旦进入错误状态,内部的状态机就会锁定,没有办法直接重置它回到正常状态继续写入。当你捕获到ArgumentException时,Writer已经处于错误状态,后续的任何写入操作都会触发InvalidOperationException,这是它的设计限制。

不过我们可以通过以下几种方式绕过这个问题:

1. 提前清理输入,从根源避免异常

最稳妥的方式是在调用WriteValue之前就清理字符串,不要等到异常发生再处理。你已经有了清理的代码,把它提前就行:

// 提前清理要写入的文本
string cleanedText = new string(text.Where(XmlConvert.IsXmlChar).ToArray());
writer.WriteValue(cleanedText);

这样就不会触发任何异常,也就不需要处理Writer的错误状态了。

2. 捕获异常后创建新的XmlTextWriter实例

如果必须在异常发生后处理,只能放弃当前的Writer实例,重新创建一个新的,然后把之前已经写入的内容(加上处理后的合法字符串)重新写入一遍。比如:

// 假设我们用MemoryStream来存储XML内容
MemoryStream ms = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8);

try
{
    writer.WriteStartDocument();
    writer.WriteStartElement("Root");
    writer.WriteValue(invalidText); // 这里抛出ArgumentException
}
catch (ArgumentException)
{
    // 清理无效字符
    string cleanedText = new string(invalidText.Where(XmlConvert.IsXmlChar).ToArray());
    
    // 关闭旧的Writer
    writer.Close();
    
    // 创建新的Writer和流
    ms = new MemoryStream();
    writer = new XmlTextWriter(ms, Encoding.UTF8);
    
    // 重新写入所有内容,包括处理后的文本
    writer.WriteStartDocument();
    writer.WriteStartElement("Root");
    writer.WriteValue(cleanedText);
    writer.WriteEndElement();
    writer.WriteEndDocument();
}
finally
{
    writer?.Close();
}

这种方式的缺点是需要重复写入之前的内容,如果XML结构复杂,可能会比较繁琐。

3. 改用更现代的XmlWriter(推荐)

XmlTextWriter其实已经是过时的API了,.NET推荐使用XmlWriter.Create创建的XmlWriter实例,它的错误处理更灵活,而且支持配置XmlWriterSettings来辅助处理字符问题(不过还是更推荐提前清理输入)。

示例代码:

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.Encoding = Encoding.UTF8;

using (MemoryStream ms = new MemoryStream())
using (XmlWriter writer = XmlWriter.Create(ms, settings))
{
    writer.WriteStartDocument();
    writer.WriteStartElement("Root");
    
    string cleanedText = new string(invalidText.Where(XmlConvert.IsXmlChar).ToArray());
    writer.WriteValue(cleanedText);
    
    writer.WriteEndElement();
    writer.WriteEndDocument();
}

使用using语句还能自动管理Writer的生命周期,避免资源泄漏。

总结一下:最好的方式是提前清理输入,避免进入错误状态;如果必须处理异常,就重新创建Writer实例;长远来看,建议迁移到现代的XmlWriter API。

内容的提问来源于stack exchange,提问作者Andrea Nagar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 11:42:43