Ruby to_yaml将我的json

时间:2017-07-06 14:13:32

标签: ruby

我正在尝试将ruby哈希转换为yaml。我希望哈希的一部分是有效的json;但是,当我尝试序列化json字符串时,它会在引号中转换为yaml。

例如,当我只有一个简单的字符串时,输出如下(注意foo不在引号中):

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

但是,当我在字符串的开头添加一些内容时,例如{ foo引用了body的输出:

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转到正确的ruby哈希,但我不能走另一条路。

2 个答案:

答案 0 :(得分:2)

方法my_hash.to_yaml()只需要一个哈希并将其转换为YAML,而不对值做任何特殊处理。该方法不关心您的字符串是JSON还是XML,它只是将其视为字符串。

  

那么,当其他字符串不是<?p?

时,为什么我的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()不会转换字符串。一位聪明的程序员曾告诉我:&#34;字符串是字符串。字符串不是数据结构。字符串是字符串。&#34;

如果要将字符串转换为数据结构,则需要对其进行验证并对其进行解析。因为不保证字符串是有效的,所以作为程序员,您有责任确定您的数据是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-typebody不一致,那么您应该抛出错误,因为您的输入数据不好。

答案 1 :(得分:1)

'{ foo'需要引用的原因是因为这是YAML规范7.3.3普通样式的一部分。

摘录

  

普通标量不得包含“:”和“#”字符组合。这种组合会导致映射键:值对和注释的模糊性。此外,内部流集合或用作隐式键时,普通标量必须   不包含“[”,“]”,“{”,“}”和“,”字符。这些字符会导致流量收集结构模糊不清。

基于上述情况,即使您所说的&#34;返回&#34;值不正确,正文可能用单引号括起来,例如

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

否则会产生歧义&#34; Flow Sequences&#34; [])和&#34; Flow Mappings&#34 ; {})。

如果您希望JSONXML或其他符号语言的结果被恰当地表示(客观地阅读),那么您将需要确定正确的解析器(可能来自&#34 ; Content-Type&#34;)并在转换它YAML

之前对其进行解析