Are multi-line strings allowed in JSON?
Asked Answered
S

18

1192

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.

Sjoberg answered 6/3, 2010 at 14:29 Comment(4)
structure your data: break the multiline string into an array of strings, and then join them later on.Suckow
Try hjson tool. It will convert your multiline String in json to proper json-format.Dishonesty
Possible duplicate of Can a JSON value contain a multiline stringMonah
if you have a long string you need to encode so you can pass it as a json string search online for json encoder like nddapp.com/json-encoder.htmlSaguenay
K
695

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.

Kittie answered 28/9, 2018 at 14:35 Comment(9)
It is not clear what the OP wants, newlines in string, or organize string better...Pete
Regarding "The question is how to make the code look nicer by splitting the string value across multiple lines of code ...": for a solution to multi-line statements in Python, see #53662. There is a difference between multi-line JSON and multi-line Python. Multi-line JSON use '\' followed by 'n' in the JSON, i.e. "\n" in the string. Multi-line Python statements, use '\' followed by '\n' i.e. a trailing backslash on the line that is to be continued. Windows format:replace \n with \r\n where appropriate!Septime
In case of package.json/scripts this can be dealt with to some extent by splitting the code into several scripts.Rapturous
This is the right answer that OP really wants, and SO DO ME, even the result sounds not very satisfying about JSON formatter...Fluviatile
Brilliant. This was the answer I was looking for, and moreover, the reminder that json is not a language was helpful to set the problem in context.Petterson
It's very clear what the OP is asking and this is the right answer.Croydon
Sometimes I think that the JSON format was not thoroughly designed. No comments, no multi-line support. I understand it is just a data format, but "to be used by humans". So some "human-friendly" features would be helpful.Tread
@9ilsdx9rvj0lo What is in the OP question I'm writing some data files in JSON format and would like to have some really long string values split over multiple lines. unclear that he wants to organise string better? It's totally clear and understandable.Wulfe
There is one solution: use YAML rather than JSON and if necessary, pre-process the YAML source into a JSON target (or if possible, support YAML directly in whatever application is reading the data files).Paolo
G
632

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

eg:

"first line
second line"

can be 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"

Glutelin answered 6/3, 2010 at 15:4 Comment(10)
@user359996 I'm not sure that's true. For me (storing data in JSON with just \n and outputting it via Curses), \n seems to work okay. It depends on the view/rendering engine, it seems.Nephrolith
Newline sequences are indeed platform-specific (cf. en.wikipedia.org/wiki/Newline#Representations). However, per @Lightness Races in Orbit's answer, neither cursor-return nor line-feed characters are in the JSON grammar. I'm actually not a Python programmer, so I'm not sure what's going on in your case, but either your parser is broken or you're not passing it what you think your are. Maybe this answer explains it better: https://mcmap.net/q/46744/-python-json-loads-fails-with-valueerror-invalid-control-character-at-line-1-column-33-char-33. Note especially the bit about double escaping.Sissified
@user359996: "neither cursor-return nor line-feed characters are in the JSON grammar." Well, as per the grammar, both \n and \r are allowed to be valid char in json-string.Vanillic
@Nawaz: "\n" and "\r" are escape sequences for linefeed and carriage return, respectively. They are not the literal linefeed and carriage-return control characters. As an additional example to make it more clear, consider that "\\" is an escape sequence for backslash, as opposed to a literal backslash. The JSON grammar explicitly excludes control characters (cf. the "char" definition), and instead provides for their representation via escape sequences (\\, \r, \n, etc.).Sissified
@user359996: Yes.. I saw that later on, though I'm keeping my old comment as such, in case anybody else comes up with the same doubt, our discussion might help them. thanks for confirming it BTW.Vanillic
I also have long lines of text in single variable within JSON file. After 10 minutes reading these answers, for case like mine I think turning word-wrap on is best solution. I want the \n new lines at end of sentences only in my JSON phrases, I don't want to add \n new lines in JSON, then have to get rid of them in horribly complex manner on parsing the JSON into the (C# in this case) application.Cormick
The OP didn't want to represent new lines but to format one logical JSON line over multiple source lines. He did muddy the waters by talking about \n. He wants what in the old days we called "continuation lines" pages.mtu.edu/~shene/COURSES/cs201/NOTES/chap01/continue.html.Radarman
Doesn't answer the question.Wulfe
Doesn't answer OP's question, but it answers mine 😁Vesicate
you can just add <br> tags if you output the json value in html later.Particulate
R
249

I have had to do this for a small Node.js project and found this work-around to store multiline strings as array of lines to make it more human-readable (at a cost of extra code to convert them to string later):

{
 "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>"
 
 ],
}

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.

This looks quite neat to me, apart 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.

Reluctivity answered 12/10, 2011 at 18:21 Comment(7)
This is a solution for a specific setting, not necessarily related to the question. What you create there are not multiline strings (which is not possible anyway), but arrays with strings insideChiro
This shows how to insert newline in strings, which does NOT answer the question. This answer does.Eclogite
fgrieu -- one could just as easily concatenate the strings without adding a newline. With that small alteration, it does provide a workaround for multiline strings (as long as you are in control of specifiying the JSON schema). I will try to improve the answer with this.Backlash
Thanks, I like this. I'm going with this for what I'm working on. It looks neat and organized. I'm going to have each new line in this array imply a line break in the outputted text, although this solution could also work for cases where you don't insert line breaks. I've used this solution before in my javascript source code just because I liked how organized it looks and how it doesn't leave any doubt as to what kinds of whitespace get into the final string.Alena
Notwithstanding the JSON inventor's reservations, I just used this to add comments (without the javascript part, but only the [] and commas) to add comments to help a possible future maintainer who might hand-edit my little JSON file.Hectic
Thanks, this solved my issue with having command line arguments on separate lines in my launch.json in VScode.Ceresin
Still HTML comment markers ("<!--",, "-->",) in a <script> tag. Good old and cool nineties. Netscape 1.0 :) +1 for you.Girlhood
R
146

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.

Refrangible answered 22/5, 2013 at 11:10 Comment(4)
Now it ECMA-404 )) ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdfNikolos
This is the correct answer as it leaves no ambiguity. New lines are allowed, per the specification, so long as they are properly escaped with the control character.Saldivar
@AliKhaki \n in JSON will not accomplish the outcome sought by the question. Either you're thinking of something else (i.e. embedding newline characters), or you're talking about a newline in a string literal (containing JSON) in some programming language, which is again something different.Refrangible
Nope. This does not answer the question. The question is not how to put newline characters into a string. The question is how to distribute a string across multiple lines. And the correct answer is: It is not possible.Ewe
N
103

JSON doesn't allow breaking lines for readability.

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

Nambypamby answered 2/12, 2014 at 18:58 Comment(6)
An editor like BBEdit that supports "soft" line wrap is ideal. It wraps the text so it all appears within the visible area of the editor window, but only the line endings that you type (e.g., hitting carriage return) are persisted in the file when it is saved. Makes it easier to edit JSON with really long strings without having to resort to code tricks or hacks.Eschalot
Sometimes I think that the JSON format was not thoroughly designed. No comments, no multi-line support. I understand it is just a data format, but "to be used by humans". So some "human-friendly" features would be helpful.Tread
Thanks for your answer, which made me smile. That is actually the only correct answer, because the JSON standard is very rigid here and therefore very long texts are difficult to maintain. Why didn't I come up with this simple solution myself? :-)Wulfe
@Tread I totally agree. As it would design some 90 years old programmer who had his best times before the 1st moon landing.Wulfe
Irony is not the best place for a learning platform, although I also needed to smile a short moment.Inducement
Whether JSON was intended to be human-readable (and in that case, I would agree with the comment about the poor design) or not, the fact is that it makes an excellent format for transmitting data (much more compact than XML but still easy to read by specialists). It is not a good format for reading data and it's especially bad for writing configurations because of the limitations mentioned above. YAML, for one, is a language expressly designed for the latter case.Tiresias
N
52

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.

Nepali answered 17/1, 2013 at 18:54 Comment(0)
L
29

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.

Lace answered 7/10, 2015 at 10:37 Comment(8)
I would you suggest you add the information in your answer from the link, Because links can break in future.Bauxite
But them you have an array, not a string. An array is not a string. Period.Pete
Sure, it changes the format. But if the use of multistring is to have some kind of header at the beginning of a JSON file for documentation purposes, it works fine, and human readability is the most important aspect. It looks even better with some indent. pastebin.com/Rs8HSQH5Banal
@EricDuminil This does not work in all use cases. Case and point? VSCode keybindings.json. Incorrect type. Expected "string" will be your result, and the keybinding will not work. When some things want strings to work, they want strings to work. While human readability is important, the correct format is MORE important, or things will, well, break. And when you're coding, the most important thing is that things just work. At the end of the day, a human isn't reading your code. A machine is.Casady
I don't know why this answer is not rated higher. @9ilsdx9rvj0lo: The title talks about plural, which can indeed be an array. Period.Inducement
@BrandonStivers: Normally you can teach a machine new things, so he indeed can specify a format as array and saying that each array entry is a kind of new line. Then implement that in a program. Your remark is true for the moment and for a specific use cases the questioner simply did not ask for. Anyway, good hint in general - that proposed solution cannot be applied in all cases now.Inducement
@Inducement Fair enough point. It depends on the schema that is expected of whatever they are using the json module for. As far as use case, we don't know exactly what they are using it for. All we know is the json module is being used to parse it. We don't know if he has control of the source code of whatever he's parsing the json for. I am sure VSCode isn't the only use case this wouldn't work. As 9ilsdx-9rvj-0lo said in a reply above, an array isn't a string. There's a reason why this is the least-voted answer. "Best Practices." Would this clear a json linter?Casady
nitpick: actually, a string IS an array: an array of chars, with additional methods/interface. An array and string are incompatible with each other in a JSON schema, though.Erbe
N
5

This is a very old question, but I had the same question when I wanted to improve readability of our Vega JSON Specification code which uses complex conditoinal expressions. The code is like this.

As this answer says, JSON is not designed for human. I understand that is a historical decision and it makes sense for data exchange purposes. However, JSON is still used as source code for such cases. So I asked our engineers to use Hjson for source code and process it to JSON.

For example, in Git for Windows environment, you can download the Hjson cli binary and put it in git/bin directory to use. Then, convert (transpile) Hjson source to JSON. To use automation tools such as Make will be useful to generate JSON.

$ which hjson
/c/Program Files/git/bin/hjson

$ cat example.hjson
{
  md:
    '''
    First line.
    Second line.
      This line is indented by two spaces.
    '''
}

$ hjson -j example.hjson > example.json

$ cat example.json
{
  "md": "First line.\nSecond line.\n  This line is indented by two spaces."
}

In case of using the transformed JSON in programming languages, language-specific libraries like hjson-js will be useful.

I noticed the same idea was posted in a duplicated question but I would share a bit more information.

Nicolle answered 12/1, 2023 at 2:0 Comment(1)
Thanks... needed this. Not sure I want to save Hjson or not... Seems more nice to let the software do the thinking, not my IDE.Antistrophe
F
4

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()
Fra answered 31/8, 2020 at 19:6 Comment(1)
In Python, you can allow loading of json containing multiline strings using the strict argument of json.load: json.load(file_in, strict=False)Back
N
1

Assuming the question has to do with easily editing text files and then manually converting them to json, there are two solutions I found:

  1. hjson (that was mentioned in this previous answer), in which case you can convert your existing json file to hjson format by executing hjson source.json > target.hjson, edit in your favorite editor, and convert back to json hjson -j target.hjson > source.json. You can download the binary here or use the online conversion here.
  2. jsonnet, which does the same, but with a slightly different format (single and double quoted strings are simply allowed to span multiple lines). Conveniently, the homepage has editable input fields so you can simply insert your multiple line json/jsonnet files there and they will be converted online to standard json immediately. Note that jsonnet supports much more goodies for templating json files, so it may be useful to look into, depending on your needs.
Nixon answered 19/1, 2023 at 8:50 Comment(0)
L
1

The reason OP asked is the same reason I ended up here. Had a json file with long text.

In VS Code it's just ALT+Z to turn on word wrapping in a json file. Changing the actual data isn't what you want, if all you really want is to read the contents of the file as a developer.

Lisabeth answered 21/2, 2023 at 20:12 Comment(0)
A
0

You can encode at client side and decode at server side. This will take care of \n and \t characters as well

e.g. I needed to send multiline xml through json

{
  "xml": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CiAgPFN0cnVjdHVyZXM+CiAgICAgICA8aW5wdXRzPgogICAgICAgICAgICAgICAjIFRoaXMgcHJvZ3JhbSBhZGRzIHR3byBudW1iZXJzCgogICAgICAgICAgICAgICBudW0xID0gMS41CiAgICAgICAgICAgICAgIG51bTIgPSA2LjMKCiAgICAgICAgICAgICAgICMgQWRkIHR3byBudW1iZXJzCiAgICAgICAgICAgICAgIHN1bSA9IG51bTEgKyBudW0yCgogICAgICAgICAgICAgICAjIERpc3BsYXkgdGhlIHN1bQogICAgICAgICAgICAgICBwcmludCgnVGhlIHN1bSBvZiB7MH0gYW5kIHsxfSBpcyB7Mn0nLmZvcm1hdChudW0xLCBudW0yLCBzdW0pKQogICAgICAgPC9pbnB1dHM+CiAgPC9TdHJ1Y3R1cmVzPg=="
}

then decode it on server side

public class XMLInput
{
        public string xml { get; set; }
        public string DecodeBase64()
        {
            var valueBytes = System.Convert.FromBase64String(this.xml);
            return Encoding.UTF8.GetString(valueBytes);
        }
}

public async Task<string> PublishXMLAsync([FromBody] XMLInput xmlInput)
{
     string data = xmlInput.DecodeBase64();
}

once decoded you'll get your original xml

<?xml version="1.0" encoding="utf-8" ?>
  <Structures>
       <inputs>
               # This program adds two numbers

               num1 = 1.5
               num2 = 6.3

               # Add two numbers
               sum = num1 + num2

               # Display the sum
               print('The sum of {0} and {1} is {2}'.format(num1, num2, sum))
       </inputs>
  </Structures>
Acosta answered 26/10, 2021 at 9:37 Comment(0)
I
0

I needed to read the last n number of lines (using NodeJS) from my error log, the contents of which looked something like this:

{"environment":"development","level":"ERROR","message":"[08-03-2024 16:10:00] | Request failed |......"}
{"environment":"development","level":"ERROR","message":"[08-03-2024 16:10:51] | Request failed |......"}
{"environment":"development","level":"ERROR","message":"[08-03-2024 16:13:14] | Request failed |......"}

There was no reliable way to read this and break/transform it using regex and then map it out to a readable format. And even if there was, as others have said, it's not possible for JSON to have line breaks to "look pretty". The only thing I can rely on is that each row in the log file ends with an \n and that this \n is the only occurrence of itself in any given row.

Anyway, ended up doing something like this:

const pathToLogs = path.join('path', 'to', 'error.log');
const result = {};
require('child_process').execSync(pathToLogs)
    .toString()
    .split('\n')
    .forEach((line, index) => {
        if (line) {
            result[index + 1] = line;
        }
    });

Ended up looking something like this in Postman:

{
    "result": {
        "1": "{\"environment\":\"development\",\"level\":\"ERROR\",\"message\":\"[08-03-2024 16:10:51] | Request failed |.....",
        "2": "{\"environment\":\"development\",\"level\":\"ERROR\",\"message\":\"[08-03-2024 16:13:14] | Request failed |.....",
        "3": "{\"environment\":\"development\",\"level\":\"ERROR\",\"message\":\"[08-03-2024 16:17:10] | Request failed |....."
    }
}

Not the best solution, but sufficient for me.

Identification answered 8/3 at 13:56 Comment(0)
J
-1

\n\r\n worked for me !!

\n for single line break and \n\r\n for double line break

Julianejuliann answered 25/8, 2022 at 16:38 Comment(1)
\\n worked for me.Monochord
N
-1

You can add ‍‍\n for single line break and \n\r\n for double line break.

When you render this JSON object add white-space: pre-line; CSS property to your <div> or <span> tag. This will break your text at \n.

Neptunium answered 26/1 at 4:6 Comment(0)
O
-1

If you aim is just readability for the developer side of things and you don't actually want newlines in the string data, then yes, check if your tooling supports soft wrapping. It's also possible for tooling to render soft linebreaks wherever a \n is in a JSON string, but none of the tools I use actually do that.

Note that JSON5 supports spanning the writing of a string across multiple lines by placing a \ at the end of a line that continues on the next line. This does not actually put a newline character at those places into the JSON string, though you can manually add a \n to get that.


Otherwise, if you actually want the string data to contain a newline where you insert an unescaped newline character in the JSON string, the answer is "no, you can't*".

By Douglas Crockford (the creator of JSON)'s JSON specification, a string cannot contain any of "the 32 control codes".

If you want something more precise, the RFC document (8259) for JSON says:

All Unicode characters may be placed within the quotation marks, except for the characters that MUST be escaped: quotation mark, reverse solidus, and the control characters (U+0000 through U+001F).

So no unescaped, literal carriage returns or line feeds. You can only put a newline (line feed) in JSON strings by using escape sequences (\n), which most tooling will not render as a visual line separator (though that's not to say that they couldn't- just that they usually don't).


* Technically, there is a newline character defined in Unicode that is allowed as an unescaped literal inside a JSON string: U+2028 (see also What is unicode character 2028 (LS / Line Separator) used for? TL;DR "unambiguous newline character"). But it's a relatively obscure codepoint, and your mileage will vary on whether your developer tools will render it as a line separator, or as something else (like �). I just tested with VS Code, and it issues a warning about "unusual line separators", and renders it as �. Also, not just the dev tooling, but since this is actual content, it will be what the rest of the system sees (Ex. machinery that renders the text to a user). Your mileage will vary there as well.

That is to say that this is not really practical as a workaround.

Fun fact: U+2028 is supposedly valid in JSON strings, but not in JavaScript, and some JavaScript bundler tools like Webpack have to do escaping to "put JSON in JS" (here).

Overturn answered 25/3 at 20:14 Comment(0)
R
-2

I see many answers here that may not works in most cases but may be the easiest solution if let's say you wanna output what you wrote down inside a JSON file (for example: for language translations where you wanna have just one key with more than 1 line outputted on the client) can be just adding some special characters of your choice PS: allowed by the JSON files like \\ before the new line and use some JS to parse the text ... like:

Example:

File (text.json)

{"text": "some JSON text. \\ Next line of JSON text"}

import text from 'text.json'
{text.split('\\')
.map(line => {
return (
   <div>
     {line}
     <br />
   </div>
     );
})}}
Rager answered 9/1, 2023 at 17:30 Comment(0)
S
-7

If it's just for presentation in your editor you may use ` instead of " or '

const obj = {
myMultiLineString: `This is written in a \
multiline way. \
The backside of it is that you \
can't use indentation on every new \
line because is would be included in \
your string. \
The backslash after each line escapes the carriage return. 
`
}

Examples:

console.log(`First line \
Second line`);

will put in console:
First line Second line

console.log(`First line 
second line`);

will put in console:
First line
second line

Hope this answered your question.

Selfemployed answered 7/7, 2022 at 9:46 Comment(1)
that's not JSON, that's javascript. Question is about JSON.Vito

© 2022 - 2024 — McMap. All rights reserved.