JSON.NET:在不重新解析的情况下缩小/格式化内容

Ari*_*oth 8 c# json json.net

是否可以使用Newtonsoft JSON.NET库缩小/格式化JSON字符串而不强制系统重新解析代码?这就是我的方法:

public async Task<string> Minify(string json)
{
    // TODO: Some way to do this without a re-parse?
    var jsonObj = await JsonOpener.GetJsonFromString(json);
    return jsonObj.ToString(Formatting.None);
}

public async Task<string> Beautify(string json)
{
    // TODO: Some way to do this without a re-parse?
    var jsonObj = await JsonOpener.GetJsonFromString(json);
    return FormatJson(jsonObj);
}

private string FormatJson(JToken input)
{
    // We could just do input.ToString(Formatting.Indented), but this allows us
    // to take advantage of JsonTextWriter's formatting options.
    using (var stringWriter = new StringWriter(new StringBuilder()))
    {
        using (var jsonWriter = new JsonTextWriter(stringWriter))
        {
            // Configures indentation character and indentation width
            // (e.g., "indent each level using 2 spaces", or "use tabs")
            ConfigureWriter(jsonWriter);
            var serializer = new JsonSerializer();
            serializer.Serialize(jsonWriter, input);

            return stringWriter.ToString();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码在JSON的小块中运行得很好,但它开始陷入大块内容的困境.如果我可以在不必通过解析器的情况下删除所有内容,那么它会更快,我想.

如果我必须重新发明轮子并剥离所有空白或者我自己,我会,但我不知道是否有任何陷阱发挥作用.

就此而言,还有另一个更适合这个的图书馆吗?

编辑:我的不好,JSON本身不支持评论.

Bri*_*ers 6

是的,您可以使用 Json.Net 执行此操作。只需将 aJsonTextReader直接连接到 a JsonTextWriter。这样您就可以重用读取器的标记器逻辑和写入器的格式化逻辑,但是您跳过了将标记转换为中间对象表示并返回的步骤(这是耗时的部分)。

以下是我将其分解为辅助方法以使其使用起来非常简单和灵活的方法:

public static string Minify(string json)
{
    return ReformatJson(json, Formatting.None);
}

public static string Beautify(string json)
{
    return ReformatJson(json, Formatting.Indented);
}

public static string ReformatJson(string json, Formatting formatting)
{
    using (StringReader stringReader = new StringReader(json))
    using (StringWriter stringWriter = new StringWriter())
    {
        ReformatJson(stringReader, stringWriter, formatting);
        return stringWriter.ToString();
    }
}

public static void ReformatJson(TextReader textReader, TextWriter textWriter, Formatting formatting)
{
    using (JsonReader jsonReader = new JsonTextReader(textReader))
    using (JsonWriter jsonWriter = new JsonTextWriter(textWriter))
    {
        jsonWriter.Formatting = formatting;
        jsonWriter.WriteToken(jsonReader);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个简短的演示:https : //dotnetfiddle.net/RevZNU

使用此设置,如果需要,您也可以轻松添加适用于流的其他重载。例如:

public static void Minify(Stream inputStream, Stream outputStream, Encoding encoding = null)
{
    ReformatJson(inputStream, outputStream, Formatting.None, encoding);
}

public static void Beautify(Stream inputStream, Stream outputStream, Encoding encoding = null)
{
    ReformatJson(inputStream, outputStream, Formatting.Indented, encoding);
}

public static void ReformatJson(Stream inputStream, Stream outputStream, Formatting formatting, Encoding encoding = null)
{
    if (encoding == null)
        encoding = new UTF8Encoding(false);

    const int bufferSize = 1024;
    using (StreamReader streamReader = new StreamReader(inputStream, encoding, true, bufferSize, true))
    using (StreamWriter streamWriter = new StreamWriter(outputStream, encoding, bufferSize, true))
    {
        ReformatJson(streamReader, streamWriter, formatting);
    }
}
Run Code Online (Sandbox Code Playgroud)