XmlWriter为何未按XmlWriterSettings指定格式化XML?如何解决?
问题解答
为什么第二次运行函数无法重新格式化?
第一次处理无空白的XML时,XmlReader读取的内容里没有元素之间的空白文本节点,此时XmlWriter的Indent=true会正常工作,自动添加指定的缩进和换行。
但第二次处理的是已经格式化好的XML,文件里的换行、缩进会被XmlReader默认当作有效文本节点保留下来。调用writer.WriteNode(reader, false)时,这些空白文本会被原样输出,XmlWriter的缩进设置不会覆盖已有的空白内容——因为它的缩进逻辑只在节点之间没有空白的情况下才会自动添加格式,不会主动替换已存在的空白文本。
如何确保函数始终能格式化文件?
修改XmlReader的创建逻辑,添加XmlReaderSettings并设置IgnoreWhitespace = true,让读取器忽略元素之间的空白节点,这样XmlWriter就能完全按照新的缩进设置重新生成格式化后的XML:
public static void Convert(string filename, string indent) { var input_string = File.ReadAllText(filename, Encoding.UTF8); var settings = new XmlWriterSettings { NewLineHandling = NewLineHandling.Entitize, Indent = true, IndentChars = indent, NewLineChars = Environment.NewLine }; // 添加读取器设置,忽略元素间空白 var readerSettings = new XmlReaderSettings { IgnoreWhitespace = true }; var sb = new StringBuilder(); using (var reader = XmlReader.Create(new StringReader(input_string), readerSettings)) using (var writer = XmlWriter.Create(sb, settings)) { writer.WriteNode(reader, false); } Encoding utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); File.WriteAllText(filename, sb.ToString(), utf8); }
(注:可去掉writer.Close(),using块会自动释放资源)
补充:为什么标签间有空白时写入器无法格式化?
XmlWriter的Indent功能是补充空白而非替换空白。如果元素之间已经存在空白文本(比如第一次格式化后留下的换行、缩进),XmlReader会将其视为文档的一部分内容,XmlWriter会原样输出这些内容,不会用新的缩进规则去替换。只有当读取器忽略了这些空白,写入器才会重新控制整个文档的排版,应用新的缩进配置。
内容的提问来源于stack exchange,提问作者GoWiser
相关产品推荐
相关产品推荐

