可以在JSON中使用注释吗?
我可以在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"
}
}
}
}
}
- 如果有一个名为comment的有效字段,可能需要在实际注释上加上某种前缀:`"__comment":"注释文本在这里......",
- 你也可以使用"//":这看起来更原生,并且在同一个父级中仍然是可重复的
- 顺便说一下,Java的json库[google-gson](http://code.google.com/p/google-gson/)支持评论.
- 当 JSON 用于人类预期的配置文件时,它们应该被注释以便人类更好地理解。注解,此类文件不再是有效的 JSON,但有解决方案。例如,Google 的 GYP 支持#-style 评论。JSON.Minify 将帮助您从输入文件中丢弃 C/C++ 风格的注释。
- 如果我想对"Accronym"和"Abbrev"属性单独发表评论呢?我之前使用过这种模式但是停止了,因为它不允许我这样做.这是一个黑客.也许如果我在`__comment__`之前添加一个属性名称.这是"__comment__Abbrev",仍然是一个黑客,但我会评论所有的prpoerties
- 我2012年6月评论中的链接之一不再起作用。另一个读者(@douglasgross)提供了此当前链接:https://groups.yahoo.com/neo/groups/json/conversations/topics/156
- @RobFonseca-Ensor 但是如果我们有一个名为 `__comment` 的字段怎么办?我们需要一个新字段`___comment`。
不,表格的评论//…
或/*…*/
JSON中不允许.这个答案基于:
- http://www.json.org
-
RFC 4627:
application/json
JavaScript对象表示法的媒体类型(JSON) - RFC 7159 JavaScript对象表示法(JSON)数据交换格式 - 已废弃:4627,7158
- 如果你想用注释注释你的JSON(从而使它成为无效的JSON),那么在解析或传输之前将其缩小.Crockford本人在2012年在配置文件的背景下承认了这一点.
- 虽然你的答案绝对正确,但应该说这是BS.由于有如此多的最终用户需要json配置,因此评论非常有用.仅仅因为一些锡箔帽决定JSON*是*并且*必须始终是机器可读的,忽略了人类需要阅读它的事实,这是一种小心眼的嘲弄.
- @alkuzad:当涉及到正式语法时,必须有一些明确表示他们*被允许的东西,而不是相反.例如,选择您的编程语言:仅仅因为未明确禁止某些期望(但缺失)的功能,并不意味着您的编译器会神奇地识别它.
- @cmroanirgo:你显然不是第一个抱怨JSON限制的人......这就是为什么我们有解析器静默允许注释,以及其他格式,如YAML和JSON5.然而,这并没有改变JSON就是这样的事实.更确切地说,我觉得有趣的是,人们开始使用JSON的目的在一开始就显然是不够的,考虑到这个限制.不要责怪JSON格式; 责备自己坚持使用它不是特别合适的地方.
- @stakx,我不同意。这就像说“汽车一开始没有系安全带,所以我们不应该添加它们。如果你想要安全带,那你就用错了汽车”。如果向 JSON 添加注释会使其更有用(它肯定会),我们应该添加它们。与其接受 JSON 只是“它是什么”,不如让它成为它应有的样子。
- 是。JSON格式在元素之间有很多死区,并且在那些区域中对空间不敏感,因此没有理由在此不能有单行或多行注释。许多解析器和简化器也支持JSON注释,因此只需确保您的解析器支持它们即可。JSON用于应用程序数据和配置设置,因此现在需要注释。“官方规范”是一个不错的主意,但是它不够充分且过时,因此太糟糕了。如果您担心有效负载大小或性能,请缩小您的JSON。
- @d512: If you feel strongly about what the JSON format *should be* (vs. what it *is* today), perhaps take this up with the IETF to have the JSON format specification [RFC 8259](https://tools.ietf.org/html/rfc8259) changed.
- @PixelMaster then it's time to upgrade JSON to car status. Nobody would except having to declare a string variable called `_comment` in their code so let's not resort to those types of hacks in JSON.
如果您愿意,请附上评论; 在解析或传输之前用缩小器将它们剥离.
我刚刚发布了JSON.minify(),它从JSON块中删除了注释和空格,并使其成为可以解析的有效JSON.所以,您可以使用它:
JSON.parse(JSON.minify(my_str));
当我发布它时,我得到了一个强烈反对的人甚至不同意它的想法,所以我决定写一篇关于为什么评论在JSON中有意义的综合博客文章.它包括来自JSON创建者的这个值得注意的评论:
希望这对那些不同意JSON.minify()可能有用的人有帮助.
- 我对JSON.minify()唯一的问题是它真的很慢.所以我做了自己的实现,做了同样的事情:https://gist.github.com/1170297.在一些大型测试文件上,您的实现需要74秒,并且需要0.06秒.
- 如果您可以将建议的替代算法提交给JSON.minify()的github仓库,那就太棒了,这样它就可以移植到所有支持的语言:https://github.com/getify/json.minify
- @ MarnenLaibow-Koser即使对于数据流(甚至数据包)的使用,仍然存在有效的注释用法:包含诸如创建时间或源之类的诊断元数据通常与XML一起使用,并且对于JSON数据也是完全合理的.针对注释的参数很浅,任何文本数据格式都应该允许注释,而不管隐含的预期用法(没有任何规范建议JSON不能在其他地方使用,fwiw)
- @MiniGod我已经多次听过Doug关于这个话题的想法了.我很久以前在我的博客文章中提到过他们:http://blog.getify.com/json-comments/
- 如果JSON要被普遍接受(它基本上是这样做的话)那么它应该具有通用的应用程序.示例:JSON可以充当应用程序配置文件.这个应用程序需要评论.
- 如果JSON应该是一种纯粹的"数据包交换格式",那么它应该是我自己的两分钱,那么它应该被实现为严格二进制格式.就目前而言,数据表示为人类可读的基于字符串的语法,从逻辑上讲,任何旨在被人类阅读的内容都应该允许注释.
- Perl的JSON支持#comments.
- 我的规范用例是流式传输以进行聚合或存储的日志文件; 所以流/文件区别是虚拟和瞬态的.至于跳过:所有属性都是可见的,有两种主要方法可以解决它 - (a)经典,你必须知道一切是什么(至少你可以跳过它的程度),或(b)"什么都行",即只使用你所知道的.在后一种情况下跳过元数据是微不足道的.但是我看到你无法想象只有诊断的简单概念 - 只有在这里争论过来没有意义.
- 与XML相比,JSON有太多标点符号?你能澄清你的意思吗?下面是一个用于在Django中加载灯具的示例JSON:[{"model":"foo.bar","pk":1,"fields":{"name":"foo","customer_number":12345}}] XML中的相同内容如下:<?xml version ="1.0"encoding ="utf-8"?> <django-objects version ="1.0"> <object pk ="1"model ="foo.bar "> <field type ="TextField"name ="name"> foo </ field> <field type ="IntegerField"name ="customer_number"> 12345 </ field> </ object> </ django-objects>
- 有趣的是从JSON中删除评论能力.无处不在,我总是提醒我注释我的代码.现在我在JSON中有一个巨大的配置/数据文件,无法进行评论以备将来参考,因为某些原因有人认为评论不必要/愚蠢.
- 注释在JSON中没有意义.JSON并不是一种文件格式,只是一种数据包交换格式.如果您需要注释JSON之类的东西,请改用YAML.
- 你可能会觉得有趣的是,从JSON的作者那里听到为什么评论被排除在规范之外:http://youtu.be/-C-JoyNuQJs?t = 48m53s
- @StaxMan No.数据流中的注释只是浪费的字节.如果无法从流本身推断出像创建时间这样的元数据,那么为什么不在流中创建实际的,可解析的内容呢?*评论的参数*很浅:如果值得包括,那么值得将它作为数据*包括在内.
- 这个答案的问题是JSON是一种序列化格式,因此必须为每种语言(或每个解析器的内置缩小器)编写一个minifier.我怎么能为c找到一个json minifier呢?
- 这个答案滥用了 Crockford 的评论——jsmin 是一个 javacript 压缩器,而不是一个 JSON 压缩器。javascript minifier 接受 javascript 作为输入,而不是 JSON,因此支持注释。Crockford 的评论绝不能被扭曲为 JSON 中的评论是可以的,或者 JSON 压缩器应该支持评论。充其量,它是一个扩展,最糟糕的是,它是一个安全错误,因此,强烈反对是可以理解的,并使用 Crockfords 评论来证明它是一个错误。
评论已从JSON中删除.
假设您使用JSON来保留要注释的配置文件.继续,插入您喜欢的所有评论.然后通过JSMin将其传递给JSON解析器.
资料来源:Douglas Crockford对G +的公开声明
- 我认为JSON应该比XML更人性化?评论是为了便于阅读.
- 这就像要求所有自行车都有训练轮,因为有些人不能骑自行车.删除一个重要的功能,因为愚蠢的人滥用它是一个糟糕的设计.数据格式应优先考虑可用性,而不是防止白痴.
- 个人意见:不允许评论蹩脚.除了构建一个忽略注释的非标准JSON解析器,解码我的配置文件之外别无选择.
- 无论如何,你可能很顽皮,并在JSON中添加解析指令:{"_ _ directives":{"#n#":"DateTime.Now"},"validdate":"#n#"} ...看起来像YAML是前进之路......
- @ArturCzajka我仍然不喜欢JSON不支持评论的事实,但我试试了INI,我必须承认,使用JSON配置文件更有意义.感谢您的回复,希望更多人在阅读此对话时会改变主意.(无论如何,使解析器更像是一个练习:)
- "我从JSON中删除了评论,因为我看到有人使用它们来保存解析指令".按照这个逻辑,他也应该删除字符串类型.可怕的决定.
- 经典.我不认为你必须限制可用性的论点,因为有人可能会误用某个功能.这只是教条主义和短视.正确的做法是创建一种机制,在JSON中包含注释,就像所有其他语言一样.我们不应该在一个毫无意义的哲学圣战上浪费带宽来维持"纯洁".克服它,添加评论,继续前进.
- 如果有人在他们的JSON中使用注释来包含解析指令,谁会关心?老实说.荒谬.因此,如果您在注释中为自己的解析器放置非标准解析指令,那么遵循官方规范的解析器将忽略它们.否则,人们将不使用JSON,或者使用hacks将注释包含为数据,这肯定不比在注释中使用自定义解析指令更好.就此而言,人们还会将自定义解析指令作为数据放入JSON流中.这是一个愚蠢的论点,无法使用评论是令人讨厌的.
- 正如liz lemon所说的那样......"交易破坏者,女士们"!耶稣...所以用"省略"一行测试一些东西,又名"评论"(在正常的宇宙中)..你必须删除该行吗?不用了,谢谢!任何一天都可以获得一些好的机架式安全XML!
- 没有JSON评论感觉不对.JSON中允许格式化(空格,换行)_are_,格式和注释之间没有根本区别.
- @JuanMendes没有那么多"不应该",因为它只是改变的好处(我个人认为我无法在JSON文件中发表评论).请记住,JSON也是Javascript的子集,YAML和Javascript具有互不兼容的注释语法.YAML使用`#`但Javascript使用`//`和`/**/`.JSON不能使用`#`作为注释而不会与Javascript不兼容.JSON不能是YAML和Javascript的子集,并且有注释.
- 删除评论是一个'坏想法'.由于评论也是阅读它的人的数据,因为它们不是数据而删除它们是一个不好的论点.此外,可以说任何语言,规范文件,配置文件等中的所有注释都是数据.仅仅因为它不适用于机器,并不意味着它不是数据.
- 删除`/**/`注释也使JSON成为YAML的更好子集.
- @Schwern 但是 YAML 确实允许`#` 注释,所以你的观点有点像
- JSON 的全部意义在于它只包含数据。如果您觉得需要评论,您应该使用 XML,而不是 JSON。处理指令也是如此(XML 也有)。真的,真的……如果您将 JSON 用于矩形数据(行和列)以外的任何内容,那么您可能错了,应该使用 XML。
免责声明:您的保修无效
正如已经指出的那样,这个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]
}
这意味着没有评论的痕迹,他们也不会有奇怪的副作用.
快乐的黑客!
- __NO__ - 如果解析器正在流式传输怎么办?如果解析器将其读入字典中未定义键排序,该怎么办?__用火来杀死它.
- 从[规范](http://www.ietf.org/rfc/rfc4627.txt):对象中的名称应该是唯一的.
- "所有的实现都处理它" - 这是一个难以证明的事情.
- JSON中的元素顺序无法保证.这意味着"最后"项目可能会改变!
- 这显然违反了规范(见上述评论),不要这样做.https://www.ietf.org/rfc/rfc4627.txt?number=4627
- 这是SO上[**最具争议的**](http://data.stackexchange.com/stackoverflow/query/466/most-controversial-posts-on-the-site)的帖子.
- 由于我们一直在JSON工作组的IETF上工作RFC 4627bis(加入我们并提供帮助!http://datatracker.ietf.org/wg/json/),我们发现实现者已经使用了四种不同的方法对象中的重复名称:使用第一个; 用最后一个; 报告所有这些并让呼叫者选择一个; 返回错误并停止解析.如果您的数据无法在所有这些方法中存在,那么它在实践中将无法互操作.
- Downvoted.这是一个坏主意,纯粹而简单.你滥用JSON规范的灰色区域,向其他人推广这种做法是不负责任的.这是一个黑客; 不要这样做.
- 来自rfc2119的@Quentin:"3.应该这个词,或形容词"推荐",意味着在特定情况下可能存在忽略特定项目的正当理由,但在选择不同之前必须理解并仔细权衡全部含义课程."
- 你乞求这个爆炸在你的脸上.与其他提到的一样,解析器可能直接拒绝您的JSON,回显"注释"而不是值,或者以神秘的方式失败,例如为相同的密钥推送两个事件(流式解析器,最有可能).例如,最近的APK签名漏洞本质上利用了同样的东西,多个非唯一键(文件名)的未定义行为,只是用zip而不是JSON.
- 这是我在stackoverflow上看到过的最糟糕的答案之一.它可以在任何时候中断,它不是那么聪明,因为它不像常规评论那样特别易读.人们可能总是想知道我们是否有一个评论或真实数据的项目.JSMin似乎是一个更清晰(更易读)的解决方案.也就是说,IT行业仍应该感谢你的笑话.
- 我曾经对具有双键的JSON文件有一些麻烦,因为它在规范中没有明确禁止.请不要建议其他人这样做.
- 在很多层面上这是错误的,我甚至不知道从哪里开始.我会把它放在这里 - http://pragprog.com/the-pragmatic-programmer/extracts/coincidence-并试着忘记我刚看到的内容.
- 这个答案是癌症.我的开发 在没有阅读评论的情况下,人们做了同样的事 现在,我们正在通过RPC服务器中的内容流式传输自己.
- @ Tracker1 - 订单无法保证,因为重要的是解析器而不是编写文件的人.JSON规范没有描述如果存在重复键会发生什么(它表示你应该让它们成为唯一的),所以一些解析器可能会占用第一个,而其他解析器可能占用最后一个,而其他解析器则会丢失.
- 解析器丢弃现有密钥的值而不是覆盖它们是完全合理的.
- 目前在json.org上列出了一百多种不同的实现.我打赌他们中至少有一个不会同样处理它.
- 我自己的实现(对于嵌入式系统,找不到符合要求的现有系统)总是在重复的情况下获取第一个密钥.你真的不能认为这会起作用.
- 有关错误情况,请参阅此问题:http://stackoverflow.com/questions/4912386/resolve-jsonexception-duplicate-keys
- 糟糕的想法 - 导致混淆,反对规范,而不是未来的证据和JSLint取消JSON的资格.
- 是的,但这不是语法错误,所有实现都对其进行了相同的处理。所以我认为使用起来非常安全。不是哲学上的,而是实践上的。
- @ sep332他们是手工编辑的json/config文件.
- @erdeszt - 是的,*必须理解全部含义*.如果没有测试每个JSON解析器,就无法理解那些(因为人们会继续编写新的解析器......).
- @Quentin我只是说规范并不清楚如何处理这个案例,这是一个聪明的黑客,这是"合法的"但当然气馁.
- 在今天的背景下,这是一个伟大的黑客。JSON 解析在服务器端和浏览器端都得到了简化。IE8 之后的所有浏览器都支持 JSON.parse。所以真的每个人都应该使用内置的 JSON 解析。您将仅出于遗留原因使用自定义解析器。并且内置的 JSON 解析器不太可能改变其行为并破坏向后兼容性。
- 糟糕的黑客.这是JSON解析器的问题.至少IAM策略文件(AWS)不接受重复的JSON密钥.http://www.microsofttranslator.com/bv.aspx?from=&to=en&a=http://dev.classmethod.jp/etc/adding-comment-to-json/
- "所有的实现都处理它" - [jju](https://github.com/rlidwka/jju)有一个选项可以抛出这些jsons
JSON不支持评论.它也从未打算用于需要注释的配置文件.
Hjson是人类的配置文件格式.轻松的语法,更少的错误,更多的评论.
有关JavaScript,Java,Python,PHP,Rust,Go,Ruby和C#库的信息,请参阅hjson.org.
- 我很佩服你的喜好,但你有点重新发明了YAML.如果你想要很多灵活性和人类可读性,请使用YAML(实际上不要:http://stackoverflow.com/questions/450399/which-java-yaml-library-should-i-use/1863814#comment6582202_1863814)或坚持下去与curmudgeony,但明确的JSON.
- 每当你需要json作为配置(需要注释_are_)时 - 将文件命名为".js"而不是".json".. js当然可以处理任何有效的json对象,另外_can_处理注释..这就是为什么它是"webpack.config.js"而不是"webpack.config.json"(在webpack中也有更多的原因:P)
- Upvoted.这显然是一个很好的变化,不开放的保守派人士会喜欢讨厌.我希望你的实现能够进一步了解 - 甚至可能比原版更受欢迎;)我希望有人也可以用Ruby实现它.@adelphus明确定义的语言是您自己的观点或观点.作为一个保守的"开发者"如果你是一个并不能证明你更好,你可能会更糟,让自己被关在有限的空间.不要轻易将人们视为糟糕的开发者.
- 抱歉,@ konsolebox.也许你可以在阅读http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf之后重新考虑你的"明确定义的JSON是你的意见"观点.这是一个真正的标准和开发实施他们自己的"特殊"版本会导致碎片化,混乱和大量浪费时间.看看开发人员在编写代码时留下的混乱,因为每个浏览器都实现了略有不同的标准版本.JSON语言可能并不完美,但碎片化程度更差.是的,这只是一个意见,你可以自由地反对意见.
- 我发现最用户友好的配置格式仍然是INI.它很简单,而且语法不重.这使得用户只需在配置池中浸泡脚趾就不那么令人生畏了.
考虑使用YAML.它几乎是JSON的超集(几乎所有有效的JSON都是有效的YAML)并且它允许注释.
- @ g33kz0r正确,因此我将YAML描述为JSON的近似超集.
- @NateS许多人已经指出答案是否定的.我提出了一个更好的方法来实现OP的目标.这是一个答案.
- @ marnen-laibow-koser:是的,使用Java和Perl的可用YAML库一定是无能为力的,并期望每个人生成的YAML被其他人使用而没有错误.YAML互操作是一个问题,但JSON互操作不是,完全可以解释为我缺乏知识.
- 缺点:`yaml`库不附带Python.
- @ marnen-laibow-koser,我已经驳斥了你对我自己无能的暗示,用具体细节支持了我的主张,并略微阐述了我的偏好/偏见,这些都是我YAML批评的基础.我自己的进一步评论可能会收益递减.我对未来读者做出明智选择的能力充满信心.除了接近广告攻击的边缘,谢谢你的话语.如果你愿意,最后一句话是你的.
- 同意这是一个相关的选择.不过,如果你已经倾向于使用JSON,请不要使用YAML:http://stackoverflow.com/questions/450399/which-java-yaml-library-should-i-use/1863814#comment6582202_1863814
- @toolbear 听起来像是写得不好的库的错;不要责怪格式。是的,您声称引用歧义表明缺乏知识,尽管如果您有特定案例,我会很感兴趣。但是,缺乏知识的可能是解析器实施者,不一定是您。
- @ marnen-laibow-koser,一种用更简单的规范完成同样事情的格式更好.具有完美实现的实用格式比具有不完美实现的理想格式更好.对于错误的自由主义者而言,并非所有责任都落在实施者的肩上; YAML规格长,密集,钝.它的维基百科条目引用了两个含糊不清的例子; 如果一个人必须在人和格式之间放置一个发射器以保护它们免受歧义,那么该格式就失去了人类友好的主张.JSON声称较少,并且大多数成功,YAML声称更多并且不足.
- @toolbear不打算进行人为攻击。“具有完美实现的实用格式比具有不完美实现的理想格式更好” —不确定我是否同意。如果格式是理想的(并且是可实现的),那么人们总是可以*使*一个好的实现。如果格式不理想,那么即使是完美的实现也不是很好。:)“ YAML规范很长,很密且很钝”-实际上这并不是“钝”的意思,但是YAML规范很明确。我看不出维基百科中有任何歧义;如果我错过了一些内容,请引用本文的特定部分。
- 此答案在完成向 json 添加注释时有效。它不再是标准的 json。但它仍然是json。评论 + Json + Yaml Loader = 有效的解决方案。某些框架/语言需要安装 json。默认情况下安装它是一个不使用 yaml 的糟糕借口。但是加载时间和库大小是避免它的有效理由。可能适合也可能不适合。有效答案。
你不能.至少这是我从json.org快速浏览一下的经历.
JSON的语法在该页面上可视化.关于评论没有任何说明.
您应该编写一个JSON模式.JSON模式目前是提议的Internet草案规范.除了文档之外,模式还可用于验证JSON数据.
例:
{
"description":"A person",
"type":"object",
"properties":
{
"name":
{
"type":"string"
},
"age":
{
"type":"integer",
"maximum":125
}
}
}
您可以使用description schema属性提供文档.
- JSON架构是否存活?它存在但是它是否受到任何已知库的支持?
- 这仅对结构化文档有帮助,而不是临时文档
如果您使用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的替代品.
以下是我在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"
}
- 此方法会破坏某些库,这些库要求密钥必须是唯一的.我正在通过编写评论来解决这个问题.
- 我现在倾向于使用它:{"// foo":"foo comment","foo":"foo value","// bar":"bar comment","bar":"bar value"}您可以使用数组进行多个注释:{"// foo":["foo comment 1","foo comment 2"],"foo":''foo value"}
如果您的文本文件(即JSON字符串)将被某些程序读取,那么在使用之前删除C或C++样式注释有多难?
答:这将是一个班轮.如果您这样做,那么JSON文件可以用作配置文件.
- "......将是一个单行"嗯,不,实际上,JSON不是常规语法,正则表达式可以简单地找到匹配的/*对.您必须解析文件以查找/*是否出现在字符串中(并忽略它),或者它是否被转义(并忽略它)等.此外,您的答案是无益的,因为您只是推测(错误地)而不是提供任何解决方案
- 可能是迄今为止最好的建议,尽管将文件保留为交换格式仍然是一个问题,因为它们需要在使用前进行预处理。
- 尽管我认为,扩展JSON并不是一个好主意(不要将其称为不同的交换格式):确保忽略字符串中的"注释".{"foo":"/*这不是评论.*/"}
如果您使用带有ASP.NET的Newtonsoft.Json库来读取/反序列化,则可以使用JSON内容中的注释:
//"id":int
要么
评论示例*/
PS:只有6个以上版本的Newtonsoft Json支持单行注释.
对于那些无法开箱即用的人的补充说明:我在我制作的ASP.NET Web应用程序中使用JSON格式进行基本设置.我读取文件,使用Newtonsoft库将其转换为设置对象,并在必要时使用它.
我更喜欢在JSON文件本身中编写关于每个单独设置的注释,并且我真的不关心JSON格式的完整性,只要我使用的库可以正常使用它.
我认为这是一种"更易于使用/理解"的方式,而不是创建单独的"settings.README"文件并解释其中的设置.
如果您对此类用法有疑问; 对不起,精灵已经没了灯.人们会发现JSON格式的其他用法,你无能为力.
- 我完全同意你的意见,但到目前为止,还有883个赞成,因为非答案只是说明了这一点.思想纯度高于有用的信息,这对你来说是如此.
JSON背后的想法是在应用程序之间提供简单的数据交换.这些通常是基于Web的,语言是JavaScript.
它实际上并不允许这样的注释,但是,将注释作为数据中的一个名称/值对传递肯定会起作用,尽管这些数据显然需要被解析代码忽略或处理.
总而言之,JSON文件不应该包含传统意义上的注释.它应该只是数据.
有关更多详细信息,请查看JSON网站.
- 确实,JSON格式没有注释.就个人而言,我认为这是一个重大错误 - 能够将注释作为元数据(而非数据)对xml非常有用.JSON规范的早期草稿版本确实包含了注释,但由于某些原因它们被删除了.: - /
- 元数据属于元数据构造(例如HTML <meta>标签),而不是注释.滥用元数据注释只是在没有真正的元数据构造存在的情况下使用的hack.
- @StaxMan他们被完全删除,因为人们开始使用它们作为元数据.Crockford说它破坏了格式设计的兼容性,我同意:如果你想要元数据,为什么不把它作为实际数据包括在内?用这种方式解析会更容易.
我刚刚遇到配置文件.我不想使用XML(冗长,图形,丑陋,难以阅读)或"ini"格式(没有层次结构,没有真正的标准等)或Java"属性"格式(如.ini).
JSON可以做他们能做的所有事情,但它更简洁,更人性化 - 解析器在许多语言中都很容易和无处不在.它只是一个数据树.但是,带外注释通常是记录"默认"配置等的必要条件.配置永远不会是"完整文档",而是保存数据的树,在需要时可以是人类可读的.
我想可以使用"#": "comment"
"有效"JSON.
- YAML互操作是一个谎言:http://stackoverflow.com/questions/450399/which-java-yaml-library-should-i-use/1863814#comment6582202_1863814.如果您的直觉是使用JSON配置文件,请按照它.
- 对于配置文件,我建议使用YAML,而不是JSON.它(几乎)是一个更强大的JSON超集,但也支持更多可读的结构,包括注释.
这取决于您的JSON库.Json.NET支持JavaScript风格的评论/* commment */
.
请参阅另一个Stack Overflow问题.
JSON本身不支持注释,但您可以创建自己的解码器或至少预处理器来删除注释,这非常好(只要您忽略注释并且不使用它们来指导应用程序应如何处理JSON数据).
绝不应该使用注释来传输任何有意义的内容.这就是JSON的用途.
Cf:Douglas Crockford,JSON规范的作者.
- Crockford后来写道:"假设你使用JSON来保存配置文件,你想要注释.继续插入你喜欢的所有注释.然后通过JSMin将它传递给你的JSON解析器." 有关详细信息,请参阅@ kyle-simpson关于JSON.minify的答案.
JSON用于支持评论,但它们被滥用并从标准中删除.
来自JSON的创建者:
官方JSON站点位于JSON.org.JSON被ECMA International 定义为标准.总是有一个请愿程序来修改标准.由于多种原因,注释不太可能添加到JSON标准中.
JSON设计是一种易于反向设计(人工解析)的XML替代方案.甚至简化到注释是不必要的.它甚至不是标记语言.目标是稳定性和互操作性.
任何了解面向对象"has-a"关系的人都可以理解任何JSON结构 - 这就是重点.它只是一个带有节点标签(键/值对)的有向无环图(DAG),它是一种近乎通用的数据结构.
这个唯一的注释可能是"//这些是DAG标签".密钥名称可以根据需要提供信息.
任何平台都可以用几行代码解析JSON.XML需要复杂的OO库,这些库在许多平台上都不可行.
注释只会使JSON的互操作性降低.除非您真正需要的是标记语言(XML),否则无需添加任何其他内容,并且不关心是否可以轻松解析持久化数据.
JSON对配置文件和其他本地用法很有意义,因为它无处不在,因为它比XML简单得多.
如果人们有充分的理由反对在传递数据时使用JSON进行评论(无论是否有效),那么可能JSON可以分为两部分:
- JSON-COM:线上的JSON,或者在传递JSON数据时应用的规则.
- JSON-DOC:JSON文档,或文件或本地JSON.定义有效JSON文档的规则.
JSON-DOC将允许注释,并且可能存在其他微小差异,例如处理空白.解析器可以轻松地从一个规范转换为另一个规范.
至于该言论道格拉斯克罗克福德在这个问题上取得了(由@Artur Czajka参考)
我们正在讨论通用配置文件问题(跨语言/平台),他正在回答JS特定的实用程序!
当然,JSON特定的minify可以用任何语言实现,但是标准化,因此它在所有语言和平台的解析器中变得无处不在,所以人们不再浪费他们的时间缺乏这个功能,因为他们有很好的用例,看看问题在在线论坛,并让人们告诉他们这是一个坏主意或建议很容易实现从文本文件剥离评论.
另一个问题是互操作性.假设您有一个库或API或任何类型的子系统,其中包含一些与之关联的配置或数据文件.这个子系统可以从不同的语言访问.然后你去告诉别人:顺便说一下,在将它们传递给解析器之前不要忘记从JSON文件中删除注释!
Dojo Toolkit JavaScript工具包(至少从版本1.4开始)允许您在JSON中包含注释.评论可以是/* */
格式.Dojo Toolkit通过dojo.xhrGet()
调用消耗JSON .
其他JavaScript工具包可能类似地工作.
在选择最终选项之前尝试使用备用数据结构(甚至数据列表)时,这会很有用.
- 不,不是这个.JSON没有评论.如果您选择使用注释注释JSON,请在解析或传输之前将其缩小.这不应该是接收者的责任.
- 我没有说 JSON 有评论。我也没有暗示将它们包含在您的 JSON 中是合适的,尤其是在生产系统中。我说过*Dojo 工具包* 允许您添加它们,这在(或至少是)事实上是正确的。在您的测试阶段,有非常有用的用例可以这样做。
如果您使用JSON5,则可以包含注释.
JSON5是JSON的建议扩展,旨在使人们更容易手动编写和维护.它通过直接从ECMAScript 5添加一些最小语法功能来实现这一点.
- SO指南要求提供实际答案.不需要仅链接答案.您可以查看指南http://stackoverflow.com/help/how-to-answer
- 你能加一个例子吗?那你可能真的需要那些额外的角色.
- SO由其用户主持.这意味着我可以提供一个答案,如果我这样做,我可以评论你的答案,如果它不遵循指导方针.这就是SO如何成为一个伟大的资源.
是的,新标准JSON5允许 C++ 风格的注释,以及许多其他扩展:
// A single line comment.
/* A multi-
line comment. */
JSON5 数据交换格式 (JSON5) 是 JSON 的超集,旨在减轻 JSON 的某些限制。它完全向后兼容,使用它可能比编写自定义非标准解析器、为现有解析器打开非标准功能或使用字符串字段等各种技巧进行注释更好。或者,如果使用的解析器支持,只需同意我们使用 JSON 5 子集,即 JSON 和 C++ 样式注释。这比我们以我们认为合适的方式调整 JSON 标准要好得多。
已经有npm 包、Python 包、Java 包和C 库可用。它向后兼容。我认为没有理由坚持“官方”JSON 限制。
我认为从 JSON 中删除注释的原因与在 Java 中删除运算符重载的原因相同:可以以错误的方式使用,但忽略了一些明显合法的用例。对于运算符重载,它是矩阵代数和复数。对于 JSON 注释,它是可以由人类编写、编辑或阅读的配置文件和其他文档,而不仅仅是解析器。
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编码中.(参见RFC中的 "对象中的名称应该是唯一的" ).
是的,你可以在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;
- RFC 仅声明“在六个结构字符中的任何一个之前或之后都允许使用空格”,而没有明确提及字符串、数字、“false”、“true”、“null”。在所有实现中都忽略了这一省略。
免责声明:这很傻
实际上,有一种添加注释并保持在规范内的方法(无需其他解析器)。但是,如果不进行任何形式的解析,它将不会导致人类可读的注释。
您可能会滥用以下内容:
您可以滥用这种方式添加评论。例如:用标签开始和结束您的评论。在base3中编码注释,并使用其他空格字符表示它们。例如。
010212 010202 011000 011000 011010 001012 010122 010121 011021 010202 001012 011022 010212 011020 010202 010202
(hello base three
以ASCII表示),而不是0使用空格,对于1使用换行,对于2使用回车。
这只会给您留下很多不可读的空格(除非您制作一个IDE插件来对其进行动态编码/解码)。
由于明显的原因,我什至从未尝试过,您也不应该尝试。
我们正在使用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'}
- Note that the `json` is not a valid JSON anymore when it includes these propriety comments.
要将JSON项目切割成部分,我添加"虚拟注释"行:
{
"#############################" : "Part1",
"data1" : "value1",
"data2" : "value2",
"#############################" : "Part2",
"data4" : "value3",
"data3" : "value4"
}
- 您已经在JSON中模拟了一个INI文件结构.请放下你的金锤.
- RFC说"对象中的名称应该是唯一的".另请参阅此解析JSON的人如上所述:/sf/ask/343867051/?lq = 1
JSON本身不允许评论。推理是完全愚蠢的,因为您可以使用JSON 本身来创建注释,从而完全避免推理,并且完全没有理由完全加载解析器数据空间,以得到完全相同的结果和潜在问题,例如:JSON带有注释的文件。
例如,在这里,我的图像处理系统保存了图像符号和一些与它们有关的基本格式化(注释)信息(在底部):
{
"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."
}
}
有一个很好的解决方案(hack),它是有效的JSON.只需两次(或更多)相同的密钥.例如:
{
"param" : "This is the comment place",
"param" : "This is value place",
}
所以JSON会将其理解为:
{
"param" : "This is value place",
}
- 如果任何人将遍历该对象,此方法可能会导致一些麻烦.在第一次迭代中,程序将不具有该条目是注释的信息.
- RFC说:"对象中的名称应该是唯一的".请参阅以下网址报告此错误:/sf/ask/343867051/?list = 1
- 这样做是邀请您创建JSON,在将来的某个随机点上炸毁您.
- 无法保证订单在对象名称/值对列表中很重要.解析器可以"乱序"解析它们,然后这就破坏了.
- 具有此类代码的JSON解析器的行为未定义.没有什么可说的,解析器的行为就好像只有最后一个值存在一样.它可能表现为只有第一个值存在,或任何值,或者好像该值是一个数组.
JSON的作者希望我们在JSON中包含注释,但在解析它们之前将它们删除(参见Michael Burr提供的链接).如果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));
- 这不起作用,因为它不考虑/*是否可以转义,或者可以在字符串文字内.JSON不是常规语法,因此正则表达式是不够的.你必须解析它以找出评论的位置.
的JSON规范不支持的意见,// or /* */
风格。
但是一些 JSON 解析库和 IDE 支持它们。
喜欢:
- JSON5
- 视觉工作室代码
- 评论json
如果将JSON加载为文本文件,则可以在其中使用带注释的JSON,然后从中删除注释.
您可以使用decomment库.以下是一个完整的例子.
输入JSON(文件input.js):
/*
* multi-line comments
**/
{
"value": 123 // one-line comment
}
测试应用:
var decomment = require('decomment');
var fs = require('fs');
fs.readFile('input.js', 'utf8', function (err, data) {
if (err) {
console.log(err);
} else {
var text = decomment(data); // removing comments
var json = JSON.parse(text); // parsing JSON
console.log(json);
}
});
输出:
{ value: 123 }
另见:gulp-decomment,grunt-decomment
- 如果您以需要特殊预处理器处理的自定义方式扩展语言,则它不再是JSON。
就我而言,我需要在JSON结构的输出之前使用注释进行调试。因此,我决定在HTTP标头中使用调试信息,以避免破坏客户端:
header("My-Json-Comment: Yes, I know it's a workaround ;-) ");
我刚刚发现了" grunt-strip-json-comments ".
{
// Rainbows
"unicorn": /* ? */ "cake"
}
不,JSON 不能直接有注释。但是,正如this所建议的那样,您可以通过执行类似的操作来实现类似的效果
{
"//name": "Name comment here",
"name": "Jack",
"//age": "Age comment here",
"age": "25"
}
大多数 JSON 解析器将忽略未映射的属性。
叹.为什么不直接添加字段,例如
{
"note1" : "This demonstrates the provision of annotations within a JSON file",
"field1" : 12,
"field2" : "some text",
"note2" : "Add more annotations as necessary"
}
只需确保您的"notex"名称不与任何真实字段冲突.
- `只要确保你的"notex"名称与任何真实字段都不冲突.问题就在于此.这不是任意解决方案.
- 这也提出了这样的问题:在传输之前,缩小实用程序不能剥离注释,这不可避免地导致传输更大的数据,这在传输的另一端没有用处.我真的觉得从JSON规范中获取评论支持是不幸的.特别是因为人们会一起破解解决方案.从规范中获取支持是一种行为控制的尝试,由于相互不兼容的变通办法的泛滥,这种行为控制只会失败并产生更大的不兼容性.
- 如果您使用模式来验证JSON,则由于额外的字段,它可能会失败。
- 在配置文件中,我使用`{“ / * ----我的部分---- * /”:0}`。这是有效的JSON,因为JSON接受密钥字符串中的任何字符。它不会与其他属性发生冲突,也不会有人在乎或重新排序。不过,有2条评论不能相同。
VSCode用户在2019年的实际答案是使用'jsonc'扩展名。
实用,因为这是VSCode识别的扩展,用于指示“带注释的JSON”。请在下面的评论中让我了解其他编辑器/ IDE。
如果VSCode和其他编辑器也添加对'json5'的本机支持,那就太好了,但是目前VSCode仅包括对'jsonc'的支持。
(我在发布此内容之前搜索了所有答案,但都没有提及“ jsonc”。)
如果您的上下文是Node.js配置,则可以考虑通过JavaScript module.exports
作为JSON的替代方案:
module.exports = {
"key": "value",
// And with comments!
"key2": "value2"
};
该require
语法仍然是相同的。作为JavaScript,文件扩展名应该为.js
。
正如许多答案已经指出的那样,JSON 本身没有注释。当然,有时无论如何你都想要它们。对于Python,有两种方法可以使用commentjson
(#
和//
仅适用于 Python 2)或json_tricks
(#
或//
适用于 Python 2 和 Python 3),它具有其他几个功能。免责声明:我做了json_tricks
。
您可以通过正则表达式使用简单的预处理。例如,以下函数将在PHP中解码带注释的JSON:
function json_decode_commented ($data, $objectsAsArrays = false, $maxDepth = 512, $opts = 0) {
$data = preg_replace('~
(" (?:[^"\\\\] | \\\\\\\\ | \\\\")*+ ") | \# [^\v]*+ | // [^\v]*+ | /\* .*? \*/
~xs', '$1', $data);
return json_decode($data, $objectsAsArrays, $maxDepth, $opts);
}
它支持所有PHP样式的注释:/ *,#,//。字符串文字原样保留。