JSON alternatives (for the purpose of specifying configuration)?

13,399

Solution 1

Have a look at http://github.com/igagis/puu/

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

Solution 2

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!

Solution 3

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

Solution 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.

Solution 5

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.

Share:
13,399

Related videos on Youtube

Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin over 1 year

    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.

    • BalusC
      BalusC almost 12 years
      YAML?
  • remmy
    remmy about 7 years
    "If a particular desired syntax construct isn't in Javascript, then it won't be on JSON." That's cute, but JSON isn't actually a subset of JavaScript, and supports things that JavaScript does not.
  • Abdurrahim
    Abdurrahim over 6 years
    This is love at first sight. It even has raw string literal awesome
  • igagis
    igagis over 6 years
    Glad that you liked it. Unfortunately, raw string support is only implemented in C++ library. C# and Java libs are lacking raw strings support at the moment.
  • Abdurrahim
    Abdurrahim over 6 years
    Guess it's time to collaborate the OS development. Especially C# library needs improvement seems like a C++ developer wrote it :)
  • tav
    tav almost 5 years
    To be fair, comments support in JSON5 is partial, because JSON5 does not preserve comments after saving configuration back in JSON (i.e. you can use comments in JSON5 only for read-only configuration files as JSON5.stringify() returns json without comments).
  • DJDaveMark
    DJDaveMark almost 5 years
    @tav Absolutely, since comments are only for developers. Once you parse the contents, the comments have already been lost. So it's not stringify's fault. That's the way it's supposed to happen. Another example: Compiled Java classes don't contain the comments. Decompile one. You wont find them.
  • Marshal
    Marshal over 4 years
    Lacking native regexp support in JSON5 really puts me off.
  • DJDaveMark
    DJDaveMark over 4 years
    @Marshal Here's the discussion about why native RegExp support didn't make it into JSON5 v1.0. I tend to agree. RegExp as a string is no biggie for me.
  • Marshal
    Marshal over 4 years
    @DJDaveMark Thanks for the link. Is the experimental feature still not in the current JSON5 release? If so the current suggested way of stringify regex is using the replacer function like:? Thanks.
  • Anarchofascist
    Anarchofascist over 1 year
    ToML is used in gradle's dependency version definitions docs.gradle.org/current/userguide/…