JSON alternatives (for the purpose of specifying c

2020-07-03 16:55发布

问题:

I like json as a format for configuration files for the software I write. I like that it's lightweight, simple, and widely supported. However, I'm finding that there are some things I'd really like in json that it doesn't have.

Json doesn't have multiline strings or here documents ( http://en.wikipedia.org/wiki/Here_document ), and that is often very awkward when you want your json file to be human-readable and -editable. You can use arrays of strings, but that's a kludgy workaround.

Json doesn't allow comments.

If you look at the formats of unix configuration files, you see a lot of people designing their own awkward formats for things that it would really make more sense to do using some kind of general-purpose thing. For example, here's some code from an Apache config file:

RewriteEngine on
RewriteBase /temp
RewriteCond %{HTTP_ACCEPT} application/xhtml\+xml
RewriteCond %{HTTP_ACCEPT} !application/xhtml\+xml\s*;\s*q=0
RewriteCond %{REQUEST_URI} \.html
RewriteCond %{THE_REQUEST} HTTP/1\.1
RewriteRule t\.html t.xhtml [T=application/xhtml+xml]

Essentially, what's going on here is that they've invented an extremely painful way of writing a boolean function f(w,x,y,z)=w&!x&y&z. You want a logical "or"? They've got some separate (ugly) mechanism for that, too.

What this seems to point toward is some kind of data description language that is simple and Turing-incomplete, but still more expressive, flexible, and convenient than json. Does anyone know of such a language?

To my taste, XML is too complicated, and lisp expressions have the wrong features (Turing-completeness) and lack the right features (here documents, expressive syntax).

[EDIT] The title is misleading. I'm not literally interested in the next iteration of json. I'm not interested in languages that are a subset of javascript. I'm interested in alternative data-description languages.

回答1:

The EDN format is one option based on Clojure literals. It is almost a superset of JSON, except that no special symbol separates keys and values in maps (as : does in JSON); rather, all elements are separated by whitespace and/or a comma and a map is encoded as a list with an even number of elements, enclosed in {..}.

EDN allows for comments (to newline using ;, or to end of the next element read using #_), but not here-docs. It is extensible to new types using a tag notation:

#myapp/Person {:first "Fred" :last "Mertz"}

The argument of the myapp/Person tag (i.e. {:first "Fred" :last "Mertz"}) must be a valid EDN expression, which makes it unextensible to here-doc support.

It has two built-in tags: #inst for timestamps and #uuid. It also supports namespaced symbol (i.e. identifier) and keyword (i.e. map key consts) types; it distinguishes lists (..) and vectors [..]. An element of any type may be used as a key in a map.

In the context of your above problem, one could invent an #apache/rule-or tag which accepts a sequence of elements, whose semantics I leave up to you!



回答2:

Have a look at http://igagis.github.io/stob/

It is even simpler than JSON.

It has C++ style comments.

It is possible to format multiline strings and use escaped new line \n and tab \t chars if "real" new line or tab is needed.

Here is the example snippet:

"String object"
AnotherStringObject
"String with children"{
    "child 1"
    Child2
    "child three"{
        SubChild1
        "Subchild two"

        Property1 {Value1}
        "Property two" {"Value 2"}
        //comment

        /* multi-line
           comment */

        "multi-line
         string"

        "Escape sequences \" \n \r \t \\"
    }

R"qwerty(
This is a
raw string, "Hello world!"
int main(argc, argv){
    int a = 10;
    printf("Hello %d", a);
}
)qwerty"
}


回答3:

There's always what I like to call "real JSON". JSON stands for JavaScript Object Notation, and JavaScript does have comments and something close enough to heredocs.

For the heredoc, you would use JavaScript's E4X inline XML:

{
    longString: <>
                Hello, world!
                This is a long string made possible with the magic of E4X.
                Implementing a parser isn't so difficult.
                </>.toString() // And a comment
    /* And another
       comment */
}

You can use Firefox's JavaScript engine (FF is the only browser to support E4X currently) or you can implement your own parser, which really isn't so difficult.

Here's the E4X quickstart guide, too.



回答4:

The 'J' in JSON is "Javascript". If a particular desired syntax construct isn't in Javascript, then it won't be on JSON.

Heredocs are beyond JSON's purview. That's a language syntax construct for simplified multi-line string definition, but JSON is a transport notation. It has nothing to do with construction. It does, however, have multiline strings, simply by allowing \n newline characters within strings. There's nothing in JSON that says you can't have a linebreak in a string. As long as the containing quote characters are correct, it's perfectly valid. e.g.

{"x":"y\nz"}

is 100% legitimate valid JSON, and is a multiline string, whereas

{"x":"y
z"} 

isn't and will fail on parsing.



回答5:

Since March 2018 you can use JSON5 which seems to have added everything you (& many others) were missing from JSON.

Short Example (JSON5)

{
  // comments
  unquoted: 'and you can quote me on that',
  singleQuotes: 'I can use "double quotes" here',
  lineBreaks: "Look, Mom! \
No \\n's!",
  hexadecimal: 0xdecaf,
  leadingDecimalPoint: .8675309, andTrailing: 8675309.,
  positiveSign: +1,
  trailingComma: 'in objects', andIn: ['arrays',],
  "backwardsCompatible": "with JSON",
}

The JSON5 Data Interchange Format (JSON5) is a superset of JSON that aims to alleviate some of the limitations of JSON by expanding its syntax to include some productions from ECMAScript 5.1.

Summary of Features

The following ECMAScript 5.1 features, which are not supported in JSON, have been extended to JSON5.

Objects

  • Object keys may be an ECMAScript 5.1 IdentifierName.
  • Objects may have a single trailing comma.

Arrays

  • Arrays may have a single trailing comma.

Strings

  • Strings may be single quoted.
  • Strings may span multiple lines by escaping new line characters.
  • Strings may include character escapes.

Numbers

  • Numbers may be hexadecimal.
  • Numbers may have a leading or trailing decimal point.
  • Numbers may be IEEE 754 positive infinity, negative infinity, and NaN.
  • Numbers may begin with an explicit plus sign.

Comments

  • Single and multi-line comments are allowed.

White Space

  • Additional white space characters are allowed.

GitHub: https://github.com/json5/json5



回答6:

One important attribute of JSON (probably the most important) is that you can easily "flip" between the string representation and the representation in object form, and the objects used to represent the object form are relatively simple arrays and maps. This is what makes JSON so useful in a networking context.

The functions you want would conflict with this dual nature of JSON.



回答7:

For configuration you could use an embeddable scripting language, such as lua or python, in fact this is not an uncommon thing to do for configuration. That gives you multiline strings or here documents, and comments. It also makes it easier to have things like the boolean function you describe. However, the scripting languages are, of course, Turing complete.



回答8:

There is also thindf.

Although it does not support comments, they can be emulated via empty keys:

config_var1 = value1
=some comment
config_var2 = value2


标签: json