可以在JSON中使用註釋嗎?

Can comments be used in JSON?
投票:7043回答:50

我可以在JSON文件中使用註釋嗎? 如果是這樣,怎麼辦?

tags:json,comments
50回答
418
投票

根據設計,註釋已從JSON中刪除。

我從JSON中刪除了註釋,因為我看到人們正在使用它們保留解析指令,這種做法會破壞互操作性。 我知道缺少評論會使某些人感到難過,但事實並非如此。

假設您正在使用JSON保留要註釋的配置文件。 繼續並插入您喜歡的所有評論。 然後將其通過JSMin傳遞給JSON解析器。

資料來源: 道格拉斯·克羅克福德(Douglas Crockford)關於Google+的公開聲明


28
投票

這取決於您的JSON庫。 Json.NET支持JavaScript樣式的註釋/* commment */註釋/* commment */

參見另一個堆棧溢出問題


25
投票

JSON對於配置文件和其他本地用法很有意義,因為它無處不在,而且比XML簡單得多。

如果人們有充分的理由反對在傳遞數據時在JSON中添加註釋(無論是否有效),則可以將JSON分為兩種:

  • JSON-COM:在線上的JSON,或在傳遞JSON數據時適用的規則。
  • JSON-DOC:JSON文檔,或文件中或本地的JSON。 定義有效JSON文檔的規則。

JSON-DOC將允許註釋,並且可能存在其他細微差別,例如處理空格。 解析器可以輕鬆地從一種規格轉換為另一種規格。

關於道格拉斯·克羅克福德(Douglas Crockford)在此問題上的評論 (@Artur Czajka引用)

假設您正在使用JSON保留要註釋的配置文件。 繼續並插入您喜歡的所有評論。 然後將其通過JSMin傳遞給JSON解析器。

我們正在談論一個通用的配置文件問題(跨語言/跨平台),而他正在使用JS特定實用程序進行回答!

確保可以使用任何語言來實現特定於JSON的minify,但要對此進行標準化,以使其在所有語言和平台的解析器中普遍存在,因此人們不再浪費時間缺少該功能,因為它們具有良好的用例,因此在在線論壇,並讓人們告訴他們這是一個壞主意,或者表明很容易實現從文本文件中剝離註釋。

另一個問題是互操作性。 假設您有一個庫或API或任何與某些配置或數據文件相關聯的子系統。 並且可以從不同的語言訪問該子系統。 然後,您要告訴人們:順便說一句,不要忘記在將JSON文件傳遞到解析器之前從JSON文件中刪除註釋!


28
投票

JSON本身不支持註釋,但是您可以使用自己的解碼器或至少預處理器來剝離註釋,這很好(只要您只是忽略註釋並且不使用它們來指導應用程序應如何處理JSON數據即可) )。

JSON沒有評論。 JSON編碼器不得輸出註釋。 JSON解碼器可以接受和忽略註釋。

註釋絕不能用於傳達任何有意義的內容。 這就是JSON的目的。

cf: JSON規範的作者Douglas Crockford


200
投票

免責聲明:您的保修無效

正如已經指出的那樣,這種黑客利用了規範的實現。 並非所有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]
}

上面的代碼是有效的JSON 如果您解析它,您將得到一個這樣的對象:

{
    "api_host": "hodorhodor.com",
    "retry_interval": 10,
    "auth_token": "5ad0eb93697215bc0d48a7b69aa6fb8b",
    "favorite_numbers": [19,13,53]
}

這意味著沒有評論的痕跡,並且它們不會有怪異的副作用。

駭客入侵!


18
投票

可以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]
]);

由於我的本地文件夾中有一個類似的文件,因此Same-origin策略沒有任何問題,因此我決定使用純JSON ...,當然,由於註釋, $.getJSON失敗了。

最終,我只是向上面的地址發送了一個手動HTTP請求,並意識到內容類型是text/javascript因為JSONP返回的是純JavaScript。 在這種情況下,允許註釋。 但是我的應用程序返回了內容類型application/json ,因此我不得不刪除註釋。


11
投票

要將JSON項目切成幾部分,請添加“虛擬評論”行:

{

"#############################" : "Part1",

"data1"             : "value1",
"data2"             : "value2",

"#############################" : "Part2",

"data4"             : "value3",
"data3"             : "value4"

}

9
投票

JSON的作者希望我們在JSON中包含註釋,但在解析它們之前將其刪除(請參閱Michael Burr提供的鏈接 )。 如果JSON應該有註釋,為什麼不標準化它們,然後讓JSON解析器完成呢? 我不同意其中的邏輯,但是,a,這就是標準。 使用其他人建議的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));

10
投票

有一個很好的解決方案(hack),它是有效的JSON,但在所有情況下都無法使用(請參見下面的評論)。 只需兩次(或多次)輸入相同的密鑰。 例如:

{
  "param" : "This is the comment place",
  "param" : "This is value place",
}

因此,JSON將其理解為:

{
  "param" : "This is value place",
}

60
投票

如果您將Jackson用作JSON解析器,則可以通過以下方式啟用它以允許註釋:

ObjectMapper mapper = new ObjectMapper().configure(Feature.ALLOW_COMMENTS, true);

然後,您可以有如下評論:

{
  key: "value" // Comment
}

您還可以通過設置以下內容以#開頭的註釋:

mapper.configure(Feature.ALLOW_YAML_COMMENTS, true);

但是總的來說(如前所述),該規範不允許發表評論。


169
投票

JSON不支持註釋。 也從未打算將其用於需要註釋的配置文件。

Hjson是人類的配置文件格式。 輕鬆的語法,更少的錯誤,更多的註釋。

Hjson簡介

有關JavaScript,Java,Python,PHP,Rust,Go,Ruby和C#庫的信息,請參見hjson.org


17
投票

這是一個“可以”的問題。 這是一個“是”的答案。

不,您不應該使用重複的對象成員將旁通道數據填充到JSON編碼中。 (請參閱RFC中的 “對象內的名稱應唯一”)。

是的,您可以在JSON 周圍插入註釋 ,然後將其解析出來。

但是,如果您想要一種將任意輔助數據插入和提取到有效JSON的方法,這是一個答案。 我們利用JSON編碼中數據的非唯一表示形式。 *在RFC的第二部分中“在六個結構字符中的任何一個之前或之後都允許空白”下是允許的。


首先,通過縮小規範化JSON:

$jsonMin = json_encode(json_decode($json));

然後將您的評論編碼為二進制:

$hex = unpack('H*', $comment);
$commentBinary = base_convert($hex[1], 16, 2);

然後隱藏您的二進製文件:

$steg = str_replace('0', ' ', $commentBinary);
$steg = str_replace('1', "\t", $steg);

這是您的輸出:

$jsonWithComment = $steg . $jsonMin;

102
投票

你不能 至少快速瀏覽一下json.org是我的經驗。

JSON在該頁面上顯示了其語法。 沒有關於註釋的任何註釋。


5096
投票

沒有。

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

30
投票

JSON背後的想法是提供應用程序之間的簡單數據交換。 這些通常是基於Web的,並且語言是JavaScript。

它實際上並不允許這樣的註釋,但是,儘管將數據顯然需要解析代碼特別地忽略或處理,但將註釋作為數據中的名稱/值對之一傳遞肯定會起作用。

綜上所述,JSON文件不應該包含傳統意義上的註釋。 它應該只是數據。

訪問JSON網站以獲取更多詳細信息。


34
投票

如果您將Newtonsoft.Json庫與ASP.NET一起使用來讀取/反序列化,則可以在JSON內容中使用註釋:

//“ name”:“ string”

//“ id”:int

要么

/* 這是一個

評論示例* /

PS:單行註釋僅在6+版本的Newtonsoft Json中受支持。

對於那些想不開箱即用的人的補充說明:我將JSON格式用於我製作的ASP.NET Web應用程序中的基本設置。 我閱讀了文件,並使用Newtonsoft庫將其轉換為設置對象,並在必要時使用它。

我更喜歡在JSON文件本身中寫有關每個設置的註釋,並且我真的不在乎JSON格式的完整性,只要我使用的庫可以使用就可以了。

我認為這比創建單獨的“ settings.README”文件並解釋其中的設置“更易於使用/理解”。

如果您對這種用法有疑問; 抱歉,精靈沒電了。 人們會發現JSON格式還有其他用法,您對此無能為力。


39
投票

如果您的文本文件(它是JSON字符串)將被某個程序讀取,那麼在使用它之前剝離出C或C ++樣式的註釋會有多困難?

答:那將是一個班輪。 如果這樣做,則可以將JSON文件用作配置文件。


12
投票

我們正在為項目使用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'}

768
投票

如果選擇,請添加評論; 在解析或傳輸之前,先用減法器將其剝離。

我剛剛發布了JSON.minify() ,它從JSON塊中刪除了註釋和空格,並使之成為可以解析的有效JSON。 因此,您可以像這樣使用它:

JSON.parse(JSON.minify(my_str));

當我發布它時,我什至遭到了人們的強烈反對,甚至對此想法也持反對意見,因此我決定寫一篇關於為什麼在JSON中有意義的博客文章。 它包含JSON創建者的以下著名註釋:

假設您正在使用JSON保留要註釋的配置文件。 繼續並插入您喜歡的所有評論。 然後將其通過JSMin傳遞給JSON解析器。 - 道格拉斯·克羅克福德Douglas Crockford),2012年

希望這對那些不同意為什麼JSON.minify()可能有用的人有所幫助。


19
投票

JSON不是框架協議 這是一種無語言格式 因此,未為JSON定義註釋的格式。

正如許多人所建議的那樣,有一些技巧,例如,可以使用重複鍵或特定鍵_comment 由你決定。


66
投票

您應該改為編寫JSON模式 JSON模式是當前提議的Internet草案規範。 除了文檔之外,該模式還可以用於驗證JSON數據。

例:

{
    "description":"A person",
    "type":"object",
    "properties":
        {
            "name":
                {
                    "type":"string"
                },
            "age":
                {
                    "type":"integer",
                    "maximum":125
                }
        }
}

您可以通過使用描述架構屬性來提供文檔。


22
投票

如果您使用JSON5 ,則可以包含註釋。


JSON5是對JSON的擬議擴展 ,旨在使人類更輕鬆地手工編寫和維護。 它通過直接從ECMAScript 5添加一些最小語法功能來實現此目的。


23
投票

JSON曾經支持註釋,但是它們被濫用並從標準中刪除。

來自JSON的創建者:

我從JSON中刪除了註釋,因為我看到人們正在使用它們保留解析指令,這種做法會破壞互操作性。 我知道缺少評論會使某些人感到難過,但事實並非如此。 - 道格拉斯·克羅克福德Douglas Crockford),2012年

官方JSON網站位於JSON.org JSON被ECMA International定義為標準 總有一個請願程序來修改標準。 由於多種原因,註釋不太可能被添加到JSON標準中。

通過設計,JSON是XML的一種易於反向工程(人工分析)的替代方案。 甚至簡化到不需要註釋的地步。 它甚至不是標記語言。 目標是穩定和互操作性。

任何了解面向對象的“具有”關係的人都可以理解任何JSON結構-這就是重點。 它只是帶有節點標籤(鍵/值對)的有向無環圖(DAG),這是一種幾乎通用的數據結構。

唯一需要的註釋可能是“ //這些是DAG標籤”。 鍵名可以根據需要提供豐富的信息,從而允許任意語義上的統一。

任何平台都可以僅用幾行代碼來解析JSON。 XML需要復雜的OO庫,這些庫在許多平台上都不可行。

註釋只會使JSON的互操作性降低。 除非您真正需要的是標記語言(XML),否則根本就沒有其他要添加的內容,並且不關心持久性數據是否易於解析。


1763
投票

,形式的意見//…/*…*/沒有在JSON不允許的。 該答案基於:

  • http://www.json.org
  • RFC 4627 :JavaScript對象符號(JSON)的application/json媒體類型
  • RFC 8259 JavaScript對象表示法(JSON)數據交換格式(取代RFC 4627、7158、7159)

48
投票

這是我在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"
}

22
投票

Dojo Toolkit JavaScript工具箱(至少從1.4版開始)允許您在JSON中包含註釋。 註釋可以是/* */格式。 Dojo Toolkit通過dojo.xhrGet()調用使用JSON。

其他JavaScript工具包可能會類似地工作。

在選擇最終選項之前嘗試使用備用數據結構(甚至數據列表)時,這可能會有所幫助。


10
投票

JSON本身不允許評論。 推理是完全愚蠢的,因為您可以使用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."
    }
}

13
投票

免責聲明:這很傻

實際上,有一種添加註釋並保持在規範內的方法(無需其他解析器)。 但是,如果不進行任何形式的解析,它將不會導致人類可讀的註釋。

您可能會濫用以下內容:

在任何令牌之前或之後都可以使用無關緊要的空格。 空格是以下一個或多個代碼點的任意序列:字符列表(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

hello base three以ASCII表示的hello base three )但不是0使用空格,而是1使用換行,2使用回車。

這只會給您留下很多不可讀的空格(除非您製作一個IDE插件來對其進行動態編碼/解碼)。

由於明顯的原因,我什至從未嘗試過,您也不應該嘗試。


29
投票

我只是在配置文件中遇到此問題。 我不想使用XML (冗長,圖形化,醜陋,難以閱讀)或“ ini”格式(無層次結構,沒有真正的標準等)或Java“屬性”格式(如.ini)。

JSON可以完成他們所能做的所有事情,但是它不那麼冗長,更容易被人理解-並且解析器在許多語言中都很容易實現。 這只是一棵數據樹。 但是帶外註釋通常是記錄“默認”配置等的必要條件。 配置絕不能是“完整文檔”,而可以是需要時人類可讀的保存數據樹。

我猜一個人可以對“ valid” JSON使用"#": "comment"


114
投票

考慮使用YAML。 它幾乎是JSON的超集(幾乎所有有效的JSON都是有效的YAML),並且允許註釋。


58
投票

評論不是官方標準。 儘管某些解析器支持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


©2020 sofbug.com - All rights reserved.