简体   繁体   中英

Are multi-line strings allowed in JSON?

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.

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"

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.

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.

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\u003c/code> 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.

JSON doesn't allow breaking lines for readability.

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

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.

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.

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

Yes. I just tested this now with my Firefox web browser by pressing F12, clicking console and typing at the bottom of the screen.

x={text:"hello\nworld"}

Object x has just been created from a JSON format string containing a multi-line string.

console.log(x.text)
hello
world

x.text is displayed showing that it is a multi-line string.

These two tests show that Firefox's Javascript interpreter is happy to create and use JSON with multiline strings.

More tests with JSON.stringify and JSON.parse showed the Javascript interpreter can convert an object containing multiline strings to JSON and parse it back again with no problem at all.

I have in the past stored the complete works of Shakespeare as a property in a JSON object and then sent it over the internet, uncorrupted.

Example

Here is a two line string entered over three lines

x={text:"expert\
s\nex\
change"}

We can display the object

console.log(x)

giving

Object { text: "experts\nexchange" }

or the string

console.log(x.text)

giving

experts
exchange

The end of lines in the string result from using \\n and the multiple input lines are achieved using just \\ at the end of the line.

In practice you might want to synchronize your line endings with the ones in the string, eg

x={text:"experts\n\
exchange"}

Multi-Line String Length

console.log("Hello\nWorld".length)
11 
console.log("Hello World".length)
11

Note that the string with the newline is not longer than the string with the space. Even though two characters were typed on the keyboard ('\\' and 'n'), only one character is stored in the string.

Use regex to replace all occurrences of \\r\\n with \\\\n .

This worked for me in scala.

val newstr = str.replace("\r\n", "\\n")

Use json5 (loader) see https://json5.org/ - example (by json5)

{
  lineBreaks: "Look, Mom! \
No \\n's!",
}

If you are willing to use Node.js, you can do this:

module.exports = {

  multilineStr: `

     dis my life 
     it's now or never

  `

}

you can import with Node.js and convert it to JSON easily like so:

echo `node -pe 'JSON.stringify(require("./json-mod.js"))'`

and you get:

{"multilineStr":"\n \n dis my life\n it's now or never\n \n "}

how it works : you use Node.js to load a JS module, which creates a JS object which can easily be JSON stringified by Node.js. The -e option evaluates the string, and the -p option echoes the return result of the last Node.js operation to stdout.

If you want to load a .js script that's in a different working directory, you have to switch the "" and '' strings:

my_script='../json-mod.js'
echo `node -pe "JSON.stringify(require('$my_script'))"`

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()

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');
}

Use an array of strings:

{
    "text": [
"line 1 line 1 line 1 line 1 line 1 line 1 line 1 line 1 ",
"line 2 line 2 line 2 line 2 line 2 line 2 line 2 line 2"
     ]
}

then join them in code:

<your JSON object>.text.join()

You can encode and decode xml strings

{
  "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>

\n\r\n worked for me !!

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

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>
     );
})}}

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.

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. jso.net , 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/jso.net files there and they will be converted online to standard json immediately. Note that jso.net supports much more goodies for templating json files, so it may be useful to look into, depending on your needs.

Try using base64 encoded string value. Worked for me most of the time.

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

after base64 encoded string look like

{
    "singleLine": "Some singleline String",
    "multiline": "TGluZSBvbmUKTGluZSBUd28KTGluZSBUaHJlZQ=="
} 

base64 encoding and decoding is available in all languages.

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.

put the multiline text on txt file and then

var str = {
    text: cat('path_to_file/text.txt')
}

(it work's on mongoDB)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM