2016-10-16 16 views
3

我有點不能確定究竟在何處(我自己當然除外),以將矛頭指向使用YAML解析器處理JSON;拋出選項卡上的空白

  1. JSON是YAML 1.2 http://www.yaml.org/spec/1.2/spec.html 的一個子集「的每個JSON文件也是有效YAML文件」

  2. JSON可以有標籤爲‘不重要的空白’ - 包括標籤 http://www.ietf.org/rfc/rfc4627.txt ‘不重要的空白被允許......’

  3. YAML不允許標籤縮進 http://www.yaml.org/spec/1.2/spec.html

所以用我的YAML解析器來處理以下JSON

{ 
\t"result" : "success", 
} 

注意「製表符不能在壓痕使用」:在\ t只是可視化,輸入包含一個真正的製表符。

點擊一個錯誤'不允許使用縮進'選項卡< - 這似乎是正確的。

但是,那麼「每個JSON文件是否也是有效的YAML文件」規則如何保存;因爲我的文件是有效的JSON?

由於製表符是無意義的,我應該運行預處理步驟去除所有制表符?由於字符串中允許的唯一空格是'空格',因此刪除文件中的所有選項卡應該是安全的。

+0

你的輸入是否包含一個真正的製表符(並且你寫了「\ t」來形象化它)還是真的包含「\ t」(即反斜槓和t)? – Codo

+0

嗨科多;好的問題 - 我會更新澄清,\ t只是可視化,輸入包含一個真正的製表符 – brent

回答

2

點擊一個錯誤'不允許使用縮進'選項卡< - 這似乎是正確的。

不是。

這是規格的relevant production

[140] c-flow-mapping(n,c) ::= 「{」 s-separate(n,c)? 
           ns-s-flow-map-entries(n,in-flow(c))? 「}」 

s-separate(n,c)解析爲 here(因爲我們不是內部block-keyflow-key)。跳過一些步驟,我們達到允許製表符的s-separate-in-line

底線是你的JSON中的這個製表符不是縮進。縮進只與塊樣式相關(即,分別對序列和映射不使用[{)。在Flow風格中,空格僅用於分隔。

編輯:刪除示例鏈接,因爲它有點誤導。

編輯2:要回答你的第二個問題:不,不要剝去標籤。他們可能是標量內的內容!請參見this example,其中表格實際確定塊標量的縮進。

1

僅在YAML規範的1.2版本中添加了JSON兼容性。在最初爲YAML 1.1設計的解析器之上實現這種兼容性並不是微不足道的。

製表符在空格中沒有固定的表示形式,編輯時取決於編輯器的設置(或默認設置)。在實踐中,這意味着你不應該在塊樣式模式下使用製表符,大多數解析器也不允許它們在流式樣模式下使用。爲解析器的1.2兼容性「固定」似乎不是優先事項(至少它不適合我)。

所以這應該被你的解析器所接受,但是如果它不是,你應該過濾出來,但只在行的開頭。或者如果JSON自動生成,則調整生成器以使用空間。

+0

謝謝安東!也欣賞你的答案;我接受了flyx的回覆,因爲它將我與規範的部分聯繫起來,它解釋了我的哪些觀點不正確;但我的問題是相當廣泛的 - 而且你的輸入是非常感謝和 – brent

+0

@brent flyx'答案是在我編輯我的時候發佈的(正如你可以從我編輯你的答案和發佈這個之間的時間看到的),而我沒有想在這裏重複這些細節。不要忘記,你也可以讚揚他的回答(除了接受),我知道你並沒有因爲他的答案中的那一句贊成是我的。 – Anthon

0

對於它的價值,我們總是使用TAB進行縮進 - 恕我直言,這是唯一合理的選擇。所以,使用YAML是一個真正的問題。不想修改現有的YAML解析器(不好的事情),我寫了下面的JavaScript函數「untabify」的字符串,其結果可以被送入YAML解析器:

function untabify(str, indent=' ') { 

return str.replace(/^(\t*)(\x20*)/gm, function(match, p1, p2) { 

    // --- Keep track of line numbers, for error messages 
    if (untabify.hasOwnProperty('lineNumber')) { 
     ++untabify.lineNumber; 
     } 
    else { 
     untabify.lineNumber = 0; 
     } 

    // --- It's an error for space characters to appear in indentation 
    if (p2.length > 0) { 
     throw "Space character not allowed in indentation on line " 
       + untabify.lineNumber; 
     } 

    return indent.repeat(p1.length); 
    }); 
} // untabify() 

有了它,你可以只是這樣做(除了去掉,保持行號的跟蹤代碼,我不知道我怎麼能改善它):

var str = ` 
--- 
- StudentName 
- StudentCode 
- Age 
- DateOfBirth 
- Gender 
- 
    - lCustomData 
    - Name 
    - Value 
- 
    - lRaces 
    - bPrimaryRace 
    - Race 
    - RaceCode 
- 
    - lGoals 
    - iGoal 
    - Goal 
    - BeginDate 
    - EndDate 
    - 
     - lObjectives 
     - iObjective 
     - Objective 
`; 

var lStudentFields = YAML.parse(untabify(str)); 

,如果你嘗試混合製表符和空格它會拋出一個錯誤在你的縮進中。另外,請注意行號從0開始,但由於我的通常用法與示例中一樣,反向字符串從其開始的位置開始,所以第一個行號0將是從那裏開始的空行,所以'--- '在這個例子中,實際上是1號線。沒有經過高度測試,但非常簡單明瞭 - 使用需要您自擔風險。