2017-07-06 105 views
0

我想將紅寶石散列轉換爲yaml。我希望散列的一部分是有效的json;然而,當我嘗試序列化json字符串時,它被轉換爲引號中的yaml。紅寶石to_yaml字符串我的json

例如,當我只是有一個簡單的字符串時,輸出中如下(注foo不帶引號):

request = {} 
request['body'] = 'foo' 
request.to_yaml # outputs: body: foo 

然而,當我添加一些東西到字符串的開頭,如{ foo身體的輸出得到報價:

request['body'] = '{ foo' 
request.to_yaml # outputs: body: '{ foo' 

我該如何解決這個問題?我試過JSON.parse,雖然這樣做工作,我不能保證這個輸入實際上是json(可以是xml等等) - 我只是想回饋給我的任何東西,但不是「字符串化」。

基本上,我想給的對象,看起來像:

{ 'request' => { 
    'url' => '/posts', 
    'method' => 'GET', 
    'headers' => [ 
     'Content-Type' => 'application/json' 
    ] 
    }, 
    'response' => { 
    'code' => 200, 
    'body' => '[{"id":"ef4b3a","title":"this is the title"},{"id":"a98c4f","title":"title of the second post"}]' 
    } 
} 

將返回:

request: 
    url: /posts 
    method: GET 
    headers: 
     - Content-Type: application/json 

response: 
    code: 200 
    body: 
     [{"id":"ef4b3a","title":"this is the title"},{"id":"a98c4f","title":"title of the second post"}] 

其原因是:現在,我可以從YAML到正確的紅寶石哈希但我不能走另一條路。

+0

@engineersmnky - 重新:原因是因爲我有一個空間:我可以鍵入'這是標題'有三個空格,它不會被引用。這是當我添加一個花括號,它被引用。另外,請參閱編輯 – Tom

+0

如果你想解析'String'體,你將不得不知道內容類型'YAML'不會假定這個字符串可能是別的東西讓我檢查每個字符串解析庫是我假設的它只是一個'String' – engineersmnky

回答

2

方法my_hash.to_yaml()只需要一個散列並將其轉換爲YAML而不做任何特殊的值。該方法不關心你的字符串是JSON還是XML,它只是將它視爲一個字符串。

那麼,爲什麼我的JSON被引入其他字符串時引號?

好問題!原因很簡單:花括號是YAML語法的有效部分。

此:

my_key: { sub: 1, keys: 2} 

就是所謂的YAML流映射語法,它可以讓你在同一行做嵌套映射。爲了逃避這對他們有大括號的字符串,YAML使用引號:

my_key: "{ sub: 1, keys: 2}" # this is just a string 

當然,報價是可選的所有字符串:

my_key: "foo" #same as my_key: foo 

好吧,但我想to_yaml()找到我JSON字符串並將其轉換爲YAML映射,如其餘的哈希。

那麼,你需要將你的JSON字符串轉換爲像你的散列其餘部分一樣的散列。 to_yaml()將散列轉換爲YAML。它不會將字符串轉換爲YAML。這樣做的正確方法是使用JSON.parse,正如你所說:

request['body'] = JSON.parse('{"id":"ef4b3a"}') 

但該字符串可能不是JSON!它可能是XML或其他一些臭的字符串。

這是正是爲什麼to_yaml()不轉換字符串。一位聰明的程序員曾告訴我:「字符串是字符串,字符串不是數據結構,字符串是字符串。」

如果要將字符串轉換爲數據結構,則需要驗證它並對其進行解析。因爲不能保證字符串是有效的,所以作爲程序員你有責任確定你的數據是JSON還是XML還是壞的,並決定如何響應每一個數據。

,因爲它看起來像你解析網頁,你可能要考慮使用相同的數據位其他Web客戶端用來解析這些東西:

{ 'request' => { 
    'url' => '/posts', 
    'method' => 'GET', 
    'headers' => [ 
     'Content-Type' => 'application/json' #<== this guy, right here! 
    ] 
    }, 
    'response' => { 
    'code' => 200, 
    'body' => '[{"id":"ef4b3a","title":"this is the title"},{"id":"a98c4f","title":"title of the second post"}]' 
    } 
} 

如果content-type不同意body那麼你應該拋出一個錯誤,因爲你的輸入數據不好。

+1

相關:http://wiki.c2.com/?StringlyTyped –

1

原因'{ foo'要求報價是因爲這是YAML規範7.3.3普通風格的一部分。

摘錄

簡單的標量絕不能含有「:」和「#」字符組合。這種組合會導致映射關鍵字:值對和註釋的歧義。此外,在內部流集合中,或者當用作隱式鍵時,純標量必須不包含「[」,「]」,「{」,「}」和「,」字符。這些字符會導致流式收集結構不明確。

基於上述情況,即使您聲明的「返回」值是不正確的,並且身體可能用單引號括起來,例如

response: 
    code: 200 
    body: '[{"id":"ef4b3a","title":"this is the title"},{"id":"a98c4f","title":"title of the second post"}]' 

否則它會創建「流程序列」[])和模糊 「流動映射」{})。

如果你想有適當的代表的JSONXML或其他符號語言的結果(客觀上讀取),那麼你將需要確定正確的解析程序(可能是從「內容類型」)之前對其進行解析轉換它YAML