我可以在 JSON 文件中使用注释吗?如果是这样,怎么做?
//comments
是否适用于 Sublime Text 配置文件的特定用例,答案是肯定的(从版本 2 开始)。 Sublime Text 至少不会抱怨它,而它会在控制台中抱怨 {"__comment": ...}
,因为它是一个意想不到的字段。
不。
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 中不允许使用 //…
或 /*…*/
形式的注释。这个答案基于:
https://www.json.org
RFC 4627:JavaScript 对象表示法 (JSON) 的 application/json 媒体类型
RFC 8259 JavaScript 对象表示法 (JSON) 数据交换格式(取代 RFC 4627、7158、7159)
如果您愿意,请包括评论;在解析或传输之前用压缩器将它们剥离。
我刚刚发布了 JSON.minify(),它从 JSON 块中去除注释和空格,使其成为可以解析的有效 JSON。因此,您可以像这样使用它:
JSON.parse(JSON.minify(my_str));
当我发布它时,我遭到了很多人的强烈反对,甚至不同意它的想法,所以我决定写一篇全面的博客文章来解释为什么comments make sense in JSON。它包括来自 JSON 的创建者的这条值得注意的评论:
假设您使用 JSON 来保存您想要注释的配置文件。继续并插入您喜欢的所有评论。然后通过 JSMin 将其通过管道传递给您的 JSON 解析器。 - 道格拉斯·克罗克福德,2012
希望这对那些不同意 JSON.minify() 有用的人有所帮助。
设计上从 JSON 中删除了评论。
我从 JSON 中删除了注释,因为我看到人们使用它们来保存解析指令,这种做法会破坏互操作性。我知道缺少评论会让一些人感到难过,但不应该。假设您使用 JSON 来保存您想要注释的配置文件。继续并插入您喜欢的所有评论。然后通过 JSMin 将其通过管道传递给您的 JSON 解析器。
来源:Public statement by Douglas Crockford on G+
JSON 不支持评论。它也从未打算用于需要注释的配置文件。
Hjson 是人类的配置文件格式。轻松的语法,更少的错误,更多的评论。
https://i.stack.imgur.com/u2E8q.gif
有关 JavaScript、Java、Python、PHP、Rust、Go、Ruby、C++ 和 C# 库的信息,请参阅 hjson.github.io。
免责声明:您的保修无效
正如已经指出的那样,这个黑客利用了规范的实现。并非所有 JSON 解析器都能理解这种 JSON。特别是流式解析器会窒息。
这是一个有趣的好奇心,但你真的不应该将它用于任何事情。以下是原答案。
我发现了一个小技巧,可以让您在 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]
}
上面的代码是 valid JSON。如果你解析它,你会得到一个像这样的对象:
{
"api_host": "hodorhodor.com",
"retry_interval": 10,
"auth_token": "5ad0eb93697215bc0d48a7b69aa6fb8b",
"favorite_numbers": [19,13,53]
}
这意味着没有评论的痕迹,也不会产生奇怪的副作用。
快乐黑客!
考虑使用 YAML。它几乎是 JSON 的超集(实际上所有有效的 JSON 都是有效的 YAML)并且它允许注释。
注释不是官方标准,尽管一些解析器支持 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。
最新版本的 nlohmann/json 提供了对忽略解析注释的可选支持。
以下是我在 Google Firebase documentation 中找到的允许您在 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 schema。 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);
但总的来说(如前所述)规范不允许评论。
不。 JSON 曾经支持评论,但它们被滥用并从标准中删除。
来自 JSON 的创建者:
我从 JSON 中删除了注释,因为我看到人们使用它们来保存解析指令,这种做法会破坏互操作性。我知道缺少评论会让一些人感到难过,但不应该。 - 道格拉斯·克罗克福德,2012
官方 JSON 站点位于 JSON.org。 JSON 被 ECMA International 定义为 standard。总是有一个请求过程来修改标准。出于多种原因,不太可能将注释添加到 JSON 标准中。
JSON 在设计上是一种易于逆向工程(人工解析)的 XML 替代方案。它甚至被简化到不需要注释的地步。它甚至不是一种标记语言。目标是稳定性和互操作性。
任何理解面向对象的“具有”关系的人都可以理解任何 JSON 结构——这就是重点。它只是一个带有节点标签(键/值对)的有向无环图(DAG),是一种近乎通用的数据结构。
唯一需要的注释可能是“//这些是 DAG 标记”。键名可以根据需要提供信息,允许任意语义。
任何平台都可以只用几行代码解析 JSON。 XML 需要复杂的 OO 库,这些库在许多平台上不可行。
注释只会降低 JSON 的互操作性。除非您真正需要的是标记语言 (XML),否则根本没有其他要添加的内容,并且不关心您的持久数据是否易于解析。
但是正如 JSON 的创建者也观察到的那样,JS 管道一直支持评论:
继续并插入您喜欢的所有评论。然后通过 JSMin 将其通过管道传递给您的 JSON 解析器。 - 道格拉斯·克罗克福德,2012
如果您使用带有 ASP.NET 的 Newtonsoft.Json 库来读取/反序列化,您可以在 JSON 内容中使用注释:
//"name": "string" //"id": int
或者
/* 这是一个注释示例 */
PS:单行注释仅支持 6+ 版本的 Newtonsoft Json。
对无法开箱即用的人的附加说明:我在我制作的 ASP.NET Web 应用程序中使用 JSON 格式进行基本设置。我阅读了该文件,使用 Newtonsoft 库将其转换为设置对象,并在必要时使用它。
我更喜欢在 JSON 文件本身中写关于每个单独设置的注释,而且我真的不关心 JSON 格式的完整性,只要我使用的库可以接受它。
我认为这是一种比创建单独的“settings.README”文件并解释其中的设置更容易使用/理解的方式。
如果您对这种用法有疑问;对不起,精灵不在灯里了。人们会发现 JSON 格式的其他用途,对此您无能为力。
如果您的文本文件(一个 JSON 字符串)将被某个程序读取,那么在使用它之前去掉 C 或 C++ 样式的注释会有多困难?
答:应该是单排。如果你这样做,那么 JSON 文件可以用作配置文件。
JSON 本身不支持评论,但是您可以制作自己的解码器或至少预处理器来去除评论,这非常好(只要您忽略评论并且不使用它们来指导您的应用程序应该如何处理 JSON 数据)。
JSON 没有评论。 JSON 编码器不得输出评论。 JSON 解码器可以接受和忽略评论。
永远不应该使用评论来传递任何有意义的东西。这就是 JSON 的用途。
参见:Douglas Crockford, author of JSON spec。
JSON 背后的想法是在应用程序之间提供简单的数据交换。这些通常是基于网络的,语言是 JavaScript。
它实际上不允许这样的注释,但是,将注释作为数据中的名称/值对之一传递肯定会起作用,尽管该数据显然需要被解析代码忽略或专门处理。
综上所述,JSON 文件不应该包含传统意义上的注释。它应该只是数据。
查看 JSON website 了解更多详情。
我只是在配置文件中遇到这个。我不想使用 XML(冗长、图形化、丑陋、难以阅读)或“ini”格式(没有层次结构、没有真正的标准等)或 Java“Properties”格式(如 .ini)。
JSON 可以做他们能做的所有事情,但它不那么冗长,而且更易于阅读——而且解析器在许多语言中都很容易且无处不在。它只是一棵数据树。但是带外注释通常是记录“默认”配置等的必要条件。配置永远不会是“完整文档”,而是在需要时可供人类阅读的已保存数据树。
我想可以将 "#": "comment"
用于“有效”JSON。
这取决于您的 JSON 库。 Json.NET 支持 JavaScript 样式的注释,/* commment */
。
请参阅another Stack Overflow question。
JSON 对于配置文件和其他本地使用很有意义,因为它无处不在,而且比 XML 简单得多。
如果人们在交流数据(无论是否有效)时有充分的理由反对在 JSON 中添加评论,那么 JSON 可能会被分成两部分:
JSON-COM:在线上的 JSON,或在传输 JSON 数据时应用的规则。
JSON-DOC:JSON 文档,或文件中或本地的 JSON。定义有效 JSON 文档的规则。
JSON-DOC 将允许注释,并且可能存在其他细微差异,例如处理空格。解析器可以轻松地从一种规范转换为另一种规范。
关于 Douglas Crockford 在此问题上提出的remark(@Artur Czajka 引用)
假设您使用 JSON 来保存您想要注释的配置文件。继续并插入您喜欢的所有评论。然后通过 JSMin 将其通过管道传递给您的 JSON 解析器。
我们正在谈论一个通用的配置文件问题(跨语言/平台),而他正在用一个 JS 特定的实用程序来回答!
当然,特定于 JSON 的缩小可以用任何语言实现,但是将其标准化,以便它在所有语言和平台的解析器中无处不在,这样人们就不会因为缺少该功能而浪费时间,因为他们有很好的用例,在在线论坛,并让人们告诉他们这是一个坏主意,或者建议很容易实现从文本文件中删除评论。
另一个问题是互操作性。假设您有一个库或 API 或任何类型的子系统,其中有一些与之关联的配置或数据文件。并且这个子系统可以从不同的语言中访问。然后你会告诉人们:顺便说一下,在将 JSON 文件传递给解析器之前不要忘记从 JSON 文件中删除注释!
是,新标准,JSON5 允许 C++ 样式注释,其中有许多 other extensions:
// A single line comment.
/* A multi-
line comment. */
JSON5 数据交换格式 (JSON5) 是 JSON 的超集,旨在减轻 JSON 的一些限制。它完全向后兼容,使用它可能比编写自定义非标准解析器、为现有解析器打开非标准功能或使用各种技巧(如字符串字段进行注释)更好。或者,如果使用的解析器支持,只需同意我们使用 JSON 5 子集,即 JSON 和 C++ 样式注释。它比我们以我们认为合适的方式调整 JSON 标准要好得多。
已经有 npm package、Python package、Java package 和 C library 可用。它向后兼容。我认为没有理由坚持“官方”JSON 限制。
我认为从 JSON 中删除注释的原因与在 Java 中删除运算符重载的原因相同:可能会以错误的方式使用,但忽略了一些明显合法的用例。对于运算符重载,它是矩阵代数和复数。对于 JSON 注释,它是可以由人类编写、编辑或读取的配置文件和其他文档,而不仅仅是解析器。
如果您使用 JSON5,则可以包含评论。
JSON5 是对 JSON 的提议扩展,旨在使人类更容易手动编写和维护。它通过直接从 ECMAScript 5 添加一些最小的语法特性来做到这一点。
Dojo Toolkit JavaScript 工具包(至少从 1.4 版开始)允许您在 JSON 中包含注释。评论可以是 /* */
格式。 Dojo Toolkit 通过 dojo.xhrGet()
调用使用 JSON。
其他 JavaScript 工具包也可以类似地工作。
在选择最终选项之前尝试替代数据结构(甚至数据列表)时,这会很有帮助。
dojo.xhrGet()
通过接受隐含鼓励。
JSON 不是框架协议。它是一种无语言格式。所以评论的格式没有为 JSON 定义。
正如许多人所建议的那样,有一些技巧,例如,您可以使用重复键或特定键 _comment
。由你决定。
免责声明:这很愚蠢
实际上有一种方法可以添加注释并保持在规范范围内(不需要额外的解析器)。但是,如果没有任何类型的解析,它不会产生人类可读的评论。
您可能会滥用以下内容:
在任何标记之前或之后都允许使用无关紧要的空格。空格是以下一个或多个代码点的任意序列:字符制表符 (U+0009)、换行符 (U+000A)、回车符 (U+000D) 和空格 (U+0020)。
您可以以一种骇人听闻的方式滥用它来添加评论。例如:使用选项卡开始和结束您的评论。在 base3 中编码注释并使用其他空白字符来表示它们。例如。
010212 010202 011000 011000 011010 001012 010122 010121 011021 010202 001012 011022 010212 011020 010202 010202
(ASCII 中的 hello base three
)但不是 0 使用空格,1 使用换行,2 使用回车。
这只会给你留下很多不可读的空白(除非你制作一个 IDE 插件来动态编码/解码它)。
出于明显的原因,我什至从未尝试过,你也不应该这样做。
您可以在 JSONP 中添加评论,但不能使用纯 JSON。我刚刚花了一个小时试图让我的程序与 this example from Highcharts 一起工作。
如果你点击链接,你会看到
?(/* AAPL historical OHLC data from the Google Finance API */
[
/* May 2006 */
[1147651200000,67.79],
[1147737600000,64.98],
...
[1368057600000,456.77],
[1368144000000,452.97]
]);
因为我的本地文件夹中有一个类似的文件,所以 Same-origin policy 没有问题,所以我决定使用纯 JSON……当然,$.getJSON
因为评论而默默地失败了。
最后,我只是向上面的地址发送了一个手动 HTTP 请求,并意识到内容类型是 text/javascript
,因为 JSONP 返回纯 JavaScript。在这种情况下,评论是允许的。但是我的应用程序返回了内容类型 application/json
,所以我不得不删除评论。
这是一个“你能不能”的问题。这是一个“是”的答案。
不,您不应该使用重复的对象成员将侧通道数据填充到 JSON 编码中。 (请参阅“对象中的名称应该是唯一的”in the RFC)。
是的,你可以insert comments around the JSON,你可以解析出来。
但是,如果您想要一种将任意侧通道数据插入和提取到有效 JSON 的方法,这里有一个答案。我们利用 JSON 编码中数据的非唯一表示。这在 RFC 的第二部分中是允许的*“在六个结构字符中的任何一个之前或之后允许空白”。
RFC 仅声明“在六个结构字符之前或之后允许使用空格”,没有明确提及字符串、数字、“false”、“true”和“null”。在所有实现中都会忽略此省略。
首先,通过缩小 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;
JSON 本身不允许评论。推理是完全愚蠢的,因为您可以使用 JSON 本身来创建注释,这完全消除了推理,并且完全没有充分理由加载解析器数据空间以获得完全相同的结果和潜在问题,例如它们是:JSON带有评论的文件。
如果您尝试在其中添加注释(例如使用 // 或 /* */ 或 #),则某些解析器将失败,因为这严格不符合 JSON 规范。所以你永远不应该那样做。
例如,在这里,我的 image manipulation system 保存了图像符号和一些与它们相关的基本格式化(评论)信息(在底部):
{
"Notations": [
{
"anchorX": 333,
"anchorY": 265,
"areaMode": "Ellipse",
"extentX": 356,
"extentY": 294,
"opacity": 0.5,
"text": "Elliptical area on top",
"textX": 333,
"textY": 265,
"title": "Notation 1"
},
{
"anchorX": 87,
"anchorY": 385,
"areaMode": "Rectangle",
"extentX": 109,
"extentY": 412,
"opacity": 0.5,
"text": "Rect area\non bottom",
"textX": 98,
"textY": 385,
"title": "Notation 2"
},
{
"anchorX": 69,
"anchorY": 104,
"areaMode": "Polygon",
"extentX": 102,
"extentY": 136,
"opacity": 0.5,
"pointList": [
{
"i": 0,
"x": 83,
"y": 104
},
{
"i": 1,
"x": 69,
"y": 136
},
{
"i": 2,
"x": 102,
"y": 132
},
{
"i": 3,
"x": 83,
"y": 104
}
],
"text": "Simple polygon",
"textX": 85,
"textY": 104,
"title": "Notation 3"
}
],
"imageXW": 512,
"imageYW": 512,
"imageName": "lena_std.ato",
"tinyDocs": {
"c01": "JSON image notation data:",
"c02": "-------------------------",
"c03": "",
"c04": "This data contains image notations and related area",
"c05": "selection information that provides a means for an",
"c06": "image gallery to display notations with elliptical,",
"c07": "rectangular, polygonal or freehand area indications",
"c08": "over an image displayed to a gallery visitor.",
"c09": "",
"c10": "X and Y positions are all in image space. The image",
"c11": "resolution is given as imageXW and imageYW, which",
"c12": "you use to scale the notation areas to their proper",
"c13": "locations and sizes for your display of the image,",
"c14": "regardless of scale.",
"c15": "",
"c16": "For Ellipses, anchor is the center of the ellipse,",
"c17": "and the extents are the X and Y radii respectively.",
"c18": "",
"c19": "For Rectangles, the anchor is the top left and the",
"c20": "extents are the bottom right.",
"c21": "",
"c22": "For Freehand and Polygon area modes, the pointList",
"c23": "contains a series of numbered XY points. If the area",
"c24": "is closed, the last point will be the same as the",
"c25": "first, so all you have to be concerned with is drawing",
"c26": "lines between the points in the list. Anchor and extent",
"c27": "are set to the top left and bottom right of the indicated",
"c28": "region, and can be used as a simplistic rectangular",
"c29": "detect for the mouse hover position over these types",
"c30": "of areas.",
"c31": "",
"c32": "The textx and texty positions provide basic positioning",
"c33": "information to help you locate the text information",
"c34": "in a reasonable location associated with the area",
"c35": "indication.",
"c36": "",
"c37": "Opacity is a value between 0 and 1, where .5 represents",
"c38": "a 50% opaque backdrop and 1.0 represents a fully opaque",
"c39": "backdrop. Recommendation is that regions be drawn",
"c40": "only if the user hovers the pointer over the image,",
"c41": "and that the text associated with the regions be drawn",
"c42": "only if the user hovers the pointer over the indicated",
"c43": "region."
}
}
就我而言,我需要在 JSON 输出之前使用注释进行调试。所以我把调试信息放在HTTP头中,避免破坏客户端:
header("My-Json-Comment: Yes, I know it's a workaround ;-) ");
https://i.stack.imgur.com/yMh3J.png
我们将 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
包含这些专有注释时,它不再是有效的 JSON。
不定期副业成功案例分享
"__comment":"comment text goes here...",
Accronym
和Abbrev
属性进行单独评论怎么办?我以前使用过这种模式,但因为它不允许我这样做而停止了。这是一个黑客。也许如果我用__comment__
代替属性名称。那是“__comment__Abbrev”,仍然是一个 hack,但会让我评论所有的 prpoerties