题
我可以在 JSON 文件中使用注释吗?如果是这样,怎么办?
解决方案
没有。
JSON应该都是数据,如果你包含注释,那么它也将是数据。
您可以使用名为" _comment"
(或其他)的指定数据元素,这些元素将被使用JSON数据的应用程序忽略。
你可能会更好地在生成/接收JSON的进程中发表评论,因为他们应该事先了解JSON数据,或者至少知道它的结构。
但如果你决定:
{
"_comment": "comment text goes here...",
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
其他提示
不, 表单的注释 //…
或者 /*…*/
JSON 中不允许。这个答案基于:
- http://www.json.org
- RFC 4627:这
application/json
JavaScript 对象表示法 (JSON) 的媒体类型 - RFC 7159 JavaScript 对象表示法 (JSON) 数据交换格式 - 已过时:4627, 7158
如果您选择,请附上评论;在解析或传输之前用缩小器将它们剥离。
我刚刚发布 JSON.minify() 来自JSON块的注释和空格,使其成为可以解析的有效JSON。所以,您可以像以下一样使用它:
JSON.parse(JSON.minify(my_str));
当我发布它时,我得到了一个强烈反对的人甚至不同意它的想法,所以我决定写一篇关于评论在JSON中有意义。它包括来自JSON创建者的这个值得注意的评论:
假设您使用JSON来保留要注释的配置文件。继续,插入您喜欢的所有评论。然后通过JSMin将其传递给JSON解析器。 - Douglas Crockford,2012
希望这对那些不同意为什么 JSON.minify()有用的人有帮助。
评论已从设计中删除。
我从JSON中删除了注释,因为我看到有人使用它们来保存解析指令,这种做法会破坏互操作性。我知道缺乏评论会让一些人感到悲伤,但事实并非如此。
假设您使用JSON来保留要注释的配置文件。继续,插入您喜欢的所有评论。然后通过JSMin将其传递给JSON解析器。
免责声明:您的保修无效
正如已经指出的那样,这个hack利用了规范的实现。并非所有JSON解析器都能理解这种JSON。特别是流解析器会阻塞。
这是一个有趣的好奇心,但你根本不应该用它来做任何事情。以下是原始答案。
我发现了一个小小的hack,它允许你将注释放在一个不会影响解析的JSON文件中,或者改变以任何方式表示的数据。
似乎在声明对象文字时,您可以使用相同的键指定两个值,最后一个值优先。信不信由你,事实证明JSON解析器的工作方式相同。因此,我们可以使用它在源JSON中创建注释,这些注释不会出现在已解析的对象表示中。
({a: 1, a: 2});
// => Object {a: 2}
Object.keys(JSON.parse('{"a": 1, "a": 2}')).length;
// => 1
如果我们应用此技术,您评论的JSON文件可能如下所示:
{
"api_host" : "The hostname of your API server. You may also specify the port.",
"api_host" : "hodorhodor.com",
"retry_interval" : "The interval in seconds between retrying failed API calls",
"retry_interval" : 10,
"auth_token" : "The authentication token. It is available in your developer dashboard under 'Settings'",
"auth_token" : "5ad0eb93697215bc0d48a7b69aa6fb8b",
"favorite_numbers": "An array containing my all-time favorite numbers",
"favorite_numbers": [19, 13, 53]
}
以上代码为有效的JSON 。如果你解析它,你会得到一个像这样的对象:
{
"api_host": "hodorhodor.com",
"retry_interval": 10,
"auth_token": "5ad0eb93697215bc0d48a7b69aa6fb8b",
"favorite_numbers": [19,13,53]
}
这意味着没有评论的痕迹,并且它们不会产生奇怪的副作用。
快乐的黑客攻击!
JSON不支持评论。它也从未打算用于需要注释的配置文件。
Hjson是人类的配置文件格式。轻松的语法,更少的错误,更多的评论。
有关JavaScript,Java,Python,PHP,Rust,Go,Ruby和C#库的信息,请参见 hjson.org 。
考虑使用YAML。它几乎是JSON的超集(几乎所有有效的JSON都是有效的YAML),它允许注释。
你做不到。至少这是我通过快速浏览 json.org 的经验。
JSON的语法在该页面上可视化。没有关于评论的任何说明。
您应该编写 JSON架构。 JSON模式目前是提议的Internet草案规范。除了文档之外,架构还可用于验证您的JSON数据。
示例:
{
"description":"A person",
"type":"object",
"properties":
{
"name":
{
"type":"string"
},
"age":
{
"type":"integer",
"maximum":125
}
}
}
您可以使用说明架构属性提供文档。
如果您使用 Jackson 作为JSON解析器,那么这就是您启用它以允许注释的方式:
ObjectMapper mapper = new ObjectMapper().configure(Feature.ALLOW_COMMENTS, true);
然后你可以得到这样的评论:
{
key: "value" // Comment
}
您还可以通过设置
以#
开头的评论
mapper.configure(Feature.ALLOW_YAML_COMMENTS, true);
但总的来说(如前所述)规范不允许发表评论。
评论不是官方标准。虽然一些解析器支持C风格的注释。我使用的是 JsonCpp 。在这些例子中有一个:
// Configuration options
{
// Default encoding for text
"encoding" : "UTF-8",
// Plug-ins loaded at start-up
"plug-ins" : [
"python",
"c++",
"ruby"
],
// Tab indent size
"indent" : { "length" : 3, "use_space": true }
}
jsonlint 未对此进行验证。因此,注释是特定于解析器的扩展,而不是标准扩展。
另一个解析器是 JSON5 。
JSON TOML 的替代方案。
另一种选择是 jsonc 。
以下是我在 Google Firebase文档中找到的内容允许您在JSON中添加注释:
{
"//": "Some browsers will use this to enable push notifications.",
"//": "It is the same for all projects, this is not your project's sender ID",
"gcm_sender_id": "1234567890"
}
如果你的文本文件是一个JSON字符串,某个程序会读取它,在使用它之前去除C或C ++样式注释有多难?
答案:这将是一个班轮。如果这样做,那么JSON文件可以用作配置文件。
如果您使用带有ASP.NET的Newtonsoft.Json库来读取/反序列化,则可以使用JSON内容中的注释:
//" name":" string"
//" id":int
或
/ *这是
评论示例* /
PS:只有6个版本的Newtonsoft Json支持单行注释。
对于那些无法想到开箱即用的人的补充说明:我在我制作的ASP.NET Web应用程序中使用JSON格式进行基本设置。我读取文件,使用Newtonsoft库将其转换为设置对象,并在必要时使用它。
我更喜欢在JSON文件本身中编写关于每个单独设置的注释,并且我真的不关心JSON格式的完整性,只要我使用的库是正常的。
我认为这比“创建单独的'settings.README'文件并解释其中的设置更容易使用/理解”。
如果您对此类用法有疑问;对不起,精灵已经没了灯。人们会发现JSON格式的其他用法,你无能为力。
JSON背后的想法是在应用程序之间提供简单的数据交换。这些通常是基于Web的,语言是JavaScript。
它实际上不允许这样的注释,但是,将注释作为数据中的一个名称/值对传递肯定会起作用,尽管这些数据显然需要被解析代码忽略或处理
所有这一切,并不意味着JSON文件应该包含传统意义上的注释。它应该只是数据。
有关更多详细信息,请查看 JSON网站。
我刚刚遇到配置文件。我不想使用 XML (详细,图形,丑陋,难以阅读)或“ini”格式(没有层次结构,没有真正的标准等)或Java“属性”格式(如.ini)。
JSON可以做他们能做的所有事情,但它更简洁,更易于阅读 - 解析器在许多语言中都很容易和普遍存在。它只是一个数据树。但是,带外评论通常是记录“默认”的必要条件。配置等。配置永远不是“完整文档”,而是保存数据的树,在需要时可以是人类可读的。
我想可以使用"#":" comment"
,for“valid”" JSON。
JSON本身不支持注释,但您可以创建自己的解码器或至少预处理器来删除注释,这非常好(只要您忽略注释并且不使用它们来指导应用程序应该如何处理JSON数据)。
JSON没有评论。 JSON编码器绝不能输出注释。 JSON解码器可以接受并忽略注释。
永远不应该使用注释来传输任何有意义的内容。那是 JSON的用途是什么。
这取决于您的JSON库。 Json.NET 支持JavaScript样式的注释, / * commment * /
JSON 对于配置文件和其他本地使用非常有意义,因为它无处不在,而且比 XML 简单得多。
如果人们有充分的理由反对在通信数据时在 JSON 中添加注释(无论是否有效),那么 JSON 可能会分为两部分:
- JSON-COM:线路上的 JSON,或传输 JSON 数据时应用的规则。
- JSON-文档:JSON 文档,或者文件中或本地的 JSON。定义有效 JSON 文档的规则。
JSON-DOC 将允许注释,并且可能存在其他细微差别,例如处理空格。解析器可以轻松地从一种规范转换为另一种规范。
关于 评论 Douglas Crockford 关于此问题的文章(由 @Artur Czajka 引用)
假设您使用 JSON 来保存您想要注释的配置文件。继续插入您喜欢的所有评论。然后通过 JSMin 将其传递给 JSON 解析器。
我们正在讨论通用配置文件问题(跨语言/平台),而他正在用 JS 特定实用程序来回答!
当然,任何语言都可以实现针对 JSON 的最小化、 但要将其标准化,使其在所有语言和平台的解析器中普遍存在,这样人们就不会再浪费时间,因为他们有很好的使用案例而缺乏该功能,也不会再在网络论坛上寻找这个问题,而人们却告诉他们这是个坏主意,或建议很容易实现从文本文件中剥离注释。
另一个问题是互操作性。假设您有一个库或 API 或任何类型的子系统,其中有一些与之关联的配置或数据文件。这个子系统是 可从不同语言访问。然后你会告诉人们:顺便说一下 在将 JSON 文件传递给解析器之前,不要忘记将注释从 JSON 文件中剥离出来!
Dojo Toolkit JavaScript工具包(至少从版本1.4开始)允许您在JSON中包含注释。注释可以是 / * * /
格式。 Dojo Toolkit通过 dojo.xhrGet()
调用来使用JSON。
其他JavaScript工具包的工作方式可能类似。
在选择最终选项之前尝试使用备用数据结构(甚至数据列表)时,这会很有用。
JSON不是框架协议。它是一种语言免费格式。因此,没有为JSON定义注释的格式。
正如许多人所建议的,有一些技巧,例如,重复的密钥或您可以使用的特定密钥 _comment
。这取决于你。
你可以在 JSONP 中发表评论,但不是纯粹的JSON。我花了一个小时试图让我的程序使用Highcharts中的这个例子: http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-c.json&callback=?
如果您点击该链接,您会看到
?(/* AAPL historical OHLC data from the Google Finance API */
[
/* May 2006 */
[1147651200000,67.79],
[1147737600000,64.98],
...
[1368057600000,456.77],
[1368144000000,452.97]
]);
由于我的本地文件夹中有类似的文件,因此同源文件没有问题策略,所以我决定使用纯JSON ......当然, $。getJSON
由于评论而无声地失败。
最后我只是向上面的地址发送了一个手动HTTP请求,并意识到内容类型是 text / javascript
,因为JSONP返回纯JavaScript。在这种情况下,允许评论 。但是我的应用程序返回了内容类型 application / json
,因此我不得不删除注释。
JSON用于支持评论,但它们被滥用并从标准中删除。
来自JSON的创建者:
我从JSON中删除了注释,因为我看到有人使用它们来保存解析指令,这种做法会破坏互操作性。我知道缺乏评论会让一些人感到悲伤,但事实并非如此。 - Douglas Crockford,2012
官方JSON网站位于 JSON.org 。 JSON被ECMA International定义为标准。总是有一个请愿程序来修改标准。由于多种原因,注释不太可能添加到JSON标准中。
JSON by design是一种易于反向设计(人工解析)的XML替代方案。甚至简化到注释是不必要的。它甚至不是标记语言。目标是稳定性和互操作性。
任何了解“has-a”的人面向对象的关系可以理解任何JSON结构 - 这就是重点。它只是一个带有节点标签(键/值对)的有向无环图(DAG),它是一种近乎通用的数据结构。
此唯一需要的注释可能是“//这些是DAG标签”。键名可以根据需要提供信息,允许任意语义。
任何平台都可以用几行代码解析JSON。 XML需要复杂的OO库,这些库在许多平台上都不可行。
注释只会使JSON的互操作性降低。除非您真正需要的是标记语言(XML),否则无需添加任何其他内容,并且不关心是否可以轻松解析持久化数据。
这是一个“你可以”的问题。这是一个“是”答案。
不,您不应该使用重复的对象成员将侧信道数据填充到JSON编码中。 (参见“对象中的名称应该是唯一的”,在RFC中)。
是的,您可以在 JSON 周围插入评论可以解析出来。
但是如果你想要一种插入和提取任意侧通道数据到有效JSON的方法,这里是一个答案。我们利用JSON编码中的非唯一数据表示。这在RFC的第二部分中允许 * ,在“六个结构字符中的任何一个之前或之后允许空白”。
* RFC仅声明“在六个结构字符中的任何一个之前或之后允许空格”,未明确提及字符串,数字,“假”,“真”等。 ,和“null”。在所有实现中都忽略了这个省略。
首先,通过缩小JSON来规范化您的JSON:
$jsonMin = json_encode(json_decode($json));
然后用二进制编码你的评论:
$hex = unpack('H*', $comment);
$commentBinary = base_convert($hex[1], 16, 2);
然后steg你的二进制文件:
$steg = str_replace('0', ' ', $commentBinary);
$steg = str_replace('1', "\t", $steg);
这是你的输出:
$jsonWithComment = $steg . $jsonMin;
我们正在为我们的项目使用 strip-json-comments
。它支持以下内容:
/*
* Description
*/
{
// rainbows
"unicorn": /* ❤ */ "cake"
}
只需 npm install --save strip-json-comments
即可安装和使用它:
var strip_json_comments = require('strip-json-comments')
var json = '{/*rainbows*/"unicorn":"cake"}';
JSON.parse(strip_json_comments(json));
//=> {unicorn: 'cake'}
要将JSON项目剪切为部分,我添加“虚拟评论”。行:
{
"#############################" : "Part1",
"data1" : "value1",
"data2" : "value2",
"#############################" : "Part2",
"data4" : "value3",
"data3" : "value4"
}
有一个很好的解决方案(hack),它是有效的JSON。 只需两次(或更多)相同的密钥。例如:
{
"param" : "This is the comment place",
"param" : "This is value place",
}
所以JSON会理解为:
{
"param" : "This is value place",
}
JSON的作者希望我们在JSON中包含注释,但在解析之前将其删除(请参阅链接。如果JSON应该有注释,为什么不标准化它们,让JSON解析器完成这项工作呢?我不同意那里的逻辑,但是,唉,这是标准。使用其他人建议的YAML解决方案很好,但它需要库依赖。
如果你想删除注释,但又不想拥有库依赖,那么这是一个两行解决方案,适用于C ++风格的注释,但可以适应其他人:
var comments = new RegExp("//.*", 'mg');
data = JSON.parse(fs.readFileSync(sample_file, 'utf8').replace(comments, ''));
请注意,此解决方案只能用于您可以确定JSON数据不包含注释启动器的情况,例如: ('//').
实现JSON解析,删除注释以及没有额外库的另一种方法是在JavaScript解释器中评估JSON。当然,使用这种方法的警告是,您只想评估无污染的数据(没有不受信任的用户输入)。这是Node.js中这种方法的一个例子 - 另一个警告,下面的例子只会读取一次数据,然后它将被缓存:
data = require(fs.realpathSync(doctree_fp));
叹息。为什么不直接添加字段,例如
{
"note1" : "This demonstrates the provision of annotations within a JSON file",
"field1" : 12,
"field2" : "some text",
"note2" : "Add more annotations as necessary"
}
只需确保您的“notex”即可。名称不与任何真实字段冲突。