[英]Ruby to_yaml stringifies my json
我正在尝试将ruby hash转换为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 hash,但不能以其他方式使用。
方法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
不一致,则应输入错误,因为您的输入数据不正确。
'{ foo'
需要引号的原因是因为这是YAML规范7.3.3纯样式的一部分。
摘抄
普通标量绝对不能包含“:”和“#”字符组合。 这种组合将导致映射键(值对和注释)含糊不清。 另外,在内部流集合中,或当用作隐式键时,普通标量不得包含“ [”,“]”,“ {”,“}”和“,”字符。 这些字符将与流收集结构产生歧义。
基于上述情况,即使您声明的“返回”值也不正确,并且正文可能用单引号引起来,例如
response:
code: 200
body: '[{"id":"ef4b3a","title":"this is the title"},{"id":"a98c4f","title":"title of the second post"}]'
否则,它将与“流序列” ( [
, ]
)和“流映射” ( {
, }
)产生歧义。
如果您希望JSON
, XML
或其他表示法语言的结果得到适当的表示(客观地读取),则需要确定正确的解析器(可能来自“ Content-Type”)并进行解析,然后再将其转换为YAML
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.