791
votes

Is it possible to have multi-line strings in JSON?

It's mostly for visual comfort so I suppose I can just turn word wrap on in my editor, but I'm just kinda curious.

I'm writing some data files in JSON format and would like to have some really long string values split over multiple lines. Using python's JSON module I get a whole lot of errors, whether I use \ or \n as an escape.

9
structure your data: break the multiline string into an array of strings, and then join them later on.RubyTuesdayDONO
Try hjson tool. It will convert your multiline String in json to proper json-format.Gaurav

9 Answers

486
votes

JSON does not allow real line-breaks. You need to replace all the line breaks with \n.

eg:

"first line second line"

can saved with:

"first line\nsecond line"

Note:

for Python, this should be written as:

"first line\\nsecond line"

where \\ is for escaping the backslash, otherwise python will treat \n as the control character "new line"

224
votes

I have had to do this for a small Node.js project and found this work-around:

{
 "modify_head": [

  "<script type='text/javascript'>",
  "<!--",
  "  function drawSomeText(id) {",
  "  var pjs = Processing.getInstanceById(id);",
  "  var text = document.getElementById('inputtext').value;",
  "  pjs.drawText(text);}",
  "-->",
  "</script>"

 ],

 "modify_body": [

  "<input type='text' id='inputtext'></input>",
  "<button onclick=drawSomeText('ExampleCanvas')></button>"

 ],
}

This looks quite neat to me, appart from that I have to use double quotes everywhere. Though otherwise, I could, perhaps, use YAML, but that has other pitfalls and is not supported natively. Once parsed, I just use myData.modify_head.join('\n') or myData.modify_head.join(), depending upon whether I want a line break after each string or not.

213
votes

Unfortunately many of the answers here address the question of how to put a newline character in the string data. The question is how to make the code look nicer by splitting the string value across multiple lines of code. (And even the answers that recognize this provide "solutions" that assume one is free to change the data representation, which in many cases one is not.)

And the worse news is, there is no good answer.

In many programming languages, even if they don't explicitly support splitting strings across lines, you can still use string concatenation to get the desired effect; and as long as the compiler isn't awful this is fine.

But json is not a programming language; it's just a data representation. You can't tell it to concatenate strings. Nor does its (fairly small) grammar include any facility for representing a string on multiple lines.

Short of devising a pre-processor of some kind (and I, for one, don't feel like effectively making up my own language to solve this issue), there isn't a general solution to this problem. IF you can change the data format, then you can substitute an array of strings. Otherwise, this is one of the numerous ways that json isn't designed for human-readability.

116
votes

Check out the specification! The JSON grammar's char production can take the following values:

  • any-Unicode-character-except-"-or-\-or-control-character
  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u four-hex-digits

Newlines are "control characters" so, no, you may not have a literal newline within your string. However you may encode it using whatever combination of \n and \r you require.

63
votes

JSON doesn't allow breaking lines for readability.

Your best bet is to use an IDE that will line-wrap for you.

51
votes

This is a really old question, but I came across this on a search and I think I know the source of your problem.

JSON does not allow "real" newlines in its data; it can only have escaped newlines. See the answer from @YOU. According to the question, it looks like you attempted to escape line breaks in Python two ways: by using the line continuation character ("\") or by using "\n" as an escape.

But keep in mind: if you are using a string in python, special escaped characters ("\t", "\n") are translated into REAL control characters! The "\n" will be replaced with the ASCII control character representing a newline character, which is precisely the character that is illegal in JSON. (As for the line continuation character, it simply takes the newline out.)

So what you need to do is to prevent Python from escaping characters. You can do this by using a raw string (put r in front of the string, as in r"abc\ndef", or by including an extra slash in front of the newline ("abc\\ndef").

Both of the above will, instead of replacing "\n" with the real newline ASCII control character, will leave "\n" as two literal characters, which then JSON can interpret as a newline escape.

19
votes

Write property value as a array of strings. Like example given over here https://gun.io/blog/multi-line-strings-in-json/. This will help.

We can always use array of strings for multiline strings like following.

{
    "singleLine": "Some singleline String",
    "multiline": ["Line one", "line Two", "Line Three"]
} 

And we can easily iterate array to display content in multi line fashion.

0
votes

While not standard, I found that some of the JSON libraries have options to support multiline Strings. I am saying this with the caveat, that this will hurt your interoperability.

However in the specific scenario I ran into, I needed to make a config file that was only ever used by one system readable and manageable by humans. And opted for this solution in the end.

Here is how this works out on Java with Jackson:

JsonMapper mapper = JsonMapper.builder()
   .enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS)
   .build()
0
votes

Try this, it also handles the single quote which is failed to parse by JSON.parse() method and also supports the UTF-8 character code.

    parseJSON = function() {
        var data = {};
        var reader = new FileReader();
        reader.onload = function() {
            try {
                data = JSON.parse(reader.result.replace(/'/g, "\""));
            } catch (ex) {
                console.log('error' + ex);
            }
        };
        reader.readAsText(fileSelector_test[0].files[0], 'utf-8');
}