Home > Software design >  How do I generate new JSON files that may contain a single quote from an old JSON file
How do I generate new JSON files that may contain a single quote from an old JSON file

Time:07-27

I've written some code which has to read through 5,000 JSON files and replace a number which appears twice in each file. It's set to create a new json file and delete the old one, with that, other data must be transferred into the new file too, which is not a problem, however we have a list called attributes that contain some text that use single quotes (for punctuation.) - however when the new json file is written, the text with the single quotes is changed and the single quote is replaced with \u0027

Example: old file contains:"0.png" and "Hen's Secret Bra" which in the new file is changing to "5000.png" correct, and "Hen\u0027s Secret Bra" incorrect. How do I transfer the single quote over properly?

Here is my code:

    using System.Text.Json;
    using System.Web;

internal class Program
{
    private static void Main(string[] args)
   
{
    //get all the json files
    var jsonPath = @"/Users/jasonnienaber/Desktop/nft/cef/official/fatJSONselfFIX/test";
    var jsonFiles = Directory.GetFiles(jsonPath, "*.json");

    //loop through each file and process according to specs
    foreach(var jsonFile in jsonFiles)
    {
        var json = File.ReadAllText(jsonFile);
        var sample = JsonSerializer.Deserialize<Sample>(json);
        var sampleNew = new SampleNew();
        var intCounter = 0;
        var newIntCounter = intCounter 5000;
        var Counter = intCounter.ToString();
        var newCounter = newIntCounter.ToString();

       sampleNew.image = sample.image.Replace(Counter, newCounter);
       sampleNew.name = sample.name.Replace(Counter, newCounter);
       sampleNew.description = sample.description;
       sampleNew.external_url = sample.external_url;
       sampleNew.attributes = sample.attributes;

        // serialize JSON to a string and then write string to a file
        File.Delete(jsonFile);
        File.WriteAllText(jsonFile, JsonSerializer.Serialize(sampleNew));
        intCounter  ;
        
    }

            
}    
        public class Attribute
        {
            public string trait_type { get; set; }
            public string value { get; set; }
    
        }
    
        public class Sample
        {
           // public string dna { get; set; }
            public string image { get; set; }
            public string name { get; set; }
            public string description { get; set; }
            public string external_url { get; set; }
            public List<Attribute> attributes { get; set; }
            public string compiler { get; set; }
        }
    
        public class SampleNew
        {
            public string image { get; set; }
            public string name { get; set; }
            public string description { get; set; }
            public string external_url { get; set; }
            //public List<Attribute> attributes { get; set; }

            public List<Attribute> attributes {get; set;}
        }
}

The "Hen's Secret Bra" is within attributes

CodePudding user response:

Like Jon Skeet mentioned, it's valid to use \u0027, however, you can change the serializer encoding options:

using System.Text.Json;

var obj = new
{
    Name = "John's awesome object",
    Age = 31
};

var options = new JsonSerializerOptions
{
    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};

// writes obj to json file
File.WriteAllText("obj.json", JsonSerializer.Serialize(obj, options));

Outputs

{"Name":"John's awesome object","Age":31}

So in your code, you can do as follows:

var options = new JsonSerializerOptions
{
    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};

//loop through each file and process according to specs
foreach (var jsonFile in jsonFiles)
{
    var json = File.ReadAllText(jsonFile);
    var sample = JsonSerializer.Deserialize<Sample>(json);
    var sampleNew = new SampleNew();
    var intCounter = 0;
    var newIntCounter = intCounter   5000;
    var Counter = intCounter.ToString();
    var newCounter = newIntCounter.ToString();

    sampleNew.image = sample.image.Replace(Counter, newCounter);
    sampleNew.name = sample.name.Replace(Counter, newCounter);
    sampleNew.description = sample.description;
    sampleNew.external_url = sample.external_url;
    sampleNew.attributes = sample.attributes;

    // serialize JSON to a string and then write string to a file
    File.Delete(jsonFile);
    // use serializer options
    File.WriteAllText(jsonFile, JsonSerializer.Serialize(sampleNew, options));
    intCounter  ;
}

See UnsafeRelaxedJsonEscaping

CodePudding user response:

It is better to use Newtonsoft.Json to avoid any problems like this one.

But one of the thing you can try to fix an issue is to use a serialize options

var options = new JsonSerializerOptions
{
    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};

but it is unsafe

Another option is more awkward but more safe, since it affects only one symbol, not any as in the first case

     var attr= new Attribute{trait_type="trait_type", value="Hen's Secret Bra"};    

    attr.value=attr.value.Replace("'","==="); //or you can try something else if you don't like ===

    var json=System.Text.Json.JsonSerializer.Serialize(attr);

    json=json.Replace("===","'");
    
     File.WriteAllText(jsonFile, json);
     
     json = File.ReadAllText(jsonFile);

result

{"trait_type":"trait_type","value":"Hen's Secret Bra"}
  • Related