如何在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
相关产品推荐
相关产品推荐

