【问题标题】:JSON alternatives (for the purpose of specifying configuration)?JSON 替代方案(用于指定配置)?
【发布时间】:2012-01-11 03:14:40
【问题描述】:

我喜欢 json 作为我编写的软件的配置文件格式。我喜欢它轻量级、简单且广泛支持的特点。但是,我发现 json 中有一些我真正喜欢的东西,它没有。

Json 没有多行字符串或此处的文档 (http://en.wikipedia.org/wiki/Here_document),当您希望 json 文件具有人类可读性和可编辑性时,这通常会非常尴尬。您可以使用字符串数组,但这是一个笨拙的解决方法。

Json 不允许 cmets。

如果您查看 unix 配置文件的格式,您会发现很多人都在设计自己的尴尬格式,而使用某种通用的东西确实更有意义。例如,以下是 Apache 配置文件中的一些代码:

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]

基本上,这里发生的事情是他们发明了一种极其痛苦的方式来编写布尔函数 f(w,x,y,z)=w&!x&y&z。你想要一个合乎逻辑的“或”吗?他们也有一些单独的(丑陋的)机制。

这似乎指向某种数据描述语言,它简单且图灵不完整,但比 json 更具表现力、灵活和方便。有人知道这种语言吗?

在我看来,XML 太复杂了,lisp 表达式有错误的特性(图灵完备性)并且缺少正确的特性(这里是文档,表达性语法)。

[编辑] 标题具有误导性。我对json的下一次迭代并不感兴趣。我对作为 javascript 子集的语言不感兴趣。我对替代数据描述语言感兴趣。

【问题讨论】:

  • YAML?
  • @BalusC:有趣的建议 :-) 但是 YAML 似乎没有提供任何很好的方法来处理布尔函数/Apache 示例或类似风格的应用程序。

标签: json


【解决方案1】:

EDN format 是一种基于 Clojure 文字的选项。它几乎是 JSON 的超集,除了没有特殊符号分隔映射中的键和值(就像 : 在 JSON 中所做的那样);相反,所有元素都由空格和/或逗号分隔,并且映射被编码为具有偶数个元素的列表,包含在 {..} 中。

EDN 允许 cmets(使用 ; 换行,或使用 #_ 读取下一个元素的结尾),但不是 here-docs。它可以使用 tag 表示法扩展到新类型:

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

myapp/Person 标记的参数(即{:first "Fred" :last "Mertz"})必须是有效的 EDN 表达式,这使得它无法扩展到 here-doc 支持。

它有两个内置标签:#inst 用于时间戳和#uuid。它还支持命名空间符号(即标识符)和关键字(即映射键常量)类型;它区分列表(..) 和向量[..]。任何类型的元素都可以用作地图中的键。

在上述问题的背景下,可以发明一个#apache/rule-or 标签,它接受一系列元素,我将其语义留给你!

【讨论】:

    【解决方案2】:

    看看http://github.com/igagis/puu/

    比 JSON 还要简单。

    它有 C++ 风格的 cmets。

    如果需要“真正的”换行符或制表符,可以格式化多行字符串并使用转义的换行符 \n 和制表符 \t 字符。

    这里是 sn-p 的例子:

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

    【讨论】:

    • 这是一见钟情。它甚至有原始字符串文字真棒
    • 很高兴您喜欢它。不幸的是,原始字符串支持仅在 C++ 库中实现。 C# 和 Java 库目前缺乏对原始字符串的支持。
    • 猜猜是时候合作开发操作系统了。特别是 C# 库需要改进,好像是 C++ 开发人员写的:)
    【解决方案3】:

    JSON 中的“J”是“Javascript”。如果特定的所需语法结构不在 Javascript 中,那么它就不会在 JSON 中。

    Heredocs 超出了 JSON 的范围。这是一种用于简化多行字符串定义的语言语法结构,但 JSON 是一种传输符号。它与建筑无关。但是,它确实具有多行字符串,只需在字符串中允许\n 换行符即可。 JSON 中没有任何内容表明字符串中不能有换行符。只要包含的引号字符正确,它就完全有效。例如

    {"x":"y\nz"}
    

    是 100% 合法有效的 JSON,并且是多行字符串,而

    {"x":"y
    z"} 
    

    不是,解析时会失败。

    【讨论】:

    • “如果特定的语法结构不在 Javascript 中,那么它就不会在 JSON 中。”这很可爱,但 JSON 实际上并不是 JavaScript 的子集,它支持 JavaScript 不支持的东西。
    【解决方案4】:

    总有我喜欢称之为“真正的 JSON”的东西。 JSON 代表 JavaScript Object Notation,而 JavaScript 确实 有 cmets 和与 heredocs 足够接近的东西。

    对于 heredoc,您可以使用 JavaScript 的 E4X 内联 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 */
    }
    

    你可以使用 Firefox 的 JavaScript 引擎(FF 是目前唯一支持 E4X 的浏览器)或者你可以实现自己的解析器,这真的不是那么难。

    Here's the E4X quickstart guide, too.

    【讨论】:

    • 有趣的想法,虽然它不符合图灵不完备的标准。
    • 压缩空格以节省网络带宽的方法是什么?谢谢。
    • @AizzatSuhardi:使用实际的 JSON JSON
    • @minitech♦:你的意思是 {"actualJson":"Hi!\nI'm actual JSON"}?
    【解决方案5】:

    由于March 2018,您可以使用JSON5,它似乎已经添加了您(和许多其他人)从JSON 中缺少的所有内容。

    简短示例 (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",
    }
    

    JSON5 数据交换格式 (JSON5) 是 JSON 的超集,它 旨在通过扩展 JSON 来缓解 JSON 的一些限制 包含来自 ECMAScript 5.1 的一些产品的语法。

    功能总结

    以下 ECMAScript 5.1 功能不支持 JSON,已扩展为 JSON5。

    对象

    • 对象键可能是 ECMAScript 5.1 IdentifierName。
    • 对象可能有一个尾随逗号。

    数组

    • 数组可能有一个尾随逗号。

    字符串

    • 字符串可以是单引号。
    • 通过转义换行符,字符串可以跨越多行。
    • 字符串可能包含字符转义。

    数字

    • 数字可以是十六进制。
    • 数字可能有前导或尾随小数点。
    • 数字可以是 IEEE 754 正无穷大、负无穷大和 NaN。
    • 数字可能以明确的加号开头。

    评论

    • 允许单行和多行 cmets。

    空白

    • 允许使用额外的空白字符。

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

    【讨论】:

    • 公平地说,JSON5 中的 cmets 支持是部分的,因为 JSON5 在将配置保存回 JSON 后不会保留 cmets(即,您可以将 JSON5 中的 cmets 仅用于只读配置文件作为 JSON5.stringify () 返回没有 cmets 的 json)。
    • @tav 当然,因为 cmets 仅适用于开发人员。解析内容后,cmets 已经丢失。所以不是stringify's fault。这就是它应该发生的方式。另一个例子:编译的 Java 类不包含 cmets。反编译一。你不会找到他们的。
    • 在 JSON5 中缺乏原生正则表达式支持真的让我很反感。
    • @Marshal Here's the discussion 关于为什么原生 RegExp 支持没有进入 JSON5 v1.0。我倾向于同意。 RegExp 作为字符串对我来说没什么大不了的。
    • @DJDaveMark 感谢您的链接。当前的 JSON5 版本中还没有实验功能吗?如果是这样,当前建议的字符串化正则表达式方法是使用替换函数,如:?谢谢。
    【解决方案6】:

    考虑TOML。 专为配置而设计。看起来非常友好和强大。易于阅读并支持广泛的数据类型和结构。有很多语言的解析器: C C# C++ 通用 Lisp 水晶 镖 二郎 Fortran 去 珍妮特 爪哇 JavaScript 朱莉娅 科特林 卢阿 尼姆 OCaml Perl Perl6/乐库 Python 锈 迅速 V

    【讨论】:

    【解决方案7】:

    JSON 的一个重要属性(可能是最重要的)是可以轻松地在字符串表示和对象形式的表示之间“翻转”,而用于表示对象形式的对象是相对简单的数组和映射。这就是 JSON 在网络环境中如此有用的原因。

    您想要的功能会与 JSON 的这种双重性质发生冲突。

    【讨论】:

      【解决方案8】:

      对于配置,您可以使用可嵌入的脚本语言,例如 lua 或 python,实际上这对于配置来说并不少见。这为您提供了多行字符串或此处的文档和 cmets。它还使您更容易拥有诸如您描述的布尔函数之类的东西。但是,脚本语言当然是图灵完备的。

      【讨论】:

        【解决方案9】:

        还有ELDF

        虽然不支持 cmets,但可以通过空键来模拟:

        config_var1 = value1
        =some comment
        config_var2 = value2
        

        【讨论】:

          猜你喜欢
          • 2018-07-24
          • 2019-07-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-14
          • 2010-10-31
          • 2018-01-08
          • 1970-01-01
          相关资源
          最近更新 更多