BACKGROUND
I get a lot of xml files that contain no newlines and to quickly format them I use the function below.

SCENARIO
When I run the tool the first time on a file that contains no newlines (and no insignificant whitespace) then it works as expected:

Convert("myfile.xml", "  ");

如果我对刚刚格式化的同一文件再次运行该工具以增加收件箱,则收件箱不会更改:

Convert("myfile.xml", "    ");

QUESTION
Why is the file not formatted the second time I run the function? How do I make sure the function always formats the file?

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 sb = new StringBuilder();
    using (var reader = XmlReader.Create(new StringReader(input_string)))
    using (var writer = XmlWriter.Create(sb, settings))
    {
        writer.WriteNode(reader, false);
        writer.Close();
    }
    File.Delete(filename);
    Encoding utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
    File.WriteAllText(filename, sb.ToString(), utf8);
}

NOTE
If I modify the reader to ignore whitespace then the writer can format the output correctly:

XmlReader.Create(new StringReader(input_string),
                 new XmlReaderSettings { IgnoreWhitespace = true })

但我仍然想知道为什么当标签之间存在微不足道的空白时,作者未能格式化输出.

推荐答案

问题是,如果读者保留的是微不足道的空白,那么就作者而言,现在是significant个空白.

因此,它不能添加更多的空白,因为这会改变含义,或者至少,它似乎没有判断正在编写的内部文本是否只是空白.

因此正确的做法确实是首先剥离空白并使用您提到的代码new XmlReaderSettings { IgnoreWhitespace = true })来重写它

顺便说一句,仅仅通过流而不是使用字符串和字符串生成器更有效.我很感激您正在卸载该文件,因此您需要将现有的文件放入字节数组中

var input = File.ReadAllBytes(filename);
var settings = new XmlWriterSettings
{
    NewLineHandling = NewLineHandling.Entitize,
    Indent = true,
    IndentChars = indent,
    NewLineChars = Environment.NewLine
};
Encoding utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

using (var mem = new MemoryStream(input))
using (var sr = new StreamReader(mem, Encoding.UTF8))
using (var reader = XmlReader.Create(sr, new XmlReaderSettings { IgnoreWhitespace = true }))
using (var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None))
using (var sw = new StreamWriter(fs, utf8))
using (var writer = XmlWriter.Create(sw, settings))
{
    writer.WriteNode(reader, false);
}

理想情况下,您还应该写序言

    writer.WriteStartDocument();

Csharp相关问答推荐

Blazor:子编辑表单上的嵌套编辑表单验证

是否可以将gltf转换为字节数组,然后将字节数组转换回文件?

ListaryImportProperty的默认DllImportSearchPathsProperty行为

获取ASP.NET核心身份认证cookie名称

. NET在上一个操作完成之前,在此上下文实例上启动了第二个操作

如何在Visual Studio代码中更改大括号模式{},用于C#语言

无法解析数据库上下文的服务

如何在C#中将对象[*,*]直接转换为字符串[*,*]?

在一个模拟上设置一个方法,该模拟具有一个参数,该参数是一个numc函数表达式

默认情况下,.NET通用主机(Host.CreateDefaultBuilder)中是否包含UseConsoleLifetime?

C#EF Core WHERE IN LINQ FROM LIST WITH.CONTAINS不返回任何内容

如何在实体框架中添加包含列表?

Azure函数中实体框架核心的依赖注入

如何使用NumberFormatInfo

将类移动到新命名空间后更新RavenDB Raven-Clr-Type

Swagger没有显示int?可以为空

在DoubleClick上交换DataGridViewImageColumn的图像和工具提示

如何防止Visual Studio断点以红色突出显示到整行?

在implementationFactory中避免循环依赖

在';、';附近有错误的语法.必须声明标量变量";@Checkin";.';