সি # তে জেএসএন ফরমেটার?


100

এমন কোনও ফাংশন সন্ধান করছেন যা কোনও stringজসনকে ইনপুট হিসাবে গ্রহণ করবে এবং এটিকে লাইন ব্রেক এবং ইন্ডেন্টেশন সহ ফর্ম্যাট করবে। বৈধতা বোনাস হবে, তবে এটি প্রয়োজনীয় নয় এবং আমার এটি কোনও বস্তু বা কোনও কিছুর মধ্যে পার্স করার দরকার নেই।

এমন লাইব্রেরি কি কেউ জানেন?


নমুনা ইনপুট:

{"status":"OK", "results":[ {"types":[ "locality", "political"], "formatted_address":"New York, NY, USA", "address_components":[ {"long_name":"New York", "short_name":"New York", "types":[ "locality", "political"]}, {"long_name":"New York", "short_name":"New York", "types":[ "administrative_area_level_2", "political"]}, {"long_name":"New York", "short_name":"NY", "types":[ "administrative_area_level_1", "political"]}, {"long_name":"United States", "short_name":"US", "types":[ "country", "political"]}], "geometry":{"location":{"lat":40.7143528, "lng":-74.0059731}, "location_type":"APPROXIMATE", "viewport":{"southwest":{"lat":40.5788964, "lng":-74.2620919}, "northeast":{"lat":40.8495342, "lng":-73.7498543}}, "bounds":{"southwest":{"lat":40.4773990, "lng":-74.2590900}, "northeast":{"lat":40.9175770, "lng":-73.7002720}}}}]} 

উত্তর:


123

আমি পুরানো সংস্করণ আপডেট করেছি, এখন এটি পূর্ণসংখ্যা এবং বুলিয়ানগুলির মতো অব্যক্ত মানগুলিকে সমর্থন করবে।

আমি পূর্ববর্তী সংস্করণটি রিফ্যাক্ট করেছিলাম এবং চূড়ান্ত সংস্করণটি পেয়েছি: কোডটি সংক্ষিপ্ত এবং ক্লিনার। কেবলমাত্র একটি এক্সটেনশন পদ্ধতি প্রয়োজন। সর্বাধিক গুরুত্বপূর্ণ: কিছু বাগ স্থির করা হয়েছে।

class JsonHelper
{
    private const string INDENT_STRING = "    ";
    public static string FormatJson(string str)
    {
        var indent = 0;
        var quoted = false;
        var sb = new StringBuilder();
        for (var i = 0; i < str.Length; i++)
        {
            var ch = str[i];
            switch (ch)
            {
                case '{':
                case '[':
                    sb.Append(ch);
                    if (!quoted)
                    {
                        sb.AppendLine();
                        Enumerable.Range(0, ++indent).ForEach(item => sb.Append(INDENT_STRING));
                    }
                    break;
                case '}':
                case ']':
                    if (!quoted)
                    {
                        sb.AppendLine();
                        Enumerable.Range(0, --indent).ForEach(item => sb.Append(INDENT_STRING));
                    }
                    sb.Append(ch);
                    break;
                case '"':
                    sb.Append(ch);
                    bool escaped = false;
                    var index = i;
                    while (index > 0 && str[--index] == '\\')
                        escaped = !escaped;
                    if (!escaped)
                        quoted = !quoted;
                    break;
                case ',':
                    sb.Append(ch);
                    if (!quoted)
                    {
                        sb.AppendLine();
                        Enumerable.Range(0, indent).ForEach(item => sb.Append(INDENT_STRING));
                    }
                    break;
                case ':':
                    sb.Append(ch);
                    if (!quoted)
                        sb.Append(" ");
                    break;
                default:
                    sb.Append(ch);
                    break;
            }
        }
        return sb.ToString();
    }
}

static class Extensions
{
    public static void ForEach<T>(this IEnumerable<T> ie, Action<T> action)
    {
        foreach (var i in ie)
        {
            action(i);
        }
    }
}

ওহ .. আমি আমার পুরানো সংস্করণ তাকিয়ে ছিল। আচ্ছা ভালো. তবুও দুর্দান্ত: ডি স্পষ্টতই আমি এখনও কোনও উত্তরে স্বীকৃতি পাইনি, তাই জিজে! আপনি চেক পেতে।
এমপেন

আপনার এক মাইনর বাগ: "url":"url('http://google.com')"ফর্ম্যাট থেকে বাদে খুব সুন্দর "url":"url('http : //google.com')"। দ্বিতীয় ":" এর আগে এবং পরে স্পেস যুক্ত করা হয় যা ভুল।
পিটার লং

এটি কি সত্যিই পূর্ণসংখ্যার মতো অসমাপ্ত মানগুলিতে কাজ করছে?
জোহান ড্যানফোর্থ

@ জোহানডানফোর্থ - একবার আমি লাইন # 64 ("যদি (উদ্ধৃত)" বিট) সরিয়ে ফেলেছি তবে মনে হয় এটি আমার জন্য অব্যক্ত মানের সাথে ভাল কাজ করছে।
জেরুয়েট

কেন ব্যবহার করবেন .ToList()উপর IEnumerableনতুন পদ্ধতি তৈরি করার পরিবর্তে? আপনি ব্যবহার করছেন যদি MoreLinqআপনার প্রকল্পের মধ্যে, এটি সমর্থন করবে .ForEach()উপর IEnumerableবাক্সের বাইরে।
কেহলান ক্রুমমে

122

আপনি এর জন্য নিউটনসফট.জসন লাইব্রেরিটিও ব্যবহার করতে পারেন এবং ফরম্যাটিংয়ের সাথে সিরিয়ালাইজ অবজেক্টটি কল করতে পারেন Iএন্টেন্টেড এনাম -

var x = JsonConvert.SerializeObject(jsonString, Formatting.Indented);

ডকুমেন্টেশন: সিরিজ একটি বিষয়


হালনাগাদ -

শুধু আবার চেষ্টা করে দেখুন। খুব নিশ্চিত যে এটি কাজ করত - সম্ভবত এটি পরবর্তী সংস্করণে পরিবর্তিত হয়েছিল বা সম্ভবত আমি কেবল জিনিসগুলি কল্পনা করছি। যাইহোক, নীচের মতামত অনুসারে, এটি প্রত্যাশার মতো কার্যকরভাবে কাজ করে না। এটিগুলি অবশ্য (লিঙ্কপ্যাডে কেবল পরীক্ষিত)। প্রথমটি মন্তব্যগুলি থেকে, ২ য়টি একটি উদাহরণ যা আমি অন্য কোথাও এসওতে পেয়েছি -

void Main()
{
    //Example 1
    var t = "{\"x\":57,\"y\":57.0,\"z\":\"Yes\"}";
    var obj = Newtonsoft.Json.JsonConvert.DeserializeObject(t); 
    var f = Newtonsoft.Json.JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented);
    Console.WriteLine(f);

    //Example 2
    JToken jt = JToken.Parse(t);
    string formatted = jt.ToString(Newtonsoft.Json.Formatting.Indented);
    Console.WriteLine(formatted);

    //Example 2 in one line -
    Console.WriteLine(JToken.Parse(t).ToString(Newtonsoft.Json.Formatting.Indented));
}

8
ভিনস - সত্য, তবে যদি আপনি এটি করতে যাচ্ছেন তবে এর অর্থ সম্ভবত আপনি অন্যান্য জেএসওন স্টাফগুলিও করতে যাচ্ছেন এবং যদি তা হয় তবে তা বোধগম্য হবে। তা না হলেও, আমি যুক্তি দিয়েছি যে বেশিরভাগ ক্ষেত্রে আপনার নিজের প্রিন্টারের ঘূর্ণায়মানের চেয়ে আরও বেশি চেষ্টা করা দরকার যার জন্য আরও বেশি প্রচেষ্টা প্রয়োজন :)
ফ্রাঙ্ক তজানাবেটিস

6
এটা কাজ করে না. ইতিমধ্যে এইভাবে জসন করা একটি স্ট্রিং সিরিয়ালিং করা এমনকি এটি বিন্যাস করা হবে না, এমনকি বিন্যাসকরণের সাথেও I এটি কেবল স্ট্রিংটি উদ্ধৃত করে এবং বিদ্যমান সমস্ত উদ্ধৃতিগুলি থেকে বেরিয়ে যায়।
রস

রস - তুমি কি চেষ্টা করেছ? আপনি যখন এটির সাথে ফরম্যাটিং.এন্টেন্টযুক্ত বিকল্পটি ব্যবহার করেন, এটি JSON স্ট্রিংটিকে "প্রিন্ট করে"।
ফ্রাঙ্ক তাজানাবিটিস

8
আমি উপরের কোডটি চেষ্টা করেছিলাম এবং একই (ভুল) ফলাফল পেয়েছি - আমার জন্য var obj = JsonConvert.DeserializeObject(jsonString); var formatted = JsonConvert.SerializeObject(obj, Formatting.Indented) স্থিরিকরণটি ছিল: (অর্থাত্‍ একটি অস্থায়ী বস্তুতে ডিসরিয়ালাইজ করা, তারপরে জেসসনে ফিরে আসা) - সত্যিই সবচেয়ে কার্যকর পদ্ধতি নয়, তবে এটি কমপক্ষে কাজ করেছিল!
বেনজিমাস

59

Json.net লাইব্রেরির জন্য সংক্ষিপ্ত নমুনা।

using Newtonsoft.Json;

private static string format_json(string json)
{
    dynamic parsedJson = JsonConvert.DeserializeObject(json);
    return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
}

পিএস: আপনি html পৃষ্ঠায় রয়েছে তেমন মুদ্রণের জন্য ট্যাগযুক্ত ফর্ম্যাটড জসন পাঠ্যটি মোড়ানো করতে পারেন।


Newtonsoft.Json সংস্করণ 6. সঙ্গে আমার জন্য দুর্দান্ত কাজ
Rocklan

Newtonsoft.Json সংস্করণ 10.0.3 সঙ্গে ভাল কাজ করে Works উইন 10 ইন্টেল আই 7-7700 সিপিইউতে (4.20 গিগাহার্টজ) 5 সেকেন্ডের নীচে 6 এমবি জেএসএন ফাইল ফর্ম্যাট করা হয়েছে।
batpox

35

এখানে একটি JSON বিউটিফায়ারের একটি কমপ্যাক্ট সংস্করণ।

private const string INDENT_STRING = "    ";

static string FormatJson(string json) {

    int indentation = 0;
    int quoteCount = 0;
    var result = 
        from ch in json
        let quotes = ch == '"' ? quoteCount++ : quoteCount
        let lineBreak = ch == ',' && quotes % 2 == 0 ? ch + Environment.NewLine +  String.Concat(Enumerable.Repeat(INDENT_STRING, indentation)) : null
        let openChar = ch == '{' || ch == '[' ? ch + Environment.NewLine + String.Concat(Enumerable.Repeat(INDENT_STRING, ++indentation)) : ch.ToString()
        let closeChar = ch == '}' || ch == ']' ? Environment.NewLine + String.Concat(Enumerable.Repeat(INDENT_STRING, --indentation)) + ch : ch.ToString()
        select lineBreak == null    
                    ? openChar.Length > 1 
                        ? openChar 
                        : closeChar
                    : lineBreak;

    return String.Concat(result);
}

আউটপুট:

 {
    "status":"OK",
     "results":[
         {
            "types":[
                 "locality",
                 "political"
            ],
             "formatted_address":"New York, NY, USA",
             "address_components":[
                 {
                    "long_name":"New York",
                     "short_name":"New York",
                     "types":[
                         "locality",
                         "political"
                    ]
                },
                 {
                    "long_name":"New York",
                     "short_name":"New York",
                     "types":[
                         "administrative_area_level_2",
                         "political"
                    ]
                },
                 {
                    "long_name":"New York",
                     "short_name":"NY",
                     "types":[
                         "administrative_area_level_1",
                         "political"
                    ]
                },
                 {
                    "long_name":"United States",
                     "short_name":"US",
                     "types":[
                         "country",
                         "political"
                    ]
                }
            ],
             "geometry":{
                "location":{
                    "lat":40.7143528,
                     "lng":-74.0059731
                },
                 "location_type":"APPROXIMATE",
                 "viewport":{
                    "southwest":{
                        "lat":40.5788964,
                         "lng":-74.2620919
                    },
                     "northeast":{
                        "lat":40.8495342,
                         "lng":-73.7498543
                    }
                },
                 "bounds":{
                    "southwest":{
                        "lat":40.4773990,
                         "lng":-74.2590900
                    },
                     "northeast":{
                        "lat":40.9175770,
                         "lng":-73.7002720
                    }
                }
            }
        }
    ]
}

2
প্রতিটি অন্যান্য লাইনে আউটপুট 1 স্পেস দ্বারা বন্ধ থাকে এবং এটি কলোনগুলির পরে কিছু স্থান ব্যবহার করতে পারে।
এমপেন

6
আমি বিশ্বাস করতে পারি না @ ভিনস_প্যানুসিওর উত্তরটি কেবলমাত্র 3 টি উপভোগ করেছে? এটা খাঁটি প্রতিভা তার লিনক কোডটি নিয়ে ভিজ্যুয়াল স্টুডিওতে পেস্ট করুন, তারপরে পুনরায় শেয়ারারটিকে একটি পদ্ধতি শৃঙ্খলে রূপান্তর করতে ব্যবহার করুন, আপনি কীভাবে সাধারণ ব্যবহার করে একই জিনিস লিখবেন তা দেখুন। নির্বাচন করুন (এক্স ...) নির্বাচন করুন (y) এবং এটি কয়েকটি পৃষ্ঠাগুলি দীর্ঘ ভিনস ভাল হয়েছে, ... খুব ভাল!
স্নোকোড

1
চমৎকার কারুশিল্পের জন্য +1। আমার যতটুকু পছন্দ হয়েছে, (ভাগ করা) প্রোডাকশন কোডের জন্য আমি সম্ভবত এটি বিভক্ত করে পঠনযোগ্যতা / ডিবাগিবিলিটির জন্য ফোরচ লুপে রূপান্তর করব।
ডিগ্রাবার

1
@ স্পেনটি অতিরিক্ত স্থানটি কমা পরে এবং মূল ইনপুটটিতে উদ্ধৃতি হওয়ার আগে স্থান হিসাবে উপস্থিত হবে। সুতরাং, আপনার ইনপুট উপর নির্ভর করে, ymmv।
জেসি চিশলম

1
এটি নিখুঁত ছেলেরা নয়, নিজের প্রকল্পে এটি নির্ধারণ করতে দ্বিধা বোধ করুন
রেজার

8

এমনকি সহজ একটি যা আমি সবে লিখেছি:

public class JsonFormatter
{
    public static string Indent = "    ";

    public static string PrettyPrint(string input)
    {
        var output = new StringBuilder(input.Length * 2);
        char? quote = null;
        int depth = 0;

        for(int i=0; i<input.Length; ++i)
        {
            char ch = input[i];

            switch (ch)
            {
                case '{':
                case '[':
                    output.Append(ch);
                    if (!quote.HasValue)
                    {
                        output.AppendLine();
                        output.Append(Indent.Repeat(++depth));
                    }
                    break;
                case '}':
                case ']':
                    if (quote.HasValue)  
                        output.Append(ch);
                    else
                    {
                        output.AppendLine();
                        output.Append(Indent.Repeat(--depth));
                        output.Append(ch);
                    }
                    break;
                case '"':
                case '\'':
                    output.Append(ch);
                    if (quote.HasValue)
                    {
                        if (!output.IsEscaped(i))
                            quote = null;
                    }
                    else quote = ch;
                    break;
                case ',':
                    output.Append(ch);
                    if (!quote.HasValue)
                    {
                        output.AppendLine();
                        output.Append(Indent.Repeat(depth));
                    }
                    break;
                case ':':
                    if (quote.HasValue) output.Append(ch);
                    else output.Append(" : ");
                    break;
                default:
                    if (quote.HasValue || !char.IsWhiteSpace(ch)) 
                        output.Append(ch);
                    break;
            }
        }

        return output.ToString();
    }
}

প্রয়োজনীয় এক্সটেনশনগুলি:

    public static string Repeat(this string str, int count)
    {
        return new StringBuilder().Insert(0, str, count).ToString();
    }

    public static bool IsEscaped(this string str, int index)
    {
        bool escaped = false;
        while (index > 0 && str[--index] == '\\') escaped = !escaped;
        return escaped;
    }

    public static bool IsEscaped(this StringBuilder str, int index)
    {
        return str.ToString().IsEscaped(index);
    }

নমুনা আউটপুট:

{
    "status" : "OK",
    "results" : [
        {
            "types" : [
                "locality",
                "political"
            ],
            "formatted_address" : "New York, NY, USA",
            "address_components" : [
                {
                    "long_name" : "New York",
                    "short_name" : "New York",
                    "types" : [
                        "locality",
                        "political"
                    ]
                },
                {
                    "long_name" : "New York",
                    "short_name" : "New York",
                    "types" : [
                        "administrative_area_level_2",
                        "political"
                    ]
                },
                {
                    "long_name" : "New York",
                    "short_name" : "NY",
                    "types" : [
                        "administrative_area_level_1",
                        "political"
                    ]
                },
                {
                    "long_name" : "United States",
                    "short_name" : "US",
                    "types" : [
                        "country",
                        "political"
                    ]
                }
            ],
            "geometry" : {
                "location" : {
                    "lat" : 40.7143528,
                    "lng" : -74.0059731
                },
                "location_type" : "APPROXIMATE",
                "viewport" : {
                    "southwest" : {
                        "lat" : 40.5788964,
                        "lng" : -74.2620919
                    },
                    "northeast" : {
                        "lat" : 40.8495342,
                        "lng" : -73.7498543
                    }
                },
                "bounds" : {
                    "southwest" : {
                        "lat" : 40.4773990,
                        "lng" : -74.2590900
                    },
                    "northeast" : {
                        "lat" : 40.9175770,
                        "lng" : -73.7002720
                    }
                }
            }
        }
    ]
}

একটি মাইনর বাগ: এর "url":"url('http://google.com')"ফর্ম্যাট হবে "url":"url('http : //google.com')"
পিটার লং

6

এখানে ইতিমধ্যে বেশ কয়েকটি দুর্দান্ত উত্তর রয়েছে যা নিউটনসফট.জেএসএন ব্যবহার করে , তবে এখানে আরও একটির JObject.Parseসংমিশ্রণে ব্যবহার করা হয় ToString(), যেহেতু এখনও এটি উল্লেখ করা হয়নি:

var jObj = Newtonsoft.Json.Linq.JObject.Parse(json);
var formatted = jObj.ToString(Newtonsoft.Json.Formatting.Indented);

এটির উত্তরটি হওয়া উচিত .. কেবলমাত্র দুটি লাইনের ক্ষেত্রে তবে আপনার ভেরিয়েবল জসন যদি জসন-অবজেক্ট হয়; অন্যথায় পার্স ব্যর্থ হতে পারে যদি যুক্তিটি অ্যারে, স্ট্রিং, নাল ইত্যাদি হয়
joedotnot

6

আমি খুব কম্প্যাক্ট দেখে মুগ্ধ হন তাদেরকে JSON ফরম্যাটার দ্বারা ভিন্স Panuccio
এখানে আমি এখন ব্যবহার করেছি একটি উন্নত সংস্করণ:

public static string FormatJson(string json, string indent = "  ")
{
    var indentation = 0;
    var quoteCount = 0;
    var escapeCount = 0;

    var result =
        from ch in json ?? string.Empty
        let escaped = (ch == '\\' ? escapeCount++ : escapeCount > 0 ? escapeCount-- : escapeCount) > 0
        let quotes = ch == '"' && !escaped ? quoteCount++ : quoteCount
        let unquoted = quotes % 2 == 0
        let colon = ch == ':' && unquoted ? ": " : null
        let nospace = char.IsWhiteSpace(ch) && unquoted ? string.Empty : null
        let lineBreak = ch == ',' && unquoted ? ch + Environment.NewLine + string.Concat(Enumerable.Repeat(indent, indentation)) : null
        let openChar = (ch == '{' || ch == '[') && unquoted ? ch + Environment.NewLine + string.Concat(Enumerable.Repeat(indent, ++indentation)) : ch.ToString()
        let closeChar = (ch == '}' || ch == ']') && unquoted ? Environment.NewLine + string.Concat(Enumerable.Repeat(indent, --indentation)) + ch : ch.ToString()
        select colon ?? nospace ?? lineBreak ?? (
            openChar.Length > 1 ? openChar : closeChar
        );

    return string.Concat(result);
}

এটি নিম্নলিখিত সমস্যাগুলি সমাধান করে:

  1. স্ট্রিংয়ের ভিতরে ক্রমগুলি এড়িয়ে চলুন
  2. কোলনের পরে ফাঁকা স্থানগুলি
  3. কমা পরে অতিরিক্ত স্থান (বা অন্য কোথাও)
  4. স্ট্রিংয়ের ভিতরে স্কোয়ার এবং কোঁকড়া ধনুর্বন্ধনী
  5. নাল ইনপুট ব্যর্থ হয় না

আউটপুট:

{
  "status": "OK",
  "results": [
    {
      "types": [
        "locality",
        "political"
      ],
      "formatted_address": "New York, NY, USA",
      "address_components": [
        {
          "long_name": "New York",
          "short_name": "New York",
          "types": [
            "locality",
            "political"
          ]
        },
        {
          "long_name": "New York",
          "short_name": "New York",
          "types": [
            "administrative_area_level_2",
            "political"
          ]
        },
        {
          "long_name": "New York",
          "short_name": "NY",
          "types": [
            "administrative_area_level_1",
            "political"
          ]
        },
        {
          "long_name": "United States",
          "short_name": "US",
          "types": [
            "country",
            "political"
          ]
        }
      ],
      "geometry": {
        "location": {
          "lat": 40.7143528,
          "lng": -74.0059731
        },
        "location_type": "APPROXIMATE",
        "viewport": {
          "southwest": {
            "lat": 40.5788964,
            "lng": -74.2620919
          },
          "northeast": {
            "lat": 40.8495342,
            "lng": -73.7498543
          }
        },
        "bounds": {
          "southwest": {
            "lat": 40.4773990,
            "lng": -74.2590900
          },
          "northeast": {
            "lat": 40.9175770,
            "lng": -73.7002720
          }
        }
      }
    }
  ]
}

3

আপনার নিজের ফাংশনটি লেখার মূল কারণটি হ'ল জেএসওএন ফ্রেমওয়ার্কগুলি সাধারণত। নেট টাইপগুলিতে স্ট্রিংগুলির পার্সিং সম্পাদন করে সেগুলিকে আবার স্ট্রিংয়ে রূপান্তর করে, যার ফলে মূল স্ট্রিংগুলি হারাতে পারে। উদাহরণস্বরূপ 0.0002 2E-4 হয়

আমি আমার ফাংশন পোস্ট করি না (এটি অন্যদের মতো এখানেও একই) তবে এখানে পরীক্ষার কেসগুলি রয়েছে

using System.IO;

using Newtonsoft.Json;

using NUnit.Framework;

namespace json_formatter.tests
{
    [TestFixture]
    internal class FormatterTests
    {
        [Test]
        public void CompareWithNewtonsofJson()
        {
            string file = Path.Combine(TestContext.CurrentContext.TestDirectory, "json", "minified.txt");

            string json = File.ReadAllText(file);

            string newton = JsonPrettify(json);
            // Double space are indent symbols which newtonsoft framework uses
            string my = new Formatter("  ").Format(json);

            Assert.AreEqual(newton, my);
        }

        [Test]
        public void EmptyArrayMustNotBeFormatted()
        {
            var input = "{\"na{me\": []}";
            var expected = "{\r\n\t\"na{me\": []\r\n}";

            Assert.AreEqual(expected, new Formatter().Format(input));
        }

        [Test]
        public void EmptyObjectMustNotBeFormatted()
        {
            var input = "{\"na{me\": {}}";
            var expected = "{\r\n\t\"na{me\": {}\r\n}";

            Assert.AreEqual(expected, new Formatter().Format(input));
        }

        [Test]
        public void MustAddLinebreakAfterBraces()
        {
            var input = "{\"name\": \"value\"}";
            var expected = "{\r\n\t\"name\": \"value\"\r\n}";

            Assert.AreEqual(expected, new Formatter().Format(input));
        }

        [Test]
        public void MustFormatNestedObject()
        {
            var input = "{\"na{me\":\"val}ue\", \"name1\": {\"name2\":\"value\"}}";
            var expected = "{\r\n\t\"na{me\": \"val}ue\",\r\n\t\"name1\": {\r\n\t\t\"name2\": \"value\"\r\n\t}\r\n}";

            Assert.AreEqual(expected, new Formatter().Format(input));
        }

        [Test]
        public void MustHandleArray()
        {
            var input = "{\"name\": \"value\", \"name2\":[\"a\", \"b\", \"c\"]}";
            var expected = "{\r\n\t\"name\": \"value\",\r\n\t\"name2\": [\r\n\t\t\"a\",\r\n\t\t\"b\",\r\n\t\t\"c\"\r\n\t]\r\n}";
            Assert.AreEqual(expected, new Formatter().Format(input));
        }

        [Test]
        public void MustHandleArrayOfObject()
        {
            var input = "{\"name\": \"value\", \"name2\":[{\"na{me\":\"val}ue\"}, {\"nam\\\"e2\":\"val\\\\\\\"ue\"}]}";
            var expected =
                "{\r\n\t\"name\": \"value\",\r\n\t\"name2\": [\r\n\t\t{\r\n\t\t\t\"na{me\": \"val}ue\"\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"nam\\\"e2\": \"val\\\\\\\"ue\"\r\n\t\t}\r\n\t]\r\n}";
            Assert.AreEqual(expected, new Formatter().Format(input));
        }

        [Test]
        public void MustHandleEscapedString()
        {
            var input = "{\"na{me\":\"val}ue\", \"name1\": {\"nam\\\"e2\":\"val\\\\\\\"ue\"}}";
            var expected = "{\r\n\t\"na{me\": \"val}ue\",\r\n\t\"name1\": {\r\n\t\t\"nam\\\"e2\": \"val\\\\\\\"ue\"\r\n\t}\r\n}";
            Assert.AreEqual(expected, new Formatter().Format(input));
        }

        [Test]
        public void MustIgnoreEscapedQuotesInsideString()
        {
            var input = "{\"na{me\\\"\": \"val}ue\"}";
            var expected = "{\r\n\t\"na{me\\\"\": \"val}ue\"\r\n}";

            Assert.AreEqual(expected, new Formatter().Format(input));
        }

        [TestCase(" ")]
        [TestCase("\"")]
        [TestCase("{")]
        [TestCase("}")]
        [TestCase("[")]
        [TestCase("]")]
        [TestCase(":")]
        [TestCase(",")]
        public void MustIgnoreSpecialSymbolsInsideString(string symbol)
        {
            string input = "{\"na" + symbol + "me\": \"val" + symbol + "ue\"}";
            string expected = "{\r\n\t\"na" + symbol + "me\": \"val" + symbol + "ue\"\r\n}";

            Assert.AreEqual(expected, new Formatter().Format(input));
        }

        [Test]
        public void StringEndsWithEscapedBackslash()
        {
            var input = "{\"na{me\\\\\": \"val}ue\"}";
            var expected = "{\r\n\t\"na{me\\\\\": \"val}ue\"\r\n}";

            Assert.AreEqual(expected, new Formatter().Format(input));
        }

        private static string PrettifyUsingNewtosoft(string json)
        {
            using (var stringReader = new StringReader(json))
            using (var stringWriter = new StringWriter())
            {
                var jsonReader = new JsonTextReader(stringReader);
                var jsonWriter = new JsonTextWriter(stringWriter)
                                {
                                    Formatting = Formatting.Indented
                                };
                jsonWriter.WriteToken(jsonReader);
                return stringWriter.ToString();
            }
        }
    }
}

2

আপনি ছেড়ে যাওয়ার প্রয়োজন \rএবং \nমধ্যে PrettyPrint()। আউটপুটটি মজাদার মনে হচ্ছে কিছু ক্রলফের ইতিমধ্যে উপস্থিত রয়েছে (বা উত্সটি ইতিমধ্যে ফর্ম্যাট করা হয়েছিল)।


2

কিছুটা স্থির করে রেখেছি ...

public class JsonFormatter
{
    #region class members
    const string Space = " ";
    const int DefaultIndent = 0;
    const string Indent = Space + Space + Space + Space;
    static readonly string NewLine = Environment.NewLine;
    #endregion

    private enum JsonContextType
    {
        Object, Array
    }

    static void BuildIndents(int indents, StringBuilder output)
    {
        indents += DefaultIndent;
        for (; indents > 0; indents--)
            output.Append(Indent);
    }


    bool inDoubleString = false;
    bool inSingleString = false;
    bool inVariableAssignment = false;
    char prevChar = '\0';

    Stack<JsonContextType> context = new Stack<JsonContextType>();

    bool InString()
    {
        return inDoubleString || inSingleString;
    }

    public string PrettyPrint(string input)
    {
        var output = new StringBuilder(input.Length * 2);
        char c;

        for (int i = 0; i < input.Length; i++)
        {
            c = input[i];

            switch (c)
            {
                case '{':
                    if (!InString())
                    {
                        if (inVariableAssignment || (context.Count > 0 && context.Peek() != JsonContextType.Array))
                        {
                            output.Append(NewLine);
                            BuildIndents(context.Count, output);
                        }
                        output.Append(c);
                        context.Push(JsonContextType.Object);
                        output.Append(NewLine);
                        BuildIndents(context.Count, output);
                    }
                    else
                        output.Append(c);

                    break;

                case '}':
                    if (!InString())
                    {
                        output.Append(NewLine);
                        context.Pop();
                        BuildIndents(context.Count, output);
                        output.Append(c);
                    }
                    else
                        output.Append(c);

                    break;

                case '[':
                    output.Append(c);

                    if (!InString())
                        context.Push(JsonContextType.Array);

                    break;

                case ']':
                    if (!InString())
                    {
                        output.Append(c);
                        context.Pop();
                    }
                    else
                        output.Append(c);

                    break;

                case '=':
                    output.Append(c);
                    break;

                case ',':
                    output.Append(c);

                    if (!InString() && context.Peek() != JsonContextType.Array)
                    {
                        BuildIndents(context.Count, output);
                        output.Append(NewLine);
                        BuildIndents(context.Count, output);
                        inVariableAssignment = false;
                    }

                    break;

                case '\'':
                    if (!inDoubleString && prevChar != '\\')
                        inSingleString = !inSingleString;

                    output.Append(c);
                    break;

                case ':':
                    if (!InString())
                    {
                        inVariableAssignment = true;
                        output.Append(Space);
                        output.Append(c);
                        output.Append(Space);
                    }
                    else
                        output.Append(c);

                    break;

                case '"':
                    if (!inSingleString && prevChar != '\\')
                        inDoubleString = !inDoubleString;

                    output.Append(c);
                    break;
                case ' ':
                    if (InString())
                        output.Append(c);
                    break;

                default:
                    output.Append(c);
                    break;
            }
            prevChar = c;
        }

        return output.ToString();
    }
}

ধার [মৃত লিঙ্ক]


2

বেঞ্জিমাস নির্দেশিত হিসাবে , আপনি একটি অস্থায়ী অবজেক্টের সাহায্যে নিউটনসফট.জসন ব্যবহার করতে পারেন এবং ডিজিটালাইজ / সিরিয়ালাইজ করতে পারেন।

var obj = JsonConvert.DeserializeObject(jsonString); 
var formatted = JsonConvert.SerializeObject(obj, Formatting.Indented);

1
@ ডিভিডিএমএন অ্যালরেডি দু'বছর আগে একই অ্যাঞ্জার পোস্ট করেছেন
এনটিফ্রেএক্স

2

সমস্ত ক্রেডিট ফ্র্যাঙ্ক তজানাবেটিসের কাছে। তবে এটি সবচেয়ে সংক্ষিপ্ত প্রত্যক্ষ উদাহরণ, এটি খালি স্ট্রিং বা ভাঙা মূল JSON স্ট্রিংয়ের ক্ষেত্রেও বেঁচে থাকে:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

    ...
    private static string Format(string jsonString)
    {
        try
        {
            return JToken.Parse(jsonString).ToString(Formatting.Indented);
        }
        catch
        {
            return jsonString;
        }
    }

2

এটি প্রতিটি আইটেমকে একটি নতুন লাইনে রাখবে

VB.NET

mytext = responseFromServer.Replace("{", vbNewLine + "{")

সি শার্প

mytext = responseFromServer.Replace("{", Environment.NewLine + "{");

1

এটি গ্রহণযোগ্য উত্তরের একটি বৈকল্পিক যা আমি ব্যবহার করতে পছন্দ করি। মন্তব্য করা অংশগুলির ফলাফল যা আমি আরও পঠনযোগ্য ফর্ম্যাট হিসাবে বিবেচনা করি (আপনার পার্থক্যটি দেখার জন্য সংলগ্ন কোডটি মন্তব্য করতে হবে):

public class JsonHelper
{
    private const int INDENT_SIZE = 4;

    public static string FormatJson(string str)
    {
        str = (str ?? "").Replace("{}", @"\{\}").Replace("[]", @"\[\]");

        var inserts = new List<int[]>();
        bool quoted = false, escape = false;
        int depth = 0/*-1*/;

        for (int i = 0, N = str.Length; i < N; i++)
        {
            var chr = str[i];

            if (!escape && !quoted)
                switch (chr)
                {
                    case '{':
                    case '[':
                        inserts.Add(new[] { i, +1, 0, INDENT_SIZE * ++depth });
                        //int n = (i == 0 || "{[,".Contains(str[i - 1])) ? 0 : -1;
                        //inserts.Add(new[] { i, n, INDENT_SIZE * ++depth * -n, INDENT_SIZE - 1 });
                        break;
                    case ',':
                        inserts.Add(new[] { i, +1, 0, INDENT_SIZE * depth });
                        //inserts.Add(new[] { i, -1, INDENT_SIZE * depth, INDENT_SIZE - 1 });
                        break;
                    case '}':
                    case ']':
                        inserts.Add(new[] { i, -1, INDENT_SIZE * --depth, 0 });
                        //inserts.Add(new[] { i, -1, INDENT_SIZE * depth--, 0 });
                        break;
                    case ':':
                        inserts.Add(new[] { i, 0, 1, 1 });
                        break;
                }

            quoted = (chr == '"') ? !quoted : quoted;
            escape = (chr == '\\') ? !escape : false;
        }

        if (inserts.Count > 0)
        {
            var sb = new System.Text.StringBuilder(str.Length * 2);

            int lastIndex = 0;
            foreach (var insert in inserts)
            {
                int index = insert[0], before = insert[2], after = insert[3];
                bool nlBefore = (insert[1] == -1), nlAfter = (insert[1] == +1);

                sb.Append(str.Substring(lastIndex, index - lastIndex));

                if (nlBefore) sb.AppendLine();
                if (before > 0) sb.Append(new String(' ', before));

                sb.Append(str[index]);

                if (nlAfter) sb.AppendLine();
                if (after > 0) sb.Append(new String(' ', after));

                lastIndex = index + 1;
            }

            str = sb.ToString();
        }

        return str.Replace(@"\{\}", "{}").Replace(@"\[\]", "[]");
    }
}

1

শুধু ব্যবহার করুন JsonDocumentএবং Utf8JsonWriterকোনও তৃতীয় পক্ষের লাইব্রেরির প্রয়োজন নেই। jsonStringপ্রয়োজনে deserialization জন্য কোন লক্ষ্য বস্তু ।

using System.IO;
using System.Text;
using System.Text.Json;

// other code ...

public string Prettify(string jsonString)
{
    using var stream = new MemoryStream();
    var document = JsonDocument.Parse(jsonString);
    var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true });
    document.WriteTo(writer);
    writer.Flush();
    return Encoding.UTF8.GetString(stream.ToArray());
}

আপনি কি মনে JsonDocument.Parseকরেন? অবশ্যই যে এটি deserializes?
এমপেন

0

জে ব্রায়ান প্রাইস, একটি ভাল উদাহরণ তবে ত্রুটি রয়েছে

{\"response\":[123, 456, {\"name\":\"John\"}, {\"count\":3}]}

বিন্যাস পরে

{
    "response" : [
        123,
         456,
         {
            "name" : "John"
        },
         {
            "count" : 3
        }
    ]
}

অনুপযুক্ত পক্ষপাত :(


0

উদাহরণ

    public static string JsonFormatter(string json)
    {
        StringBuilder builder = new StringBuilder();

        bool quotes = false;

        bool ignore = false;

        int offset = 0;

        int position = 0;

        if (string.IsNullOrEmpty(json))
        {
            return string.Empty;
        }

        json = json.Replace(Environment.NewLine, "").Replace("\t", "");

        foreach (char character in json)
        {
            switch (character)
            {
                case '"':
                    if (!ignore)
                    {
                        quotes = !quotes;
                    }
                    break;
                case '\'':
                    if (quotes)
                    {
                        ignore = !ignore;
                    }
                    break;
            }

            if (quotes)
            {
                builder.Append(character);
            }
            else
            {
                switch (character)
                {
                    case '{':
                    case '[':
                        builder.Append(character);
                        builder.Append(Environment.NewLine);
                        builder.Append(new string(' ', ++offset * 4));
                        break;
                    case '}':
                    case ']':
                        builder.Append(Environment.NewLine);
                        builder.Append(new string(' ', --offset * 4));
                        builder.Append(character);
                        break;
                    case ',':
                        builder.Append(character);
                        builder.Append(Environment.NewLine);
                        builder.Append(new string(' ', offset * 4));
                        break;
                    case ':':
                        builder.Append(character);
                        builder.Append(' ');
                        break;
                    default:
                        if (character != ' ')
                        {
                            builder.Append(character);
                        }
                        break;
                }

                position++;
            }
        }

        return builder.ToString().Trim();
    }

0

এই সংস্করণটি JSON উত্পাদন করে যা আরও কমপ্যাক্ট এবং আমার মতে আরও বেশি পঠনযোগ্য কারণ আপনি একবারে আরও দেখতে পাচ্ছেন। এটি গভীরতম স্তর ইনলাইন বিন্যাস করে বা একটি কমপ্যাক্ট অ্যারে কাঠামোর মতো করে এটি করে।

কোডটির কোনও নির্ভরতা নেই তবে এটি আরও জটিল।

{ 
  "name":"Seller", 
  "schema":"dbo",
  "CaptionFields":["Caption","Id"],
  "fields":[ 
    {"name":"Id","type":"Integer","length":"10","autoincrement":true,"nullable":false}, 
    {"name":"FirstName","type":"Text","length":"50","autoincrement":false,"nullable":false}, 
    {"name":"LastName","type":"Text","length":"50","autoincrement":false,"nullable":false}, 
    {"name":"LotName","type":"Text","length":"50","autoincrement":false,"nullable":true}, 
    {"name":"LotDetailsURL","type":"Text","length":"255","autoincrement":false,"nullable":true} 
  ]
}

কোডটি অনুসরণ করে

private class IndentJsonInfo
{
    public IndentJsonInfo(string prefix, char openingTag)
    {
        Prefix = prefix;
        OpeningTag = openingTag;
        Data = new List<string>();
    }
    public string Prefix;
    public char OpeningTag;
    public bool isOutputStarted;
    public List<string> Data;
}
internal static string IndentJSON(string jsonString, int startIndent = 0, int indentSpaces = 2)
{
    if (String.IsNullOrEmpty(jsonString))
        return jsonString;

    try
    {
        var jsonCache = new List<IndentJsonInfo>();
        IndentJsonInfo currentItem = null;

        var sbResult = new StringBuilder();

        int curIndex = 0;
        bool inQuotedText = false;

        var chunk = new StringBuilder();

        var saveChunk = new Action(() =>
        {
            if (chunk.Length == 0)
                return;
            if (currentItem == null)
                throw new Exception("Invalid JSON: No container.");
            currentItem.Data.Add(chunk.ToString());
            chunk = new StringBuilder();
        });

        while (curIndex < jsonString.Length)
        {
            var cChar = jsonString[curIndex];
            if (inQuotedText)
            {
                // Get the rest of quoted text.
                chunk.Append(cChar);

                // Determine if the quote is escaped.
                bool isEscaped = false;
                var excapeIndex = curIndex;
                while (excapeIndex > 0 && jsonString[--excapeIndex] == '\\') isEscaped = !isEscaped;

                if (cChar == '"' && !isEscaped)
                    inQuotedText = false;
            }
            else if (Char.IsWhiteSpace(cChar))
            {
                // Ignore all whitespace outside of quotes.
            }
            else
            {
                // Outside of Quotes.
                switch (cChar)
                {
                    case '"':
                        chunk.Append(cChar);
                        inQuotedText = true;
                        break;
                    case ',':
                        chunk.Append(cChar);
                        saveChunk();
                        break;
                    case '{':
                    case '[':
                        currentItem = new IndentJsonInfo(chunk.ToString(), cChar);
                        jsonCache.Add(currentItem);
                        chunk = new StringBuilder();
                        break;
                    case '}':
                    case ']':
                        saveChunk();
                        for (int i = 0; i < jsonCache.Count; i++)
                        {
                            var item = jsonCache[i];
                            var isLast = i == jsonCache.Count - 1;
                            if (!isLast)
                            {
                                if (!item.isOutputStarted)
                                {
                                    sbResult.AppendLine(
                                        "".PadLeft((startIndent + i) * indentSpaces) +
                                        item.Prefix + item.OpeningTag);
                                    item.isOutputStarted = true;
                                }
                                var newIndentString = "".PadLeft((startIndent + i + 1) * indentSpaces);
                                foreach (var listItem in item.Data)
                                {
                                    sbResult.AppendLine(newIndentString + listItem);
                                }
                                item.Data = new List<string>();
                            }
                            else // If Last
                            {
                                if (!(
                                    (item.OpeningTag == '{' && cChar == '}') ||
                                    (item.OpeningTag == '[' && cChar == ']')
                                   ))
                                {
                                    throw new Exception("Invalid JSON: Container Mismatch, Open '" + item.OpeningTag + "', Close '" + cChar + "'.");
                                }

                                string closing = null;
                                if (item.isOutputStarted)
                                {
                                    var newIndentString = "".PadLeft((startIndent + i + 1) * indentSpaces);
                                    foreach (var listItem in item.Data)
                                    {
                                        sbResult.AppendLine(newIndentString + listItem);
                                    }
                                    closing = cChar.ToString();
                                }
                                else
                                {
                                    closing =
                                        item.Prefix + item.OpeningTag +
                                        String.Join("", currentItem.Data.ToArray()) +
                                        cChar;
                                }

                                jsonCache.RemoveAt(i);
                                currentItem = (jsonCache.Count > 0) ? jsonCache[jsonCache.Count - 1] : null;
                                chunk.Append(closing);
                            }
                        }
                        break;
                    default:
                        chunk.Append(cChar);
                        break;
                }
            }
            curIndex++;
        }

        if (inQuotedText)
            throw new Exception("Invalid JSON: Incomplete Quote");
        else if (jsonCache.Count != 0)
            throw new Exception("Invalid JSON: Incomplete Structure");
        else
        {
            if (chunk.Length > 0)
                sbResult.AppendLine("".PadLeft(startIndent * indentSpaces) + chunk);
            var result = sbResult.ToString();
            return result;
        }
    }
    catch (Exception ex)
    {
        throw;  // Comment out to return unformatted text if the format failed.
        // Invalid JSON, skip the formatting.
        return jsonString;
    }
}

ফাংশনটি আপনাকে ইন্ডেন্টেশনের জন্য একটি প্রাথমিক পয়েন্ট নির্দিষ্ট করার অনুমতি দেয় কারণ আমি এটি এমন একটি প্রক্রিয়ার অংশ হিসাবে ব্যবহার করি যা খুব বড় JSON ফর্ম্যাট ব্যাকআপ ফাইলগুলিকে একত্রিত করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.